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 /// @brief renames a file
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool TRI_RenameFile (char const* old, char const* filename) { int TRI_RenameFile (char const* old, char const* filename) {
int res; int res;
res = rename(old, filename); res = rename(old, filename);
if (res != 0) { 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); 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 /// @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 /// @brief unlinks a file

View File

@ -652,14 +652,14 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
return false; return false;
} }
ok = TRI_RenameFile(tmp, filename); res = TRI_RenameFile(tmp, filename);
if (! ok) { if (res != TRI_ERROR_NO_ERROR) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR); LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
TRI_UnlinkFile(tmp); TRI_UnlinkFile(tmp);
TRI_FreeString(tmp); TRI_FreeString(tmp);
return false;
return res;
} }
TRI_FreeString(tmp); 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()); 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 /// @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(); 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; TRI_vocbase_col_status_e status = collection->_status;
if (status != TRI_VOC_COL_STATUS_LOADED) { if (status != TRI_VOC_COL_STATUS_LOADED) {
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(result); return scope.Close(result);
} }
if (collection->_collection == 0) { 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"))); 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_Free(info);
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
return scope.Close(result); 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; 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()) { if (0 < argv.Length()) {
v8::Handle<v8::Value> par = argv[0]; v8::Handle<v8::Value> par = argv[0];
if (par->IsObject()) { if (par->IsObject()) {
v8::Handle<v8::Object> po = par->ToObject(); 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; bool waitForSync = sim->base.base._waitForSync;
TRI_UnlockCondition(&sim->_journalsCondition);
// extract sync after objects // extract sync after objects
if (po->Has(v8g->WaitForSyncKey)) { if (po->Has(v8g->WaitForSyncKey)) {
waitForSync = TRI_ObjectToBoolean(po->Get(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; 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); ReleaseCollection(collection);
return scope.Close(v8::ThrowException(v8::String::New(TRI_last_error()))); 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(); v8::Handle<v8::Object> result = v8::Object::New();
if (doc->base._type == TRI_COL_TYPE_SIMPLE_DOCUMENT) { if (doc->base._type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {
TRI_LockCondition(&sim->_journalsCondition);
TRI_voc_size_t maximalSize = sim->base.base._maximalSize; TRI_voc_size_t maximalSize = sim->base.base._maximalSize;
bool waitForSync = sim->base.base._waitForSync; bool waitForSync = sim->base.base._waitForSync;
TRI_UnlockCondition(&sim->_journalsCondition);
result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False()); result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False());
result->Set(v8g->JournalSizeKey, v8::Number::New(maximalSize)); 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"))); 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_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)); 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> 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> 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> 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> 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> EdgesFuncName = v8::Persistent<v8::String>::New(v8::String::New("edges"));
v8::Handle<v8::String> EnsureGeoIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("ensureGeoIndex")); 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(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol)); rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery)); 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(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol)); rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol)); 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(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol)); rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery)); 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(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol)); rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol)); 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; return NULL;
} }
// save the parameter block // save the parameter block (within create, no need to lock)
res = TRI_SaveParameterInfo(filename, parameter); res = TRI_SaveParameterInfoCollection(filename, parameter);
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeString(filename); TRI_FreeString(filename);
@ -477,10 +477,12 @@ void TRI_FreeCollection (TRI_collection_t* collection) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief creates a parameter info block from file /// @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, int TRI_LoadParameterInfoCollection (char const* path, TRI_col_info_t* parameter) {
TRI_col_info_t* parameter) {
TRI_json_t* json; TRI_json_t* json;
char* filename; char* filename;
char* error; char* error;
@ -560,10 +562,12 @@ int TRI_LoadParameterInfo (char const* path,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief saves a parameter info block to file /// @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, int TRI_SaveParameterInfoCollection (char const* path, TRI_col_info_t* info) {
TRI_col_info_t* info) {
TRI_json_t* json; TRI_json_t* json;
char* filename; char* filename;
bool ok; bool ok;
@ -598,9 +602,12 @@ int TRI_SaveParameterInfo (char const* path,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief updates the parameter info block /// @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; TRI_col_info_t parameter;
parameter._version = collection->_version; parameter._version = collection->_version;
@ -612,11 +619,14 @@ bool TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
parameter._deleted = collection->_deleted; parameter._deleted = collection->_deleted;
parameter._size = sizeof(TRI_col_info_t); 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 /// @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) { 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._deleted = collection->_deleted;
parameter._size = sizeof(TRI_col_info_t); 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) { if (res == TRI_ERROR_NO_ERROR) {
TRI_CopyString(collection->_name, name, sizeof(collection->_name)); TRI_CopyString(collection->_name, name, sizeof(collection->_name));
@ -770,8 +780,7 @@ void TRI_IterateIndexCollection (TRI_collection_t* collection,
/// @brief opens an existing collection /// @brief opens an existing collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection, TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection, char const* path) {
char const* path) {
TRI_col_info_t info; TRI_col_info_t info;
bool freeCol; bool freeCol;
bool ok; bool ok;
@ -787,8 +796,8 @@ TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection,
return NULL; return NULL;
} }
// read parameter block // read parameter block, no need to lock as we are opening the collection
res = TRI_LoadParameterInfo(path, &info); res = TRI_LoadParameterInfoCollection(path, &info);
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot save collection parameter '%s': '%s'", path, TRI_last_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 /// @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 /// @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 /// @brief updates the parameter info block
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool TRI_UpdateParameterInfoCollection (TRI_collection_t*); int TRI_UpdateParameterInfoCollection (TRI_collection_t*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief renames a collection /// @brief renames a collection

View File

@ -27,13 +27,12 @@
#include "compactor.h" #include "compactor.h"
#include <BasicsC/conversions.h> #include "BasicsC/conversions.h"
#include <BasicsC/files.h> #include "BasicsC/files.h"
#include <BasicsC/logging.h> #include "BasicsC/logging.h"
#include <BasicsC/strings.h> #include "BasicsC/strings.h"
#include "VocBase/simple-collection.h"
#include <VocBase/simple-collection.h> #include "VocBase/shadow-data.h"
#include <VocBase/shadow-data.h>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private constants // --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. /// 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_voc_size_t size,
TRI_df_marker_t** result) { TRI_df_marker_t** result) {
TRI_datafile_t* datafile; TRI_datafile_t* datafile;
@ -78,34 +77,34 @@ static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
size_t i; size_t i;
size_t n; size_t n;
TRI_LockCondition(&collection->_journalsCondition); TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
while (true) { while (true) {
n = collection->base.base._compactors._length; n = sim->base.base._compactors._length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
// select datafile // select datafile
datafile = collection->base.base._compactors._buffer[i]; datafile = sim->base.base._compactors._buffer[i];
// try to reserve space // try to reserve space
ok = TRI_ReserveElementDatafile(datafile, size, result); ok = TRI_ReserveElementDatafile(datafile, size, result);
// in case of full datafile, try next // in case of full datafile, try next
if (ok) { if (ok) {
TRI_UnlockCondition(&collection->_journalsCondition); TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return datafile; return datafile;
} }
else if (! ok && TRI_errno() != TRI_ERROR_AVOCADO_DATAFILE_FULL) { else if (! ok && TRI_errno() != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
TRI_UnlockCondition(&collection->_journalsCondition); TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return NULL; 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_doc_mptr_t const* found;
TRI_sim_collection_t* sim; TRI_sim_collection_t* sim;
TRI_voc_fid_t fid; TRI_voc_fid_t fid;
bool deleted;
int res; int res;
sim = data; 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; d = (TRI_doc_document_marker_t const*) marker;
// check if the document is still active // 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); found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
deleted = found == NULL || found->_deletion != 0;
if (found == NULL || found->_deletion != 0) { TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
TRI_ReadUnlockReadWriteLock(&sim->_lock);
if (deleted) {
LOG_TRACE("found a stale document: %lu", d->_did); LOG_TRACE("found a stale document: %lu", d->_did);
return true; return true;
} }
TRI_ReadUnlockReadWriteLock(&sim->_lock);
// write to compactor files // write to compactor files
res = CopyDocument(sim, marker, &result, &fid); 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 // 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); 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->_numberDead += 1;
dfi->_sizeDead += marker->_size - markerSize; dfi->_sizeDead += marker->_size - markerSize;
LOG_DEBUG("found a stale document after copying: %lu", d->_did); LOG_DEBUG("found a stale document after copying: %lu", d->_did);
TRI_WriteUnlockReadWriteLock(&sim->_lock); TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
return true; return true;
} }
@ -262,14 +269,11 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
dfi->_numberAlive += 1; dfi->_numberAlive += 1;
dfi->_sizeAlive += marker->_size - markerSize; dfi->_sizeAlive += marker->_size - markerSize;
TRI_WriteUnlockReadWriteLock(&sim->_lock); TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
} }
// deletion // deletion
else if (marker->_type == TRI_DOC_MARKER_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 // TODO: remove TRI_doc_deletion_marker_t from file
// write to compactor files // write to compactor files
@ -281,13 +285,12 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
} }
// update datafile info // update datafile info
TRI_WriteLockReadWriteLock(&sim->_lock); TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid); dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid);
dfi->_numberDeletion += 1; dfi->_numberDeletion += 1;
TRI_WriteUnlockReadWriteLock(&sim->_lock); TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
} }
return true; return true;
@ -318,7 +321,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
size_t i; size_t i;
// locate the datafile // locate the datafile
TRI_ReadLockReadWriteLock(&sim->_lock); TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
n = sim->base.base._datafiles._length; 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) { if (i == n) {
return; return;
@ -350,7 +353,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
WaitCompactSync(sim, df); WaitCompactSync(sim, df);
// remove the datafile from the list of datafiles // 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; 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) { if (i == n) {
LOG_WARNING("failed to locate the datafile '%lu'", (unsigned long) df->_fid); 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)); TRI_InitVector(&vector, sizeof(TRI_doc_datafile_info_t));
// copy datafile information // copy datafile information
TRI_ReadLockReadWriteLock(&sim->_lock); TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
n = sim->base.base._datafiles._length; n = sim->base.base._datafiles._length;
@ -400,7 +403,7 @@ static void CompactifySimCollection (TRI_sim_collection_t* sim) {
TRI_PushBackVector(&vector, dfi); TRI_PushBackVector(&vector, dfi);
} }
TRI_ReadUnlockReadWriteLock(&sim->_lock); TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
// handle datafiles with dead objects // handle datafiles with dead objects
for (i = 0; i < vector._length; ++i) { for (i = 0; i < vector._length; ++i) {
@ -532,9 +535,11 @@ void TRI_CompactorVocBase (void* data) {
TRI_col_type_e type; TRI_col_type_e type;
// copy all collections // copy all collections
TRI_ReadLockReadWriteLock(&vocbase->_lock); TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections); TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
n = collections._length; n = collections._length;
@ -544,14 +549,15 @@ void TRI_CompactorVocBase (void* data) {
collection = collections._buffer[i]; 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) { doc = collection->_collection;
TRI_ReadUnlockReadWriteLock(&collection->_lock);
if (doc == NULL) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
continue; continue;
} }
doc = collection->_collection;
type = doc->base._type; type = doc->base._type;
// for simple document collection, compactify datafiles // 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 // now release the lock and maybe unload the collection or some datafiles
if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) { 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 TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
bool ok; int res;
if (TRI_ExistsFile(filename)) { if (TRI_ExistsFile(filename)) {
LOG_ERROR("cannot overwrite datafile '%s'", filename); LOG_ERROR("cannot overwrite datafile '%s'", filename);
@ -820,9 +820,9 @@ bool TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
return false; 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->_state = TRI_DF_STATE_RENAME_ERROR;
datafile->_lastError = TRI_set_errno(TRI_ERROR_SYS_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. /// 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_voc_size_t size,
TRI_df_marker_t** result) { TRI_df_marker_t** result) {
TRI_datafile_t* datafile; TRI_datafile_t* datafile;
@ -114,34 +114,34 @@ static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
size_t i; size_t i;
size_t n; size_t n;
TRI_LockCondition(&collection->_journalsCondition); TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
while (true) { while (true) {
n = collection->base.base._journals._length; n = sim->base.base._journals._length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
// select datafile // select datafile
datafile = collection->base.base._journals._buffer[i]; datafile = sim->base.base._journals._buffer[i];
// try to reserve space // try to reserve space
res = TRI_ReserveElementDatafile(datafile, size, result); res = TRI_ReserveElementDatafile(datafile, size, result);
// in case of full datafile, try next // in case of full datafile, try next
if (res == TRI_ERROR_NO_ERROR) { if (res == TRI_ERROR_NO_ERROR) {
TRI_UnlockCondition(&collection->_journalsCondition); TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return datafile; return datafile;
} }
else if (res != TRI_ERROR_AVOCADO_DATAFILE_FULL) { else if (res != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
TRI_UnlockCondition(&collection->_journalsCondition); TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return NULL; 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. /// 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, TRI_datafile_t* journal,
char const* position) { char const* position) {
TRI_collection_t* base; 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) { if (! base->_waitForSync) {
return; return;
} }
TRI_LockCondition(&collection->_journalsCondition); TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
// wait until the sync condition is fullfilled // wait until the sync condition is fullfilled
while (true) { while (true) {
@ -186,17 +188,17 @@ static void WaitSync (TRI_sim_collection_t* collection,
} }
// we have to wait a bit longer // 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 /// @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_datafile_t* journal,
TRI_df_marker_t* marker, TRI_df_marker_t* marker,
TRI_voc_size_t markerSize, TRI_voc_size_t markerSize,
@ -215,10 +217,12 @@ static int WriteElement (TRI_sim_collection_t* collection,
return res; return res;
} }
TRI_LockCondition(&collection->_journalsCondition); TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
journal->_written = ((char*) result) + marker->_size; journal->_written = ((char*) result) + marker->_size;
journal->_nWritten++; journal->_nWritten++;
TRI_UnlockCondition(&collection->_journalsCondition);
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -1145,11 +1149,11 @@ static int DeleteShapedJson (TRI_doc_collection_t* document,
/// @brief read locks a collection /// @brief read locks a collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static int BeginRead (TRI_doc_collection_t* document) { static int BeginRead (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) doc;
TRI_ReadLockReadWriteLock(&collection->_lock); TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -1158,11 +1162,11 @@ static int BeginRead (TRI_doc_collection_t* document) {
/// @brief read unlocks a collection /// @brief read unlocks a collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static int EndRead (TRI_doc_collection_t* document) { static int EndRead (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) doc;
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -1171,11 +1175,11 @@ static int EndRead (TRI_doc_collection_t* document) {
/// @brief write locks a collection /// @brief write locks a collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static int BeginWrite (TRI_doc_collection_t* document) { static int BeginWrite (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) doc;
TRI_WriteLockReadWriteLock(&collection->_lock); TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR; 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) { static int EndWrite (TRI_doc_collection_t* document) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) document;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -1197,15 +1201,15 @@ static int EndWrite (TRI_doc_collection_t* document) {
/// @brief size of a document collection /// @brief size of a document collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* document) { static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* doc) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
TRI_voc_size_t result; TRI_voc_size_t result;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) doc;
TRI_ReadLockReadWriteLock(&collection->_lock); TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
result = collection->_primaryIndex._nrUsed; result = sim->_primaryIndex._nrUsed;
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return result; return result;
} }
@ -2348,42 +2352,39 @@ static bool FillIndex (TRI_sim_collection_t* collection,
/// @brief returns a description of all indexes /// @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; TRI_vector_pointer_t* vector;
size_t n; size_t n;
size_t i; size_t i;
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t)); vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
if (!vector) {
return NULL;
}
TRI_InitVectorPointer(vector); 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) { for (i = 0; i < n; ++i) {
TRI_index_t* idx; TRI_index_t* idx;
TRI_json_t* json; 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) { if (json != NULL) {
TRI_PushBackVectorPointer(vector, json); TRI_PushBackVectorPointer(vector, json);
} }
} }
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// ............................................................................. // .............................................................................
// without read-lock // outside read-lock
// ............................................................................. // .............................................................................
return vector; return vector;
@ -2393,31 +2394,31 @@ TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* collection
/// @brief returns a description of anindex /// @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; TRI_index_t* idx = NULL;
size_t n; size_t n;
size_t i; 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) { for (i = 0; i < n; ++i) {
idx = collection->_indexes._buffer[i]; idx = sim->_indexes._buffer[i];
if (idx->_iid == iid) { if (idx->_iid == iid) {
break; break;
} }
} }
TRI_ReadUnlockReadWriteLock(&collection->_lock); TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// ............................................................................. // .............................................................................
// without read-lock // outside read-lock
// ............................................................................. // .............................................................................
return i < n ? idx : NULL; 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 /// @brief drops an index
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t iid) { bool TRI_DropIndexSimCollection (TRI_sim_collection_t* sim, TRI_idx_iid_t iid) {
TRI_vector_pointer_t* vector;
TRI_index_t* found; TRI_index_t* found;
size_t n; size_t n;
size_t i; size_t i;
@ -2437,42 +2437,35 @@ bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t
return true; return true;
} }
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
if (!vector) {
return false;
}
found = NULL; 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) { for (i = 0; i < n; ++i) {
TRI_index_t* idx; TRI_index_t* idx;
idx = collection->_indexes._buffer[i]; idx = sim->_indexes._buffer[i];
if (idx->_iid == iid) { if (idx->_iid == iid) {
found = TRI_RemoveVectorPointer(&collection->_indexes, i); found = TRI_RemoveVectorPointer(&sim->_indexes, i);
break; break;
} }
} }
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
// ............................................................................. // .............................................................................
// without write-lock // outside write-lock
// ............................................................................. // .............................................................................
if (found != NULL) { if (found != NULL) {
return TRI_RemoveIndexFile(&collection->base, found); return TRI_RemoveIndexFile(&sim->base, found);
} }
else { else {
return false; return false;
@ -2560,10 +2553,10 @@ static TRI_json_t* JsonPrimary (TRI_index_t* idx, TRI_doc_collection_t* collecti
json = TRI_CreateArrayJson(); json = TRI_CreateArrayJson();
TRI_Insert2ArrayJson(json, "iid", TRI_CreateNumberJson(0)); TRI_Insert3ArrayJson(json, "iid", TRI_CreateNumberJson(0));
TRI_Insert2ArrayJson(json, "type", TRI_CreateStringCopyJson("primary")); TRI_Insert3ArrayJson(json, "type", TRI_CreateStringCopyJson("primary"));
TRI_Insert2ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1)); TRI_Insert3ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1));
TRI_Insert2ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id")); TRI_Insert3ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id"));
return json; 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 /// @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* location,
char const* latitude, char const* latitude,
char const* longitude, char const* longitude,
@ -2657,7 +2650,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
loc = 0; loc = 0;
idx = NULL; idx = NULL;
shaper = collection->base._shaper; shaper = sim->base._shaper;
if (location != NULL) { if (location != NULL) {
loc = shaper->findAttributePathByName(shaper, location); 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 // check, if we know the index
if (location != NULL) { if (location != NULL) {
idx = TRI_LookupGeoIndexSimCollection(collection, loc, geoJson); idx = TRI_LookupGeoIndexSimCollection(sim, loc, geoJson);
} }
else if (longitude != NULL && latitude != NULL) { else if (longitude != NULL && latitude != NULL) {
idx = TRI_LookupGeoIndex2SimCollection(collection, lat, lon); idx = TRI_LookupGeoIndex2SimCollection(sim, lat, lon);
} }
else { else {
TRI_set_errno(TRI_ERROR_INTERNAL); TRI_set_errno(TRI_ERROR_INTERNAL);
@ -2694,14 +2687,14 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
// create a new index // create a new index
if (location != NULL) { 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", LOG_TRACE("created geo-index for location '%s': %d",
location, location,
(unsigned long) loc); (unsigned long) loc);
} }
else if (longitude != NULL && latitude != NULL) { 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", LOG_TRACE("created geo-index for location '%s': %d, %d",
location, location,
@ -2714,7 +2707,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
} }
// initialises the index with all existing documents // initialises the index with all existing documents
ok = FillIndex(collection, idx); ok = FillIndex(sim, idx);
if (! ok) { if (! ok) {
TRI_FreeGeoIndex(idx); TRI_FreeGeoIndex(idx);
@ -2722,7 +2715,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
} }
// and store index // and store index
TRI_PushBackVectorPointer(&collection->_indexes, idx); TRI_PushBackVectorPointer(&sim->_indexes, idx);
return idx; return idx;
} }
@ -2850,7 +2843,6 @@ static TRI_index_t* CreateSkiplistIndexSimCollection (TRI_sim_collection_t* coll
TRI_PushBackVectorPointer(&fields, path); TRI_PushBackVectorPointer(&fields, path);
} }
// ........................................................................... // ...........................................................................
// Attempt to find an existing index which matches the attributes above. // 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 // 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; return NULL;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief finds a hash index (unique or non-unique) /// @brief finds a hash index (unique or non-unique)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -3004,7 +2995,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx; TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
bool found = true; bool found = true;
// ......................................................................... // .........................................................................
// check that the type of the index is in fact a hash index // check that the type of the index is in fact a hash index
// ......................................................................... // .........................................................................
@ -3013,7 +3003,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
continue; continue;
} }
// ......................................................................... // .........................................................................
// check that the number of paths (fields) in the hash index matches that // check that the number of paths (fields) in the hash index matches that
// of the number of attributes // of the number of attributes
@ -3023,7 +3012,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
continue; continue;
} }
// ......................................................................... // .........................................................................
// Go through all the attributes and see if they match // 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) { 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 field = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths,k)));
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k))); TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
if (field != shape) { if (field != shape) {
found = false; found = false;
break; 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; TRI_skiplist_index_t* skiplistIndex = (TRI_skiplist_index_t*) idx;
bool found = true; bool found = true;
// ......................................................................... // .........................................................................
// check that the type of the index is in fact a skiplist index // check that the type of the index is in fact a skiplist index
// ......................................................................... // .........................................................................
@ -3082,7 +3070,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
continue; continue;
} }
// ......................................................................... // .........................................................................
// check that the number of paths (fields) in the index matches that // check that the number of paths (fields) in the index matches that
// of the number of attributes // of the number of attributes
@ -3092,7 +3079,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
continue; continue;
} }
// ......................................................................... // .........................................................................
// Go through all the attributes and see if they match // 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) { 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 field = *((TRI_shape_pid_t*)(TRI_AtVector(&skiplistIndex->_paths,k)));
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k))); TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
if (field != shape) { if (field != shape) {
found = false; found = false;
break; break;
@ -3120,32 +3107,32 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
/// @brief ensures that a geo index exists /// @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, char const* location,
bool geoJson) { bool geoJson) {
TRI_index_t* idx; TRI_index_t* idx;
bool ok; 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) { if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0; 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; 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 /// @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* latitude,
char const* longitude) { char const* longitude) {
TRI_index_t* idx; TRI_index_t* idx;
bool ok; 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) { if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0; 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; return ok ? idx->_iid : 0;
} }
@ -3189,42 +3176,36 @@ TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection
/// @brief ensures that a hash index exists /// @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, const TRI_vector_t* attributes,
bool unique) { bool unique) {
TRI_index_t* idx; TRI_index_t* idx;
bool ok; 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) // Given the list of attributes (as strings)
// ............................................................................. // .............................................................................
idx = CreateHashIndexSimCollection(collection, attributes, 0, unique); idx = CreateHashIndexSimCollection(sim, attributes, 0, unique);
if (idx == NULL) { if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0; 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; 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 /// @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, const TRI_vector_t* attributes,
bool unique) { bool unique) {
TRI_index_t* idx; TRI_index_t* idx;
bool ok; 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) // Given the list of attributes (as strings)
// ............................................................................. // .............................................................................
idx = CreateSkiplistIndexSimCollection(collection, attributes, 0, unique); idx = CreateSkiplistIndexSimCollection(sim, attributes, 0, unique);
if (idx == NULL) { if (idx == NULL) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
return 0; 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; return ok ? idx->_iid : 0;
} }

View File

@ -39,6 +39,103 @@
extern "C" { extern "C" {
#endif #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 // --SECTION-- public types
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

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

View File

@ -164,17 +164,17 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection = data; collection = data;
TRI_WriteLockReadWriteLock(&collection->_lock); TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_UNLOADING) { if (collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false; return false;
} }
if (collection->_collection == NULL) { if (collection->_collection == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED; collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true; return true;
} }
@ -185,7 +185,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_LOADED; collection->_status = TRI_VOC_COL_STATUS_LOADED;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return false; return false;
} }
@ -200,7 +200,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED; collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return true; return true;
} }
@ -209,7 +209,136 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
collection->_status = TRI_VOC_COL_STATUS_UNLOADED; collection->_status = TRI_VOC_COL_STATUS_UNLOADED;
collection->_collection = NULL; 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; return true;
} }
@ -317,11 +446,15 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
if (TRI_IsDirectory(file)) { if (TRI_IsDirectory(file)) {
TRI_col_info_t info; 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) { if (res != TRI_ERROR_NO_ERROR) {
LOG_DEBUG("ignoring directory '%s' without valid parameter file '%s'", file, TRI_COL_PARAMETER_FILE); 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 { else {
type = info._type; type = info._type;
@ -351,6 +484,8 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
TRI_FreeString(file); TRI_FreeString(file);
} }
regfree(&re);
TRI_DestroyVectorString(&files); TRI_DestroyVectorString(&files);
return TRI_ERROR_NO_ERROR; 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; TRI_vocbase_col_t* collection;
char wrong; char wrong;
TRI_WriteLockReadWriteLock(&vocbase->_lock); TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// ............................................................................. // .............................................................................
// check that we have an existing name // 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); found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found.v != NULL) { if (found.v != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c; return found.c;
} }
@ -385,7 +520,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
wrong = TRI_IsAllowedCollectionName(name); wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) { if (wrong != 0) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("found illegal character in name: %c", wrong); 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); collection = AddCollection(vocbase, TRI_COL_TYPE_SIMPLE_DOCUMENT, name, TRI_NewTickVocBase(), NULL);
if (collection == NULL) { if (collection == NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL; return NULL;
} }
collection->_status = TRI_VOC_COL_STATUS_NEW_BORN; collection->_status = TRI_VOC_COL_STATUS_NEW_BORN;
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return collection; 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) { static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
TRI_col_type_e type; TRI_col_type_e type;
TRI_WriteLockReadWriteLock(&collection->_lock); TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// cannot manifest a corrupted collection // cannot manifest a corrupted collection
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
// cannot manifest a deleted collection // cannot manifest a deleted collection
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
} }
// loaded, unloaded, or unloading are manifested // loaded, unloaded, or unloading are manifested
if (collection->_status == TRI_VOC_COL_STATUS_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; return TRI_ERROR_NO_ERROR;
} }
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) { if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) { if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
if (collection->_status != TRI_VOC_COL_STATUS_NEW_BORN) { 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); 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) { if (sim == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED; collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_errno(); return TRI_errno();
} }
collection->_status = TRI_VOC_COL_STATUS_LOADED; collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_collection = &sim->base; 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; return TRI_ERROR_NO_ERROR;
} }
else { 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); 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); 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 // 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) { 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) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
} }
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
// release the read lock and acquire a write lock, we have to do some work // 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 // 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 // someone else loaded the collection, release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) { if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, 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 // release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) { if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
collection->_status = TRI_VOC_COL_STATUS_LOADED; collection->_status = TRI_VOC_COL_STATUS_LOADED;
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, collection); return LoadCollectionVocBase(vocbase, collection);
} }
// deleted, give up // deleted, give up
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
} }
// corrupted, give up // corrupted, give up
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
// new born, manifest collection, release the WRITE lock and try again // new born, manifest collection, release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) { if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
res = ManifestCollectionVocBase(vocbase, collection); res = ManifestCollectionVocBase(vocbase, collection);
@ -583,28 +719,29 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
if (sim == NULL) { if (sim == NULL) {
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED; 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); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
collection->_collection = &sim->base; collection->_collection = &sim->base;
collection->_status = TRI_VOC_COL_STATUS_LOADED; collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_path = TRI_DuplicateString(sim->base.base._directory);
// release the WRITE lock and try again // release the WRITE lock and try again
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return LoadCollectionVocBase(vocbase, collection); return LoadCollectionVocBase(vocbase, collection);
} }
else { else {
LOG_ERROR("unknown collection type %d for '%s'", (int) type, collection->_name); 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); return TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
} }
} }
LOG_ERROR("unknown collection status %d for '%s'", (int) collection->_status, collection->_name); 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); 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_InitVectorPointer(&result);
TRI_ReadLockReadWriteLock(&vocbase->_lock); TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
for (i = 0; i < vocbase->_collectionsById._nrAlloc; ++i) { for (i = 0; i < vocbase->_collectionsById._nrAlloc; ++i) {
found = vocbase->_collectionsById._table[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; 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) { TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name) {
union { void const* v; TRI_vocbase_col_t* c; } found; 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); found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c; 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) { 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; 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); found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found.c; 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) { 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; 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); found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_ReadUnlockReadWriteLock(&vocbase->_lock); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
if (found.v != NULL) { if (found.v != NULL) {
return found.c; return found.c;
@ -977,7 +1114,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
char wrong; char wrong;
void const* found; void const* found;
TRI_WriteLockReadWriteLock(&vocbase->_lock); TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// ............................................................................. // .............................................................................
// check that we have a new name // 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); found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found != NULL) { if (found != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("collection named '%s' already exists", name); 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); wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) { if (wrong != 0) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("found illegal character in name: %c", wrong); 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); sim = TRI_CreateSimCollection(vocbase->_path, parameter, 0);
if (sim == NULL) { if (sim == NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL; return NULL;
} }
doc = &sim->base; doc = &sim->base;
} }
else { else {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
LOG_ERROR("unknown collection type: %d", parameter->_type); 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_FreeSimCollection((TRI_sim_collection_t*) doc);
} }
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL; return NULL;
} }
collection->_status = TRI_VOC_COL_STATUS_LOADED; collection->_status = TRI_VOC_COL_STATUS_LOADED;
collection->_collection = doc; collection->_collection = doc;
collection->_path = TRI_DuplicateString(doc->base._directory);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return collection; 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) { 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 // cannot unload a corrupted collection
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) { 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); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
// a unloaded collection is unloaded // a unloaded collection is unloaded
if (collection->_status == TRI_VOC_COL_STATUS_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; return TRI_ERROR_NO_ERROR;
} }
// a unloading collection is treated as unloaded // a unloading collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) { if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
// a new born collection is treated as unloaded // a new born collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) { 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; return TRI_ERROR_NO_ERROR;
} }
// a deleted collection is treated as unloaded // a deleted collection is treated as unloaded
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) { if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
// must be loaded // must be loaded
if (collection->_status != TRI_VOC_COL_STATUS_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); return TRI_set_errno(TRI_ERROR_INTERNAL);
} }
@ -1112,24 +1250,130 @@ int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll
collection); collection);
// release locks // release locks
TRI_WriteUnlockReadWriteLock(&collection->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; 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 /// @brief renames a (document) collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col, char const* newName) { int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection, char const* newName) {
TRI_col_info_t info;
union { TRI_vocbase_col_t* v; TRI_vocbase_col_t const* c; } cnv; union { TRI_vocbase_col_t* v; TRI_vocbase_col_t const* c; } cnv;
TRI_col_info_t info;
void* found; void* found;
char wrong; char wrong;
char const* oldName; char const* oldName;
int res; int res;
// old name should be different // old name should be different
oldName = col->_name; oldName = collection->_name;
if (TRI_EqualString(oldName, newName)) { if (TRI_EqualString(oldName, newName)) {
return TRI_ERROR_NO_ERROR; 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 // 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 // the must be done after the collection lock
TRI_WriteLockReadWriteLock(&vocbase->_lock); TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// cannot rename a corrupted collection // cannot rename a corrupted collection
if (col->_status == TRI_VOC_COL_STATUS_CORRUPTED) { if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION); return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
} }
// cannot rename a deleted collection // cannot rename a deleted collection
if (col->_status == TRI_VOC_COL_STATUS_DELETED) { if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND); return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
} }
// check if the new name is unused // check if the new name is unused
cnv.c = col; cnv.c = collection;
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false); found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false);
if (found != NULL) { if (found != NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_NAME); 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 // new born collection, no datafile/parameter file exists
// ............................................................................. // .............................................................................
if (col->_status == TRI_VOC_COL_STATUS_NEW_BORN) { if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
TRI_CopyString(col->_name, newName, sizeof(col->_name)); TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
} }
// ............................................................................. // .............................................................................
// collection is unloaded // collection is unloaded
// ............................................................................. // .............................................................................
else if (col->_status == TRI_VOC_COL_STATUS_UNLOADED) { else if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
res = TRI_LoadParameterInfo(col->_path, &info); res = TRI_LoadParameterInfoCollection(collection->_path, &info);
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res); return TRI_set_errno(res);
} }
TRI_CopyString(info._name, newName, sizeof(info._name)); 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) { if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res); return TRI_set_errno(res);
} }
TRI_CopyString(col->_name, newName, sizeof(col->_name)); TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
} }
// ............................................................................. // .............................................................................
// collection is loaded // collection is loaded
// ............................................................................. // .............................................................................
else if (col->_status != TRI_VOC_COL_STATUS_LOADED || col->_status != TRI_VOC_COL_STATUS_UNLOADING) { else if (collection->_status != TRI_VOC_COL_STATUS_LOADED || collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
res = TRI_RenameCollection(&col->_collection->base, newName); res = TRI_RenameCollection(&collection->_collection->base, newName);
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(res); 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 { else {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_set_errno(TRI_ERROR_INTERNAL); 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_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_WriteUnlockReadWriteLock(&col->_lock); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
return TRI_ERROR_NO_ERROR; 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) { 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 // check that we have an existing name
// ............................................................................. // .............................................................................
TRI_WriteLockReadWriteLock(&vocbase->_lock); TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
collection = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name); collection = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
if (collection == NULL) { if (collection == NULL) {
LOG_ERROR("unknown collection '%s'", name); LOG_ERROR("unknown collection '%s'", name);

View File

@ -40,10 +40,83 @@
extern "C" { extern "C" {
#endif #endif
// -----------------------------------------------------------------------------
// --SECTION-- forward declarations
// -----------------------------------------------------------------------------
struct TRI_doc_collection_s; struct TRI_doc_collection_s;
struct TRI_col_parameter_s; struct TRI_col_parameter_s;
struct TRI_shadow_store_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 // --SECTION-- public constants
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -311,7 +384,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t*);
/// @brief returns all known collections /// @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 /// @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 /// @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 /// @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 /// @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. /// 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 /// @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. /// 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 /// @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 /// @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*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}