1
0
Fork 0

added drop collection

This commit is contained in:
Frank Celler 2012-03-27 13:11:05 +02:00
parent f69a009a38
commit e03abf4f06
20 changed files with 799 additions and 371 deletions

View File

@ -418,18 +418,17 @@ TRI_vector_string_t TRI_FilesDirectory (char const* path) {
/// @brief renames a file
////////////////////////////////////////////////////////////////////////////////
bool TRI_RenameFile (char const* old, char const* filename) {
int TRI_RenameFile (char const* old, char const* filename) {
int res;
res = rename(old, filename);
if (res != 0) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
LOG_TRACE("cannot rename file from '%s' to '%s': %s", old, filename, TRI_LAST_ERROR_STR);
return false;
return TRI_set_errno(TRI_ERROR_SYS_ERROR);
}
return true;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -103,7 +103,7 @@ TRI_vector_string_t TRI_FilesDirectory (char const* path);
/// @brief renames a file
////////////////////////////////////////////////////////////////////////////////
bool TRI_RenameFile (char const* old, char const* filename);
int TRI_RenameFile (char const* old, char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief unlinks a file

View File

@ -652,14 +652,14 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
return false;
}
ok = TRI_RenameFile(tmp, filename);
res = TRI_RenameFile(tmp, filename);
if (! ok) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
TRI_UnlinkFile(tmp);
TRI_FreeString(tmp);
return false;
return res;
}
TRI_FreeString(tmp);

View File

@ -3152,6 +3152,31 @@ static v8::Handle<v8::Value> JS_DeleteVocbaseCol (v8::Arguments const& argv) {
return scope.Close(v8::True());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops a collection
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_DropVocbaseCol (v8::Arguments const& argv) {
v8::HandleScope scope;
TRI_vocbase_col_t* collection = UnwrapClass<TRI_vocbase_col_t>(argv.Holder(), WRP_VOCBASE_COL_TYPE);
if (collection == 0) {
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
}
int res = TRI_DropCollectionVocBase(collection->_vocbase, collection);
if (res != TRI_ERROR_NO_ERROR) {
string err = "cannot drop collection: ";
err += TRI_last_error();
return scope.Close(v8::ThrowException(v8::String::New(err.c_str())));
}
return scope.Close(v8::Undefined());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops an index
///
@ -4009,16 +4034,16 @@ static v8::Handle<v8::Value> JS_FiguresVocbaseCol (v8::Arguments const& argv) {
v8::Handle<v8::Object> result = v8::Object::New();
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
TRI_vocbase_col_status_e status = collection->_status;
if (status != TRI_VOC_COL_STATUS_LOADED) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(result);
}
if (collection->_collection == 0) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
}
@ -4037,7 +4062,7 @@ static v8::Handle<v8::Value> JS_FiguresVocbaseCol (v8::Arguments const& argv) {
TRI_Free(info);
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(result);
}
@ -4169,31 +4194,28 @@ static v8::Handle<v8::Value> JS_ParameterVocbaseCol (v8::Arguments const& argv)
TRI_sim_collection_t* sim = (TRI_sim_collection_t*) doc;
// check if we want to change same parameters
// check if we want to change some parameters
if (0 < argv.Length()) {
v8::Handle<v8::Value> par = argv[0];
if (par->IsObject()) {
v8::Handle<v8::Object> po = par->ToObject();
TRI_LockCondition(&sim->_journalsCondition);
// holding a lock on the vocbase collection: if we ever want to
// change the maximal size a real lock is required.
bool waitForSync = sim->base.base._waitForSync;
TRI_UnlockCondition(&sim->_journalsCondition);
// extract sync after objects
if (po->Has(v8g->WaitForSyncKey)) {
waitForSync = TRI_ObjectToBoolean(po->Get(v8g->WaitForSyncKey));
}
// try to write new parameter to file
TRI_LockCondition(&sim->_journalsCondition);
sim->base.base._waitForSync = waitForSync;
bool ok = TRI_UpdateParameterInfoCollection(&sim->base.base);
TRI_UnlockCondition(&sim->_journalsCondition);
// try to write new parameter to file
int res = TRI_UpdateParameterInfoCollection(&sim->base.base);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
ReleaseCollection(collection);
return scope.Close(v8::ThrowException(v8::String::New(TRI_last_error())));
}
@ -4204,13 +4226,9 @@ static v8::Handle<v8::Value> JS_ParameterVocbaseCol (v8::Arguments const& argv)
v8::Handle<v8::Object> result = v8::Object::New();
if (doc->base._type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {
TRI_LockCondition(&sim->_journalsCondition);
TRI_voc_size_t maximalSize = sim->base.base._maximalSize;
bool waitForSync = sim->base.base._waitForSync;
TRI_UnlockCondition(&sim->_journalsCondition);
result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False());
result->Set(v8g->JournalSizeKey, v8::Number::New(maximalSize));
}
@ -4357,9 +4375,9 @@ static v8::Handle<v8::Value> JS_StatusVocbaseCol (v8::Arguments const& argv) {
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
}
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
TRI_vocbase_col_status_e status = collection->_status;
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(v8::Number::New((int) status));
}
@ -5322,6 +5340,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
v8::Handle<v8::String> DeleteFuncName = v8::Persistent<v8::String>::New(v8::String::New("delete"));
v8::Handle<v8::String> DisposeFuncName = v8::Persistent<v8::String>::New(v8::String::New("dispose"));
v8::Handle<v8::String> DocumentFuncName = v8::Persistent<v8::String>::New(v8::String::New("document"));
v8::Handle<v8::String> DropFuncName = v8::Persistent<v8::String>::New(v8::String::New("drop"));
v8::Handle<v8::String> DropIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("dropIndex"));
v8::Handle<v8::String> EdgesFuncName = v8::Persistent<v8::String>::New(v8::String::New("edges"));
v8::Handle<v8::String> EnsureGeoIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("ensureGeoIndex"));
@ -5465,6 +5484,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
rt->Set(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery));
rt->Set(DropFuncName, v8::FunctionTemplate::New(JS_DropVocbaseCol));
rt->Set(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol));
@ -5503,6 +5523,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
rt->Set(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery));
rt->Set(DropFuncName, v8::FunctionTemplate::New(JS_DropVocbaseCol));
rt->Set(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol));

View File

@ -415,8 +415,8 @@ TRI_collection_t* TRI_CreateCollection (TRI_collection_t* collection,
return NULL;
}
// save the parameter block
res = TRI_SaveParameterInfo(filename, parameter);
// save the parameter block (within create, no need to lock)
res = TRI_SaveParameterInfoCollection(filename, parameter);
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeString(filename);
@ -477,10 +477,12 @@ void TRI_FreeCollection (TRI_collection_t* collection) {
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a parameter info block from file
///
/// You must hold the @ref TRI_READ_LOCK_STATUS_VOCBASE_COL when calling this
/// function.
////////////////////////////////////////////////////////////////////////////////
int TRI_LoadParameterInfo (char const* path,
TRI_col_info_t* parameter) {
int TRI_LoadParameterInfoCollection (char const* path, TRI_col_info_t* parameter) {
TRI_json_t* json;
char* filename;
char* error;
@ -560,10 +562,12 @@ int TRI_LoadParameterInfo (char const* path,
////////////////////////////////////////////////////////////////////////////////
/// @brief saves a parameter info block to file
///
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
/// function.
////////////////////////////////////////////////////////////////////////////////
int TRI_SaveParameterInfo (char const* path,
TRI_col_info_t* info) {
int TRI_SaveParameterInfoCollection (char const* path, TRI_col_info_t* info) {
TRI_json_t* json;
char* filename;
bool ok;
@ -598,9 +602,12 @@ int TRI_SaveParameterInfo (char const* path,
////////////////////////////////////////////////////////////////////////////////
/// @brief updates the parameter info block
///
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
/// function.
////////////////////////////////////////////////////////////////////////////////
bool TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
int TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
TRI_col_info_t parameter;
parameter._version = collection->_version;
@ -612,11 +619,14 @@ bool TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
parameter._deleted = collection->_deleted;
parameter._size = sizeof(TRI_col_info_t);
return TRI_SaveParameterInfo(collection->_directory, &parameter) == TRI_ERROR_NO_ERROR;
return TRI_SaveParameterInfoCollection(collection->_directory, &parameter);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a collection
///
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
/// function.
////////////////////////////////////////////////////////////////////////////////
int TRI_RenameCollection (TRI_collection_t* collection, char const* name) {
@ -632,7 +642,7 @@ int TRI_RenameCollection (TRI_collection_t* collection, char const* name) {
parameter._deleted = collection->_deleted;
parameter._size = sizeof(TRI_col_info_t);
res = TRI_SaveParameterInfo(collection->_directory, &parameter);
res = TRI_SaveParameterInfoCollection(collection->_directory, &parameter);
if (res == TRI_ERROR_NO_ERROR) {
TRI_CopyString(collection->_name, name, sizeof(collection->_name));
@ -770,8 +780,7 @@ void TRI_IterateIndexCollection (TRI_collection_t* collection,
/// @brief opens an existing collection
////////////////////////////////////////////////////////////////////////////////
TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection,
char const* path) {
TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection, char const* path) {
TRI_col_info_t info;
bool freeCol;
bool ok;
@ -787,8 +796,8 @@ TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection,
return NULL;
}
// read parameter block
res = TRI_LoadParameterInfo(path, &info);
// read parameter block, no need to lock as we are opening the collection
res = TRI_LoadParameterInfoCollection(path, &info);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot save collection parameter '%s': '%s'", path, TRI_last_error());

View File

@ -272,19 +272,19 @@ void TRI_FreeCollection (TRI_collection_t*);
/// @brief creates a parameter info block from file
////////////////////////////////////////////////////////////////////////////////
int TRI_LoadParameterInfo (char const* filename, TRI_col_info_t*);
int TRI_LoadParameterInfoCollection (char const* filename, TRI_col_info_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief saves a parameter info block to file
////////////////////////////////////////////////////////////////////////////////
int TRI_SaveParameterInfo (char const* filename, TRI_col_info_t*);
int TRI_SaveParameterInfoCollection (char const* filename, TRI_col_info_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief updates the parameter info block
////////////////////////////////////////////////////////////////////////////////
bool TRI_UpdateParameterInfoCollection (TRI_collection_t*);
int TRI_UpdateParameterInfoCollection (TRI_collection_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a collection

View File

@ -27,13 +27,12 @@
#include "compactor.h"
#include <BasicsC/conversions.h>
#include <BasicsC/files.h>
#include <BasicsC/logging.h>
#include <BasicsC/strings.h>
#include <VocBase/simple-collection.h>
#include <VocBase/shadow-data.h>
#include "BasicsC/conversions.h"
#include "BasicsC/files.h"
#include "BasicsC/logging.h"
#include "BasicsC/strings.h"
#include "VocBase/simple-collection.h"
#include "VocBase/shadow-data.h"
// -----------------------------------------------------------------------------
// --SECTION-- private constants
@ -70,7 +69,7 @@ static int const COMPACTOR_INTERVAL = 5 * 1000 * 1000;
/// to allow the gc to start when waiting for a journal to appear.
////////////////////////////////////////////////////////////////////////////////
static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* sim,
TRI_voc_size_t size,
TRI_df_marker_t** result) {
TRI_datafile_t* datafile;
@ -78,34 +77,34 @@ static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
size_t i;
size_t n;
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
while (true) {
n = collection->base.base._compactors._length;
n = sim->base.base._compactors._length;
for (i = 0; i < n; ++i) {
// select datafile
datafile = collection->base.base._compactors._buffer[i];
datafile = sim->base.base._compactors._buffer[i];
// try to reserve space
ok = TRI_ReserveElementDatafile(datafile, size, result);
// in case of full datafile, try next
if (ok) {
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return datafile;
}
else if (! ok && TRI_errno() != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return NULL;
}
}
TRI_WaitCondition(&collection->_journalsCondition);
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
////////////////////////////////////////////////////////////////////////////////
@ -194,6 +193,7 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
TRI_doc_mptr_t const* found;
TRI_sim_collection_t* sim;
TRI_voc_fid_t fid;
bool deleted;
int res;
sim = data;
@ -217,18 +217,18 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
d = (TRI_doc_document_marker_t const*) marker;
// check if the document is still active
TRI_ReadLockReadWriteLock(&sim->_lock);
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
deleted = found == NULL || found->_deletion != 0;
if (found == NULL || found->_deletion != 0) {
TRI_ReadUnlockReadWriteLock(&sim->_lock);
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
if (deleted) {
LOG_TRACE("found a stale document: %lu", d->_did);
return true;
}
TRI_ReadUnlockReadWriteLock(&sim->_lock);
// write to compactor files
res = CopyDocument(sim, marker, &result, &fid);
@ -238,17 +238,24 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
}
// check if the document is still active
TRI_WriteLockReadWriteLock(&sim->_lock);
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
deleted = found == NULL || found->_deletion != 0;
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// update datafile
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid);
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
if (found == NULL || found->_deletion != 0) {
if (deleted) {
dfi->_numberDead += 1;
dfi->_sizeDead += marker->_size - markerSize;
LOG_DEBUG("found a stale document after copying: %lu", d->_did);
TRI_WriteUnlockReadWriteLock(&sim->_lock);
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
return true;
}
@ -262,14 +269,11 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
dfi->_numberAlive += 1;
dfi->_sizeAlive += marker->_size - markerSize;
TRI_WriteUnlockReadWriteLock(&sim->_lock);
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
}
// deletion
else if (marker->_type == TRI_DOC_MARKER_DELETION) {
// TRI_doc_deletion_marker_t const* d;
// d = (TRI_doc_deletion_marker_t const*) marker;
// TODO: remove TRI_doc_deletion_marker_t from file
// write to compactor files
@ -281,13 +285,12 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
}
// update datafile info
TRI_WriteLockReadWriteLock(&sim->_lock);
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid);
dfi->_numberDeletion += 1;
TRI_WriteUnlockReadWriteLock(&sim->_lock);
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
}
return true;
@ -318,7 +321,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
size_t i;
// locate the datafile
TRI_ReadLockReadWriteLock(&sim->_lock);
TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
n = sim->base.base._datafiles._length;
@ -330,7 +333,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
}
}
TRI_ReadUnlockReadWriteLock(&sim->_lock);
TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
if (i == n) {
return;
@ -350,7 +353,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
WaitCompactSync(sim, df);
// remove the datafile from the list of datafiles
TRI_ReadLockReadWriteLock(&sim->_lock);
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
n = sim->base.base._datafiles._length;
@ -363,7 +366,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
}
}
TRI_ReadUnlockReadWriteLock(&sim->_lock);
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
if (i == n) {
LOG_WARNING("failed to locate the datafile '%lu'", (unsigned long) df->_fid);
@ -386,7 +389,7 @@ static void CompactifySimCollection (TRI_sim_collection_t* sim) {
TRI_InitVector(&vector, sizeof(TRI_doc_datafile_info_t));
// copy datafile information
TRI_ReadLockReadWriteLock(&sim->_lock);
TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
n = sim->base.base._datafiles._length;
@ -400,7 +403,7 @@ static void CompactifySimCollection (TRI_sim_collection_t* sim) {
TRI_PushBackVector(&vector, dfi);
}
TRI_ReadUnlockReadWriteLock(&sim->_lock);
TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
// handle datafiles with dead objects
for (i = 0; i < vector._length; ++i) {
@ -532,9 +535,11 @@ void TRI_CompactorVocBase (void* data) {
TRI_col_type_e type;
// copy all collections
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
n = collections._length;
@ -544,14 +549,15 @@ void TRI_CompactorVocBase (void* data) {
collection = collections._buffer[i];
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_LOADED && collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
doc = collection->_collection;
if (doc == NULL) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
continue;
}
doc = collection->_collection;
type = doc->base._type;
// for simple document collection, compactify datafiles
@ -561,7 +567,7 @@ void TRI_CompactorVocBase (void* data) {
}
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
// now release the lock and maybe unload the collection or some datafiles
if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {

View File

@ -811,7 +811,7 @@ bool TRI_CloseDatafile (TRI_datafile_t* datafile) {
////////////////////////////////////////////////////////////////////////////////
bool TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
bool ok;
int res;
if (TRI_ExistsFile(filename)) {
LOG_ERROR("cannot overwrite datafile '%s'", filename);
@ -820,9 +820,9 @@ bool TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
return false;
}
ok = TRI_RenameFile(datafile->_filename, filename);
res = TRI_RenameFile(datafile->_filename, filename);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
datafile->_state = TRI_DF_STATE_RENAME_ERROR;
datafile->_lastError = TRI_set_errno(TRI_ERROR_SYS_ERROR);

View File

@ -106,7 +106,7 @@ static TRI_json_t* JsonPrimary (TRI_index_t* idx, TRI_doc_collection_t* collecti
/// to allow the gc to start when waiting for a journal to appear.
////////////////////////////////////////////////////////////////////////////////
static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* sim,
TRI_voc_size_t size,
TRI_df_marker_t** result) {
TRI_datafile_t* datafile;
@ -114,34 +114,34 @@ static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
size_t i;
size_t n;
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
while (true) {
n = collection->base.base._journals._length;
n = sim->base.base._journals._length;
for (i = 0; i < n; ++i) {
// select datafile
datafile = collection->base.base._journals._buffer[i];
datafile = sim->base.base._journals._buffer[i];
// try to reserve space
res = TRI_ReserveElementDatafile(datafile, size, result);
// in case of full datafile, try next
if (res == TRI_ERROR_NO_ERROR) {
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return datafile;
}
else if (res != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return NULL;
}
}
TRI_WaitCondition(&collection->_journalsCondition);
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
////////////////////////////////////////////////////////////////////////////////
@ -153,19 +153,21 @@ static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
/// datafile and has been synced.
////////////////////////////////////////////////////////////////////////////////
static void WaitSync (TRI_sim_collection_t* collection,
static void WaitSync (TRI_sim_collection_t* sim,
TRI_datafile_t* journal,
char const* position) {
TRI_collection_t* base;
base = &collection->base.base;
base = &sim->base.base;
// no condition at all. Do NOT acquire a lock, in the worst
// case we will miss a parameter change.
// no condition at all
if (! base->_waitForSync) {
return;
}
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
// wait until the sync condition is fullfilled
while (true) {
@ -186,17 +188,17 @@ static void WaitSync (TRI_sim_collection_t* collection,
}
// we have to wait a bit longer
TRI_WaitCondition(&collection->_journalsCondition);
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief writes data to the journal and updates the barriers
////////////////////////////////////////////////////////////////////////////////
static int WriteElement (TRI_sim_collection_t* collection,
static int WriteElement (TRI_sim_collection_t* sim,
TRI_datafile_t* journal,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
@ -215,10 +217,12 @@ static int WriteElement (TRI_sim_collection_t* collection,
return res;
}
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
journal->_written = ((char*) result) + marker->_size;
journal->_nWritten++;
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR;
}
@ -1145,11 +1149,11 @@ static int DeleteShapedJson (TRI_doc_collection_t* document,
/// @brief read locks a collection
////////////////////////////////////////////////////////////////////////////////
static int BeginRead (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection;
static int BeginRead (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document;
TRI_ReadLockReadWriteLock(&collection->_lock);
sim = (TRI_sim_collection_t*) doc;
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR;
}
@ -1158,11 +1162,11 @@ static int BeginRead (TRI_doc_collection_t* document) {
/// @brief read unlocks a collection
////////////////////////////////////////////////////////////////////////////////
static int EndRead (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection;
static int EndRead (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document;
TRI_ReadUnlockReadWriteLock(&collection->_lock);
sim = (TRI_sim_collection_t*) doc;
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR;
}
@ -1171,11 +1175,11 @@ static int EndRead (TRI_doc_collection_t* document) {
/// @brief write locks a collection
////////////////////////////////////////////////////////////////////////////////
static int BeginWrite (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection;
static int BeginWrite (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document;
TRI_WriteLockReadWriteLock(&collection->_lock);
sim = (TRI_sim_collection_t*) doc;
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR;
}
@ -1185,10 +1189,10 @@ static int BeginWrite (TRI_doc_collection_t* document) {
////////////////////////////////////////////////////////////////////////////////
static int EndWrite (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection;
TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
sim = (TRI_sim_collection_t*) document;
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR;
}
@ -1197,15 +1201,15 @@ static int EndWrite (TRI_doc_collection_t* document) {
/// @brief size of a document collection
////////////////////////////////////////////////////////////////////////////////
static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection;
static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* sim;
TRI_voc_size_t result;
collection = (TRI_sim_collection_t*) document;
sim = (TRI_sim_collection_t*) doc;
TRI_ReadLockReadWriteLock(&collection->_lock);
result = collection->_primaryIndex._nrUsed;
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
result = sim->_primaryIndex._nrUsed;
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return result;
}
@ -2348,42 +2352,39 @@ static bool FillIndex (TRI_sim_collection_t* collection,
/// @brief returns a description of all indexes
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* collection) {
TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim) {
TRI_vector_pointer_t* vector;
size_t n;
size_t i;
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
if (!vector) {
return NULL;
}
TRI_InitVectorPointer(vector);
// .............................................................................
// within read-lock the collection
// inside read-lock
// .............................................................................
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
n = collection->_indexes._length;
n = sim->_indexes._length;
for (i = 0; i < n; ++i) {
TRI_index_t* idx;
TRI_json_t* json;
idx = collection->_indexes._buffer[i];
idx = sim->_indexes._buffer[i];
json = idx->json(idx, &collection->base);
json = idx->json(idx, &sim->base);
if (json != NULL) {
TRI_PushBackVectorPointer(vector, json);
}
}
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without read-lock
// outside read-lock
// .............................................................................
return vector;
@ -2393,31 +2394,31 @@ TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* collection
/// @brief returns a description of anindex
////////////////////////////////////////////////////////////////////////////////
TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t iid) {
TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* sim, TRI_idx_iid_t iid) {
TRI_index_t* idx = NULL;
size_t n;
size_t i;
// .............................................................................
// within read-lock the collection
// inside read-lock
// .............................................................................
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
n = collection->_indexes._length;
n = sim->_indexes._length;
for (i = 0; i < n; ++i) {
idx = collection->_indexes._buffer[i];
idx = sim->_indexes._buffer[i];
if (idx->_iid == iid) {
break;
}
}
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without read-lock
// outside read-lock
// .............................................................................
return i < n ? idx : NULL;
@ -2427,8 +2428,7 @@ TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_i
/// @brief drops an index
////////////////////////////////////////////////////////////////////////////////
bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t iid) {
TRI_vector_pointer_t* vector;
bool TRI_DropIndexSimCollection (TRI_sim_collection_t* sim, TRI_idx_iid_t iid) {
TRI_index_t* found;
size_t n;
size_t i;
@ -2437,42 +2437,35 @@ bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t
return true;
}
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
if (!vector) {
return false;
}
found = NULL;
TRI_InitVectorPointer(vector);
// .............................................................................
// within write-lock
// inside write-lock
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
n = collection->_indexes._length;
n = sim->_indexes._length;
for (i = 0; i < n; ++i) {
TRI_index_t* idx;
idx = collection->_indexes._buffer[i];
idx = sim->_indexes._buffer[i];
if (idx->_iid == iid) {
found = TRI_RemoveVectorPointer(&collection->_indexes, i);
found = TRI_RemoveVectorPointer(&sim->_indexes, i);
break;
}
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without write-lock
// outside write-lock
// .............................................................................
if (found != NULL) {
return TRI_RemoveIndexFile(&collection->base, found);
return TRI_RemoveIndexFile(&sim->base, found);
}
else {
return false;
@ -2560,10 +2553,10 @@ static TRI_json_t* JsonPrimary (TRI_index_t* idx, TRI_doc_collection_t* collecti
json = TRI_CreateArrayJson();
TRI_Insert2ArrayJson(json, "iid", TRI_CreateNumberJson(0));
TRI_Insert2ArrayJson(json, "type", TRI_CreateStringCopyJson("primary"));
TRI_Insert2ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1));
TRI_Insert2ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id"));
TRI_Insert3ArrayJson(json, "iid", TRI_CreateNumberJson(0));
TRI_Insert3ArrayJson(json, "type", TRI_CreateStringCopyJson("primary"));
TRI_Insert3ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1));
TRI_Insert3ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id"));
return json;
}
@ -2639,7 +2632,7 @@ TRI_vector_pointer_t TRI_LookupEdgesSimCollection (TRI_sim_collection_t* edges,
/// @brief adds a geo index to a collection
////////////////////////////////////////////////////////////////////////////////
static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collection,
static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* sim,
char const* location,
char const* latitude,
char const* longitude,
@ -2657,7 +2650,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
loc = 0;
idx = NULL;
shaper = collection->base._shaper;
shaper = sim->base._shaper;
if (location != NULL) {
loc = shaper->findAttributePathByName(shaper, location);
@ -2673,10 +2666,10 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
// check, if we know the index
if (location != NULL) {
idx = TRI_LookupGeoIndexSimCollection(collection, loc, geoJson);
idx = TRI_LookupGeoIndexSimCollection(sim, loc, geoJson);
}
else if (longitude != NULL && latitude != NULL) {
idx = TRI_LookupGeoIndex2SimCollection(collection, lat, lon);
idx = TRI_LookupGeoIndex2SimCollection(sim, lat, lon);
}
else {
TRI_set_errno(TRI_ERROR_INTERNAL);
@ -2694,14 +2687,14 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
// create a new index
if (location != NULL) {
idx = TRI_CreateGeoIndex(&collection->base, location, loc, geoJson);
idx = TRI_CreateGeoIndex(&sim->base, location, loc, geoJson);
LOG_TRACE("created geo-index for location '%s': %d",
location,
(unsigned long) loc);
}
else if (longitude != NULL && latitude != NULL) {
idx = TRI_CreateGeoIndex2(&collection->base, latitude, lat, longitude, lon);
idx = TRI_CreateGeoIndex2(&sim->base, latitude, lat, longitude, lon);
LOG_TRACE("created geo-index for location '%s': %d, %d",
location,
@ -2714,7 +2707,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
}
// initialises the index with all existing documents
ok = FillIndex(collection, idx);
ok = FillIndex(sim, idx);
if (! ok) {
TRI_FreeGeoIndex(idx);
@ -2722,7 +2715,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
}
// and store index
TRI_PushBackVectorPointer(&collection->_indexes, idx);
TRI_PushBackVectorPointer(&sim->_indexes, idx);
return idx;
}
@ -2850,7 +2843,6 @@ static TRI_index_t* CreateSkiplistIndexSimCollection (TRI_sim_collection_t* coll
TRI_PushBackVectorPointer(&fields, path);
}
// ...........................................................................
// Attempt to find an existing index which matches the attributes above.
// If a suitable index is found, return that one otherwise we need to create
@ -2978,7 +2970,6 @@ TRI_index_t* TRI_LookupGeoIndex2SimCollection (TRI_sim_collection_t* collection,
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds a hash index (unique or non-unique)
////////////////////////////////////////////////////////////////////////////////
@ -3003,7 +2994,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
TRI_index_t* idx = collection->_indexes._buffer[j];
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
bool found = true;
// .........................................................................
// check that the type of the index is in fact a hash index
@ -3012,7 +3002,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
if (idx->_type != TRI_IDX_TYPE_HASH_INDEX) {
continue;
}
// .........................................................................
// check that the number of paths (fields) in the hash index matches that
@ -3023,7 +3012,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
continue;
}
// .........................................................................
// Go through all the attributes and see if they match
// .........................................................................
@ -3031,6 +3019,7 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
for (k = 0; k < paths->_length; ++k) {
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths,k)));
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
if (field != shape) {
found = false;
break;
@ -3073,7 +3062,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
TRI_skiplist_index_t* skiplistIndex = (TRI_skiplist_index_t*) idx;
bool found = true;
// .........................................................................
// check that the type of the index is in fact a skiplist index
// .........................................................................
@ -3081,7 +3069,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
if (idx->_type != TRI_IDX_TYPE_SKIPLIST_INDEX) {
continue;
}
// .........................................................................
// check that the number of paths (fields) in the index matches that
@ -3092,7 +3079,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
continue;
}
// .........................................................................
// Go through all the attributes and see if they match
// .........................................................................
@ -3100,6 +3086,7 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
for (k = 0; k < paths->_length; ++k) {
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&skiplistIndex->_paths,k)));
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
if (field != shape) {
found = false;
break;
@ -3120,32 +3107,32 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
/// @brief ensures that a geo index exists
////////////////////////////////////////////////////////////////////////////////
TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* collection,
TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* sim,
char const* location,
bool geoJson) {
TRI_index_t* idx;
bool ok;
// .............................................................................
// within write-lock the collection
// inside write-lock
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
idx = CreateGeoIndexSimCollection(collection, location, NULL, NULL, geoJson, 0);
idx = CreateGeoIndexSimCollection(sim, location, NULL, NULL, geoJson, 0);
if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0;
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without write-lock
// outside write-lock
// .............................................................................
ok = TRI_SaveIndex(&collection->base, idx);
ok = TRI_SaveIndex(&sim->base, idx);
return ok ? idx->_iid : 0;
}
@ -3154,32 +3141,32 @@ TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* collection,
/// @brief ensures that a geo index exists
////////////////////////////////////////////////////////////////////////////////
TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection,
TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* sim,
char const* latitude,
char const* longitude) {
TRI_index_t* idx;
bool ok;
// .............................................................................
// within write-lock the collection
// inside write-lock
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
idx = CreateGeoIndexSimCollection(collection, NULL, latitude, longitude, false, 0);
idx = CreateGeoIndexSimCollection(sim, NULL, latitude, longitude, false, 0);
if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0;
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without write-lock
// outside write-lock
// .............................................................................
ok = TRI_SaveIndex(&collection->base, idx);
ok = TRI_SaveIndex(&sim->base, idx);
return ok ? idx->_iid : 0;
}
@ -3189,43 +3176,37 @@ TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection
/// @brief ensures that a hash index exists
////////////////////////////////////////////////////////////////////////////////
TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* collection,
TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* sim,
const TRI_vector_t* attributes,
bool unique) {
TRI_index_t* idx;
bool ok;
// .............................................................................
// within write-lock the collection
// inside write-lock
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// Given the list of attributes (as strings)
// .............................................................................
idx = CreateHashIndexSimCollection(collection, attributes, 0, unique);
idx = CreateHashIndexSimCollection(sim, attributes, 0, unique);
if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0;
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without write-lock
// outside write-lock
// .............................................................................
ok = TRI_SaveIndex(&collection->base, idx);
ok = TRI_SaveIndex(&sim->base, idx);
if (ok) {
}
else {
assert(0);
}
return ok ? idx->_iid : 0;
}
@ -3233,42 +3214,36 @@ TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* collection,
/// @brief ensures that a skiplist index exists
////////////////////////////////////////////////////////////////////////////////
TRI_idx_iid_t TRI_EnsureSkiplistIndexSimCollection(TRI_sim_collection_t* collection,
TRI_idx_iid_t TRI_EnsureSkiplistIndexSimCollection(TRI_sim_collection_t* sim,
const TRI_vector_t* attributes,
bool unique) {
TRI_index_t* idx;
bool ok;
// .............................................................................
// within write-lock the collection
// inside write-lock the collection
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// Given the list of attributes (as strings)
// .............................................................................
idx = CreateSkiplistIndexSimCollection(collection, attributes, 0, unique);
idx = CreateSkiplistIndexSimCollection(sim, attributes, 0, unique);
if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0;
}
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// .............................................................................
// without write-lock
// outside write-lock
// .............................................................................
ok = TRI_SaveIndex(&collection->base, idx);
if (ok) {
}
else {
assert(0);
}
ok = TRI_SaveIndex(&sim->base, idx);
return ok ? idx->_iid : 0;
}

View File

@ -39,6 +39,103 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- public macros
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief read locks the journal files and the parameter file
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(a) \
TRI_ReadLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read unlocks the journal files and the parameter file
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(a) \
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the journal files and the parameter file
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(a) \
TRI_WriteLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write unlocks the journal files and the parameter file
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(a) \
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read locks the documents and indexes
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
TRI_ReadLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read unlocks the documents and indexes
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the documents and indexes
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
TRI_WriteLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write unlocks the documents and indexes
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief locks the journal entries
////////////////////////////////////////////////////////////////////////////////
#define TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
TRI_LockCondition(&(a)->_journalsCondition)
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks the journal entries
////////////////////////////////////////////////////////////////////////////////
#define TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
TRI_UnlockCondition(&(a)->_journalsCondition)
////////////////////////////////////////////////////////////////////////////////
/// @brief waits for the journal entries
////////////////////////////////////////////////////////////////////////////////
#define TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
TRI_WaitCondition(&(a)->_journalsCondition)
////////////////////////////////////////////////////////////////////////////////
/// @brief signals the journal entries
////////////////////////////////////////////////////////////////////////////////
#define TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
TRI_BroadcastCondition(&(a)->_journalsCondition)
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------

View File

@ -44,7 +44,7 @@
/// @brief checks if a file needs to be synced
////////////////////////////////////////////////////////////////////////////////
static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
static bool CheckSyncSimCollection (TRI_sim_collection_t* sim) {
TRI_collection_t* base;
TRI_datafile_t* journal;
TRI_voc_size_t nWritten;
@ -57,7 +57,7 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
size_t n;
worked = false;
base = &collection->base.base;
base = &sim->base.base;
// .............................................................................
// the only thread MODIFYING the _journals variable is this thread,
@ -69,21 +69,21 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
for (i = 0; i < n; ++i) {
journal = base->_journals._buffer[i];
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
synced = journal->_synced;
written = journal->_written;
nWritten = journal->_nWritten;
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (synced < written) {
worked = true;
ok = TRI_msync(journal->_fd, synced, written);
ti = TRI_microtime();
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (ok) {
journal->_synced = written;
@ -94,8 +94,8 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
journal->_state = TRI_DF_STATE_WRITE_ERROR;
}
TRI_BroadcastCondition(&collection->_journalsCondition);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (ok) {
LOG_TRACE("msync succeeded %p, size %lu", synced, (unsigned long)(written - synced));
@ -113,7 +113,7 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
/// @brief checks the journal of a document collection
////////////////////////////////////////////////////////////////////////////////
static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
static bool CheckJournalSimCollection (TRI_sim_collection_t* sim) {
TRI_collection_t* base;
TRI_datafile_t* journal;
bool worked;
@ -121,7 +121,7 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
size_t n;
worked = false;
base = &collection->base.base;
base = &sim->base.base;
// .............................................................................
// the only thread MODIFYING the _journals variable is this thread,
@ -138,9 +138,9 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
LOG_DEBUG("closing full journal '%s'", journal->_filename);
TRI_LockCondition(&collection->_journalsCondition);
TRI_CloseJournalDocCollection(&collection->base, i);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_CloseJournalDocCollection(&sim->base, i);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
n = base->_journals._length;
i = 0;
@ -153,16 +153,16 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
if (base->_journals._length == 0) {
worked = true;
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
journal = TRI_CreateJournalDocCollection(&collection->base);
journal = TRI_CreateJournalDocCollection(&sim->base);
if (journal != NULL) {
LOG_DEBUG("created new journal '%s'", journal->_filename);
}
TRI_BroadcastCondition(&collection->_journalsCondition);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
return worked;
@ -172,10 +172,9 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
/// @brief checks if a compactor file needs to be synced
////////////////////////////////////////////////////////////////////////////////
static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* sim) {
TRI_collection_t* base;
TRI_datafile_t* journal;
// TRI_voc_size_t nWritten;
bool ok;
bool worked;
char const* synced;
@ -185,7 +184,7 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
size_t n;
worked = false;
base = &collection->base.base;
base = &sim->base.base;
// .............................................................................
// the only thread MODIFYING the _compactors variable is this thread,
@ -197,22 +196,19 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
for (i = 0; i < n; ++i) {
journal = base->_compactors._buffer[i];
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
synced = journal->_synced;
written = journal->_written;
// TODO: remove if not used
// nWritten = journal->_nWritten;
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (synced < written) {
worked = true;
ok = TRI_msync(journal->_fd, synced, written);
ti = TRI_microtime();
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (ok) {
journal->_synced = written;
@ -222,8 +218,8 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
journal->_state = TRI_DF_STATE_WRITE_ERROR;
}
TRI_BroadcastCondition(&collection->_journalsCondition);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
if (ok) {
LOG_TRACE("msync succeeded %p, size %lu", synced, (unsigned long)(written - synced));
@ -241,7 +237,7 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
/// @brief checks the compactor of a document collection
////////////////////////////////////////////////////////////////////////////////
static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
static bool CheckCompactorSimCollection (TRI_sim_collection_t* sim) {
TRI_collection_t* base;
TRI_datafile_t* compactor;
bool worked;
@ -249,7 +245,7 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
size_t n;
worked = false;
base = &collection->base.base;
base = &sim->base.base;
// .............................................................................
// the only thread MODIFYING the _compactor variable is this thread,
@ -266,9 +262,9 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
LOG_DEBUG("closing full compactor '%s'", compactor->_filename);
TRI_LockCondition(&collection->_journalsCondition);
TRI_CloseCompactorDocCollection(&collection->base, i);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_CloseCompactorDocCollection(&sim->base, i);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
n = base->_compactors._length;
i = 0;
@ -281,16 +277,16 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
if (base->_compactors._length == 0) {
worked = true;
TRI_LockCondition(&collection->_journalsCondition);
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
compactor = TRI_CreateCompactorDocCollection(&collection->base);
compactor = TRI_CreateCompactorDocCollection(&sim->base);
if (compactor != NULL) {
LOG_DEBUG("created new compactor '%s'", compactor->_filename);
}
TRI_BroadcastCondition(&collection->_journalsCondition);
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
}
return worked;
@ -328,9 +324,11 @@ void TRI_SynchroniserVocBase (void* data) {
worked = false;
// copy all collections
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
n = collections._length;
@ -341,10 +339,10 @@ void TRI_SynchroniserVocBase (void* data) {
collection = collections._buffer[i];
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_LOADED) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
continue;
}
@ -367,7 +365,7 @@ void TRI_SynchroniserVocBase (void* data) {
worked |= result;
}
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
}
if (! worked) {

View File

@ -164,17 +164,17 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection = data;
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false;
}
if (collection->_collection == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true;
}
@ -185,7 +185,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_LOADED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false;
}
@ -200,7 +200,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true;
}
@ -209,7 +209,136 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_UNLOADED;
collection->_collection = NULL;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops a collection
////////////////////////////////////////////////////////////////////////////////
static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
TRI_sim_collection_t* sim;
TRI_vocbase_col_t* collection;
TRI_vocbase_t* vocbase;
regmatch_t matches[3];
regex_t re;
char* tmp1;
char* tmp2;
char* tmp3;
char* newFilename;
int res;
int i;
collection = data;
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_DELETED) {
LOG_ERROR("someone resurrected the collection '%s'", collection->_name);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false;
}
// .............................................................................
// unload collection
// .............................................................................
if (collection->_collection != NULL) {
if (collection->_collection->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
LOG_ERROR("cannot drop collection '%s' of type '%d'",
collection->_name,
(int) collection->_collection->base._type);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false;
}
sim = (TRI_sim_collection_t*) collection->_collection;
res = TRI_CloseSimCollection(sim);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("failed to close collection '%s': %s",
collection->_name,
TRI_last_error());
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true;
}
TRI_FreeSimCollection(sim);
collection->_collection = NULL;
}
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
// .............................................................................
// remove from list of collections
// .............................................................................
vocbase = collection->_vocbase;
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
for (i = 0; i < vocbase->_collections._length; ++i) {
if (vocbase->_collections._buffer[i] == collection) {
TRI_RemoveVectorPointer(&vocbase->_collections, i);
break;
}
}
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
// .............................................................................
// rename collection directory
// .............................................................................
if (collection->_path != NULL) {
regcomp(&re, "^(.*)/collection-([0-9][0-9]*)$", REG_ICASE | REG_EXTENDED);
if (regexec(&re, collection->_path, sizeof(matches) / sizeof(matches[0]), matches, 0) == 0) {
char const* first = collection->_path + matches[1].rm_so;
size_t firstLen = matches[1].rm_eo - matches[1].rm_so;
char const* second = collection->_path + matches[2].rm_so;
size_t secondLen = matches[2].rm_eo - matches[2].rm_so;
tmp1 = TRI_DuplicateString2(first, firstLen);
tmp2 = TRI_DuplicateString2(second, secondLen);
tmp3 = TRI_Concatenate2String("deleted-", tmp2);
TRI_FreeString(tmp2);
newFilename = TRI_Concatenate2File(tmp1, tmp3);
TRI_FreeString(tmp1);
TRI_FreeString(tmp3);
res = TRI_RenameFile(collection->_path, newFilename);
TRI_FreeString(newFilename);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot rename dropped collection '%s' from '%s' to '%s'",
collection->_name,
collection->_path,
newFilename);
}
else {
LOG_DEBUG("renamed dropped collection '%s' from '%s' to '%s'",
collection->_name,
collection->_path,
newFilename);
}
}
else {
LOG_ERROR("cannot rename dropped collection '%s': unknown path '%s'",
collection->_name,
collection->_path);
}
regfree(&re);
}
return true;
}
@ -317,11 +446,15 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
if (TRI_IsDirectory(file)) {
TRI_col_info_t info;
res = TRI_LoadParameterInfo(file, &info);
// no need to lock as we are scanning
res = TRI_LoadParameterInfoCollection(file, &info);
if (res != TRI_ERROR_NO_ERROR) {
LOG_DEBUG("ignoring directory '%s' without valid parameter file '%s'", file, TRI_COL_PARAMETER_FILE);
}
else if (info._deleted) {
LOG_DEBUG("ignoring deleted collection '%s'", file);
}
else {
type = info._type;
@ -351,6 +484,8 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
TRI_FreeString(file);
}
regfree(&re);
TRI_DestroyVectorString(&files);
return TRI_ERROR_NO_ERROR;
}
@ -364,7 +499,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
TRI_vocbase_col_t* collection;
char wrong;
TRI_WriteLockReadWriteLock(&vocbase->_lock);
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// .............................................................................
// check that we have an existing name
@ -373,7 +508,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found.v != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c;
}
@ -385,7 +520,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("found illegal character in name: %c", wrong);
@ -397,13 +532,13 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
collection = AddCollection(vocbase, TRI_COL_TYPE_SIMPLE_DOCUMENT, name, TRI_NewTickVocBase(), NULL);
if (collection == NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL;
}
collection->_status = TRI_VOC_COL_STATUS_NEW_BORN;
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return collection;
}
@ -414,38 +549,38 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
TRI_col_type_e type;
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// cannot manifest a corrupted collection
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
// cannot manifest a deleted collection
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
}
// loaded, unloaded, or unloading are manifested
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
if (collection->_status != TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL);
}
@ -469,14 +604,15 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
if (sim == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_errno();
}
collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_collection = &sim->base;
collection->_path = TRI_DuplicateString(sim->base.base._directory);
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
else {
@ -484,7 +620,7 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
LOG_ERROR("unknown collection type '%d' in collection '%s'", (int) type, collection->_name);
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
}
}
@ -505,7 +641,7 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
// .............................................................................
// check if the collection is already loaded
TRI_ReadLockReadWriteLock(&collection->_lock);
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
@ -514,27 +650,27 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
}
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
}
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
// release the read lock and acquire a write lock, we have to do some work
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
// .............................................................................
// write lock
// .............................................................................
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// someone else loaded the collection, release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, collection);
}
@ -542,25 +678,25 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
// release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
collection->_status = TRI_VOC_COL_STATUS_LOADED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, collection);
}
// deleted, give up
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
}
// corrupted, give up
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
// new born, manifest collection, release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
res = ManifestCollectionVocBase(vocbase, collection);
@ -583,28 +719,29 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
if (sim == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
collection->_collection = &sim->base;
collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_path = TRI_DuplicateString(sim->base.base._directory);
// release the WRITE lock and try again
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, collection);
}
else {
LOG_ERROR("unknown collection type %d for '%s'", (int) type, collection->_name);
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
}
}
LOG_ERROR("unknown collection status %d for '%s'", (int) collection->_status, collection->_name);
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL);
}
@ -899,7 +1036,7 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
TRI_InitVectorPointer(&result);
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
for (i = 0; i < vocbase->_collectionsById._nrAlloc; ++i) {
found = vocbase->_collectionsById._table[i];
@ -909,7 +1046,7 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
}
}
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return result;
}
@ -921,9 +1058,9 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name) {
union { void const* v; TRI_vocbase_col_t* c; } found;
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c;
}
@ -935,9 +1072,9 @@ TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase, ch
TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_voc_cid_t id) {
union { void const* v; TRI_vocbase_col_t* c; } found;
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c;
}
@ -949,9 +1086,9 @@ TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
union { void const* v; TRI_vocbase_col_t* c; } found;
TRI_ReadLockReadWriteLock(&vocbase->_lock);
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
if (found.v != NULL) {
return found.c;
@ -977,7 +1114,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
char wrong;
void const* found;
TRI_WriteLockReadWriteLock(&vocbase->_lock);
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// .............................................................................
// check that we have a new name
@ -987,7 +1124,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("collection named '%s' already exists", name);
@ -999,7 +1136,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("found illegal character in name: %c", wrong);
@ -1020,14 +1157,14 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
sim = TRI_CreateSimCollection(vocbase->_path, parameter, 0);
if (sim == NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL;
}
doc = &sim->base;
}
else {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("unknown collection type: %d", parameter->_type);
@ -1048,14 +1185,15 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
TRI_FreeSimCollection((TRI_sim_collection_t*) doc);
}
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL;
}
collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_collection = doc;
collection->_path = TRI_DuplicateString(doc->base._directory);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return collection;
}
@ -1064,41 +1202,41 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
////////////////////////////////////////////////////////////////////////////////
int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
TRI_WriteLockReadWriteLock(&collection->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// cannot unload a corrupted collection
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
// a unloaded collection is unloaded
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// a unloading collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// a new born collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// a deleted collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// must be loaded
if (collection->_status != TRI_VOC_COL_STATUS_LOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL);
}
@ -1112,24 +1250,130 @@ int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll
collection);
// release locks
TRI_WriteUnlockReadWriteLock(&collection->_lock);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops a (document) collection
////////////////////////////////////////////////////////////////////////////////
int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
TRI_col_info_t info;
int res;
// remove name and id
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, collection->_name);
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsById, &collection->_cid);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
// mark collection as deleted
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// .............................................................................
// collection already deleted
// .............................................................................
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// .............................................................................
// new born collection, no datafile/parameter file exists
// .............................................................................
else if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
// .............................................................................
// collection is unloaded
// .............................................................................
else if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
res = TRI_LoadParameterInfoCollection(collection->_path, &info);
if (res != TRI_ERROR_NO_ERROR) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res);
}
if (! info._deleted) {
info._deleted = true;
res = TRI_SaveParameterInfoCollection(collection->_path, &info);
if (res != TRI_ERROR_NO_ERROR) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res);
}
}
collection->_status = TRI_VOC_COL_STATUS_DELETED;
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
DropCollectionCallback(0, collection);
return TRI_ERROR_NO_ERROR;
}
// .............................................................................
// collection is loaded
// .............................................................................
else if (collection->_status == TRI_VOC_COL_STATUS_LOADED || collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
collection->_collection->base._deleted = true;
res = TRI_UpdateParameterInfoCollection(&collection->_collection->base);
if (res != TRI_ERROR_NO_ERROR) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return res;
}
collection->_status = TRI_VOC_COL_STATUS_DELETED;
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
// added callback for dropping
TRI_CreateBarrierCollection(&collection->_collection->_barrierList,
&collection->_collection->base,
DropCollectionCallback,
collection);
return TRI_ERROR_NO_ERROR;
}
// .............................................................................
// upps, unknown status
// .............................................................................
else {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a (document) collection
////////////////////////////////////////////////////////////////////////////////
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col, char const* newName) {
TRI_col_info_t info;
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection, char const* newName) {
union { TRI_vocbase_col_t* v; TRI_vocbase_col_t const* c; } cnv;
TRI_col_info_t info;
void* found;
char wrong;
char const* oldName;
int res;
// old name should be different
oldName = col->_name;
oldName = collection->_name;
if (TRI_EqualString(oldName, newName)) {
return TRI_ERROR_NO_ERROR;
@ -1144,34 +1388,34 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
}
// lock collection because we are going to change the name
TRI_WriteLockReadWriteLock(&col->_lock);
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// the must be done after the collection lock
TRI_WriteLockReadWriteLock(&vocbase->_lock);
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// cannot rename a corrupted collection
if (col->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
}
// cannot rename a deleted collection
if (col->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
}
// check if the new name is unused
cnv.c = col;
cnv.c = collection;
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false);
if (found != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_NAME);
}
@ -1180,59 +1424,59 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
// new born collection, no datafile/parameter file exists
// .............................................................................
if (col->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_CopyString(col->_name, newName, sizeof(col->_name));
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
}
// .............................................................................
// collection is unloaded
// .............................................................................
else if (col->_status == TRI_VOC_COL_STATUS_UNLOADED) {
res = TRI_LoadParameterInfo(col->_path, &info);
else if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
res = TRI_LoadParameterInfoCollection(collection->_path, &info);
if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res);
}
TRI_CopyString(info._name, newName, sizeof(info._name));
res = TRI_SaveParameterInfo(col->_path, &info);
res = TRI_SaveParameterInfoCollection(collection->_path, &info);
if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res);
}
TRI_CopyString(col->_name, newName, sizeof(col->_name));
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
}
// .............................................................................
// collection is loaded
// .............................................................................
else if (col->_status != TRI_VOC_COL_STATUS_LOADED || col->_status != TRI_VOC_COL_STATUS_UNLOADING) {
res = TRI_RenameCollection(&col->_collection->base, newName);
else if (collection->_status != TRI_VOC_COL_STATUS_LOADED || collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
res = TRI_RenameCollection(&collection->_collection->base, newName);
if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res);
}
TRI_CopyString(col->_name, newName, sizeof(col->_name));
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
}
// .............................................................................
@ -1242,8 +1486,8 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
else {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL);
}
@ -1254,8 +1498,8 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WriteUnlockReadWriteLock(&col->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR;
}
@ -1273,7 +1517,7 @@ int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collect
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
TRI_ReadUnlockReadWriteLock(&collection->_lock);
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
}
////////////////////////////////////////////////////////////////////////////////
@ -1289,9 +1533,9 @@ TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t* vocbase, char
// check that we have an existing name
// .............................................................................
TRI_WriteLockReadWriteLock(&vocbase->_lock);
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
collection = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
if (collection == NULL) {
LOG_ERROR("unknown collection '%s'", name);

View File

@ -40,10 +40,83 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- forward declarations
// -----------------------------------------------------------------------------
struct TRI_doc_collection_s;
struct TRI_col_parameter_s;
struct TRI_shadow_store_s;
// -----------------------------------------------------------------------------
// --SECTION-- public macros
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief read locks the collections structure
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_LOCK_COLLECTIONS_VOCBASE(a) \
TRI_ReadLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read unlocks the collections structure
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(a) \
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the collections structure
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(a) \
TRI_WriteLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write unlocks the collections structure
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(a) \
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read locks the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_LOCK_STATUS_VOCBASE_COL(a) \
TRI_ReadLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief read unlocks the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
#define TRI_READ_UNLOCK_STATUS_VOCBASE_COL(a) \
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_LOCK_STATUS_VOCBASE_COL(a) \
TRI_WriteLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write unlocks the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
#define TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(a) \
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public constants
// -----------------------------------------------------------------------------
@ -311,7 +384,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t*);
/// @brief returns all known collections
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase);
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up a (document) collection by name
@ -341,13 +414,19 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t*, struct TRI_col_p
/// @brief unloads a (document) collection
////////////////////////////////////////////////////////////////////////////////
int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
int TRI_UnloadCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief drops a (document) collection
////////////////////////////////////////////////////////////////////////////////
int TRI_DropCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a (document) collection
////////////////////////////////////////////////////////////////////////////////
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col, char const* name);
int TRI_RenameCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*, char const* name);
////////////////////////////////////////////////////////////////////////////////
/// @brief locks a (document) collection for usage, loading or manifesting it
@ -356,7 +435,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
/// collection lock by yourself.
////////////////////////////////////////////////////////////////////////////////
int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
int TRI_UseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief locks a (document) collection for usage by name
@ -366,19 +445,19 @@ int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
/// when you are done with the collection.
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name);
TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t*, char const* name);
////////////////////////////////////////////////////////////////////////////////
/// @brief releases a (document) collection from usage
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief releases a (document) collection from usage
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}