mirror of https://gitee.com/bigwinds/arangodb
added drop collection
This commit is contained in:
parent
f69a009a38
commit
e03abf4f06
|
@ -418,18 +418,17 @@ TRI_vector_string_t TRI_FilesDirectory (char const* path) {
|
|||
/// @brief renames a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_RenameFile (char const* old, char const* filename) {
|
||||
int TRI_RenameFile (char const* old, char const* filename) {
|
||||
int res;
|
||||
|
||||
res = rename(old, filename);
|
||||
|
||||
if (res != 0) {
|
||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
LOG_TRACE("cannot rename file from '%s' to '%s': %s", old, filename, TRI_LAST_ERROR_STR);
|
||||
return false;
|
||||
return TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
}
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -103,7 +103,7 @@ TRI_vector_string_t TRI_FilesDirectory (char const* path);
|
|||
/// @brief renames a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_RenameFile (char const* old, char const* filename);
|
||||
int TRI_RenameFile (char const* old, char const* filename);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unlinks a file
|
||||
|
|
|
@ -652,14 +652,14 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ok = TRI_RenameFile(tmp, filename);
|
||||
res = TRI_RenameFile(tmp, filename);
|
||||
|
||||
if (! ok) {
|
||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
|
||||
TRI_UnlinkFile(tmp);
|
||||
TRI_FreeString(tmp);
|
||||
return false;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TRI_FreeString(tmp);
|
||||
|
|
|
@ -3152,6 +3152,31 @@ static v8::Handle<v8::Value> JS_DeleteVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::True());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_DropVocbaseCol (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
TRI_vocbase_col_t* collection = UnwrapClass<TRI_vocbase_col_t>(argv.Holder(), WRP_VOCBASE_COL_TYPE);
|
||||
|
||||
if (collection == 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
|
||||
}
|
||||
|
||||
int res = TRI_DropCollectionVocBase(collection->_vocbase, collection);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
string err = "cannot drop collection: ";
|
||||
err += TRI_last_error();
|
||||
|
||||
return scope.Close(v8::ThrowException(v8::String::New(err.c_str())));
|
||||
}
|
||||
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops an index
|
||||
///
|
||||
|
@ -4009,16 +4034,16 @@ static v8::Handle<v8::Value> JS_FiguresVocbaseCol (v8::Arguments const& argv) {
|
|||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
TRI_vocbase_col_status_e status = collection->_status;
|
||||
|
||||
if (status != TRI_VOC_COL_STATUS_LOADED) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
if (collection->_collection == 0) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
|
||||
}
|
||||
|
||||
|
@ -4037,7 +4062,7 @@ static v8::Handle<v8::Value> JS_FiguresVocbaseCol (v8::Arguments const& argv) {
|
|||
|
||||
TRI_Free(info);
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
|
@ -4169,31 +4194,28 @@ static v8::Handle<v8::Value> JS_ParameterVocbaseCol (v8::Arguments const& argv)
|
|||
|
||||
TRI_sim_collection_t* sim = (TRI_sim_collection_t*) doc;
|
||||
|
||||
// check if we want to change same parameters
|
||||
// check if we want to change some parameters
|
||||
if (0 < argv.Length()) {
|
||||
v8::Handle<v8::Value> par = argv[0];
|
||||
|
||||
if (par->IsObject()) {
|
||||
v8::Handle<v8::Object> po = par->ToObject();
|
||||
|
||||
TRI_LockCondition(&sim->_journalsCondition);
|
||||
// holding a lock on the vocbase collection: if we ever want to
|
||||
// change the maximal size a real lock is required.
|
||||
bool waitForSync = sim->base.base._waitForSync;
|
||||
TRI_UnlockCondition(&sim->_journalsCondition);
|
||||
|
||||
// extract sync after objects
|
||||
if (po->Has(v8g->WaitForSyncKey)) {
|
||||
waitForSync = TRI_ObjectToBoolean(po->Get(v8g->WaitForSyncKey));
|
||||
}
|
||||
|
||||
// try to write new parameter to file
|
||||
TRI_LockCondition(&sim->_journalsCondition);
|
||||
|
||||
sim->base.base._waitForSync = waitForSync;
|
||||
bool ok = TRI_UpdateParameterInfoCollection(&sim->base.base);
|
||||
|
||||
TRI_UnlockCondition(&sim->_journalsCondition);
|
||||
// try to write new parameter to file
|
||||
int res = TRI_UpdateParameterInfoCollection(&sim->base.base);
|
||||
|
||||
if (! ok) {
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(v8::String::New(TRI_last_error())));
|
||||
}
|
||||
|
@ -4204,13 +4226,9 @@ static v8::Handle<v8::Value> JS_ParameterVocbaseCol (v8::Arguments const& argv)
|
|||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
|
||||
if (doc->base._type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {
|
||||
TRI_LockCondition(&sim->_journalsCondition);
|
||||
|
||||
TRI_voc_size_t maximalSize = sim->base.base._maximalSize;
|
||||
bool waitForSync = sim->base.base._waitForSync;
|
||||
|
||||
TRI_UnlockCondition(&sim->_journalsCondition);
|
||||
|
||||
result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False());
|
||||
result->Set(v8g->JournalSizeKey, v8::Number::New(maximalSize));
|
||||
}
|
||||
|
@ -4357,9 +4375,9 @@ static v8::Handle<v8::Value> JS_StatusVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
|
||||
}
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
TRI_vocbase_col_status_e status = collection->_status;
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return scope.Close(v8::Number::New((int) status));
|
||||
}
|
||||
|
@ -5322,6 +5340,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
v8::Handle<v8::String> DeleteFuncName = v8::Persistent<v8::String>::New(v8::String::New("delete"));
|
||||
v8::Handle<v8::String> DisposeFuncName = v8::Persistent<v8::String>::New(v8::String::New("dispose"));
|
||||
v8::Handle<v8::String> DocumentFuncName = v8::Persistent<v8::String>::New(v8::String::New("document"));
|
||||
v8::Handle<v8::String> DropFuncName = v8::Persistent<v8::String>::New(v8::String::New("drop"));
|
||||
v8::Handle<v8::String> DropIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("dropIndex"));
|
||||
v8::Handle<v8::String> EdgesFuncName = v8::Persistent<v8::String>::New(v8::String::New("edges"));
|
||||
v8::Handle<v8::String> EnsureGeoIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("ensureGeoIndex"));
|
||||
|
@ -5465,6 +5484,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
rt->Set(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
|
||||
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
|
||||
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery));
|
||||
rt->Set(DropFuncName, v8::FunctionTemplate::New(JS_DropVocbaseCol));
|
||||
rt->Set(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
|
||||
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
|
||||
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol));
|
||||
|
@ -5503,6 +5523,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
rt->Set(CountFuncName, v8::FunctionTemplate::New(JS_CountVocbaseCol));
|
||||
rt->Set(DeleteFuncName, v8::FunctionTemplate::New(JS_DeleteVocbaseCol));
|
||||
rt->Set(DocumentFuncName, v8::FunctionTemplate::New(JS_DocumentQuery));
|
||||
rt->Set(DropFuncName, v8::FunctionTemplate::New(JS_DropVocbaseCol));
|
||||
rt->Set(DropIndexFuncName, v8::FunctionTemplate::New(JS_DropIndexVocbaseCol));
|
||||
rt->Set(EnsureGeoIndexFuncName, v8::FunctionTemplate::New(JS_EnsureGeoIndexVocbaseCol));
|
||||
rt->Set(EnsureMultiHashIndexFuncName, v8::FunctionTemplate::New(JS_EnsureMultiHashIndexVocbaseCol));
|
||||
|
|
|
@ -415,8 +415,8 @@ TRI_collection_t* TRI_CreateCollection (TRI_collection_t* collection,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// save the parameter block
|
||||
res = TRI_SaveParameterInfo(filename, parameter);
|
||||
// save the parameter block (within create, no need to lock)
|
||||
res = TRI_SaveParameterInfoCollection(filename, parameter);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_FreeString(filename);
|
||||
|
@ -477,10 +477,12 @@ void TRI_FreeCollection (TRI_collection_t* collection) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a parameter info block from file
|
||||
///
|
||||
/// You must hold the @ref TRI_READ_LOCK_STATUS_VOCBASE_COL when calling this
|
||||
/// function.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_LoadParameterInfo (char const* path,
|
||||
TRI_col_info_t* parameter) {
|
||||
int TRI_LoadParameterInfoCollection (char const* path, TRI_col_info_t* parameter) {
|
||||
TRI_json_t* json;
|
||||
char* filename;
|
||||
char* error;
|
||||
|
@ -560,10 +562,12 @@ int TRI_LoadParameterInfo (char const* path,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves a parameter info block to file
|
||||
///
|
||||
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
|
||||
/// function.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_SaveParameterInfo (char const* path,
|
||||
TRI_col_info_t* info) {
|
||||
int TRI_SaveParameterInfoCollection (char const* path, TRI_col_info_t* info) {
|
||||
TRI_json_t* json;
|
||||
char* filename;
|
||||
bool ok;
|
||||
|
@ -598,9 +602,12 @@ int TRI_SaveParameterInfo (char const* path,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates the parameter info block
|
||||
///
|
||||
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
|
||||
/// function.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
|
||||
int TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
|
||||
TRI_col_info_t parameter;
|
||||
|
||||
parameter._version = collection->_version;
|
||||
|
@ -612,11 +619,14 @@ bool TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) {
|
|||
parameter._deleted = collection->_deleted;
|
||||
parameter._size = sizeof(TRI_col_info_t);
|
||||
|
||||
return TRI_SaveParameterInfo(collection->_directory, ¶meter) == TRI_ERROR_NO_ERROR;
|
||||
return TRI_SaveParameterInfoCollection(collection->_directory, ¶meter);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a collection
|
||||
///
|
||||
/// You must hold the @ref TRI_WRITE_LOCK_STATUS_VOCBASE_COL when calling this
|
||||
/// function.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RenameCollection (TRI_collection_t* collection, char const* name) {
|
||||
|
@ -632,7 +642,7 @@ int TRI_RenameCollection (TRI_collection_t* collection, char const* name) {
|
|||
parameter._deleted = collection->_deleted;
|
||||
parameter._size = sizeof(TRI_col_info_t);
|
||||
|
||||
res = TRI_SaveParameterInfo(collection->_directory, ¶meter);
|
||||
res = TRI_SaveParameterInfoCollection(collection->_directory, ¶meter);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
TRI_CopyString(collection->_name, name, sizeof(collection->_name));
|
||||
|
@ -770,8 +780,7 @@ void TRI_IterateIndexCollection (TRI_collection_t* collection,
|
|||
/// @brief opens an existing collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection,
|
||||
char const* path) {
|
||||
TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection, char const* path) {
|
||||
TRI_col_info_t info;
|
||||
bool freeCol;
|
||||
bool ok;
|
||||
|
@ -787,8 +796,8 @@ TRI_collection_t* TRI_OpenCollection (TRI_collection_t* collection,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// read parameter block
|
||||
res = TRI_LoadParameterInfo(path, &info);
|
||||
// read parameter block, no need to lock as we are opening the collection
|
||||
res = TRI_LoadParameterInfoCollection(path, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot save collection parameter '%s': '%s'", path, TRI_last_error());
|
||||
|
|
|
@ -272,19 +272,19 @@ void TRI_FreeCollection (TRI_collection_t*);
|
|||
/// @brief creates a parameter info block from file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_LoadParameterInfo (char const* filename, TRI_col_info_t*);
|
||||
int TRI_LoadParameterInfoCollection (char const* filename, TRI_col_info_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves a parameter info block to file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_SaveParameterInfo (char const* filename, TRI_col_info_t*);
|
||||
int TRI_SaveParameterInfoCollection (char const* filename, TRI_col_info_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates the parameter info block
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_UpdateParameterInfoCollection (TRI_collection_t*);
|
||||
int TRI_UpdateParameterInfoCollection (TRI_collection_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a collection
|
||||
|
|
|
@ -27,13 +27,12 @@
|
|||
|
||||
#include "compactor.h"
|
||||
|
||||
#include <BasicsC/conversions.h>
|
||||
#include <BasicsC/files.h>
|
||||
#include <BasicsC/logging.h>
|
||||
#include <BasicsC/strings.h>
|
||||
|
||||
#include <VocBase/simple-collection.h>
|
||||
#include <VocBase/shadow-data.h>
|
||||
#include "BasicsC/conversions.h"
|
||||
#include "BasicsC/files.h"
|
||||
#include "BasicsC/logging.h"
|
||||
#include "BasicsC/strings.h"
|
||||
#include "VocBase/simple-collection.h"
|
||||
#include "VocBase/shadow-data.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private constants
|
||||
|
@ -70,7 +69,7 @@ static int const COMPACTOR_INTERVAL = 5 * 1000 * 1000;
|
|||
/// to allow the gc to start when waiting for a journal to appear.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
|
||||
static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* sim,
|
||||
TRI_voc_size_t size,
|
||||
TRI_df_marker_t** result) {
|
||||
TRI_datafile_t* datafile;
|
||||
|
@ -78,34 +77,34 @@ static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
|
|||
size_t i;
|
||||
size_t n;
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
while (true) {
|
||||
n = collection->base.base._compactors._length;
|
||||
n = sim->base.base._compactors._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
|
||||
// select datafile
|
||||
datafile = collection->base.base._compactors._buffer[i];
|
||||
datafile = sim->base.base._compactors._buffer[i];
|
||||
|
||||
// try to reserve space
|
||||
ok = TRI_ReserveElementDatafile(datafile, size, result);
|
||||
|
||||
// in case of full datafile, try next
|
||||
if (ok) {
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
return datafile;
|
||||
}
|
||||
else if (! ok && TRI_errno() != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_WaitCondition(&collection->_journalsCondition);
|
||||
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -194,6 +193,7 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
TRI_doc_mptr_t const* found;
|
||||
TRI_sim_collection_t* sim;
|
||||
TRI_voc_fid_t fid;
|
||||
bool deleted;
|
||||
int res;
|
||||
|
||||
sim = data;
|
||||
|
@ -217,18 +217,18 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
d = (TRI_doc_document_marker_t const*) marker;
|
||||
|
||||
// check if the document is still active
|
||||
TRI_ReadLockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
|
||||
deleted = found == NULL || found->_deletion != 0;
|
||||
|
||||
if (found == NULL || found->_deletion != 0) {
|
||||
TRI_ReadUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
if (deleted) {
|
||||
LOG_TRACE("found a stale document: %lu", d->_did);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&sim->_lock);
|
||||
|
||||
// write to compactor files
|
||||
res = CopyDocument(sim, marker, &result, &fid);
|
||||
|
||||
|
@ -238,17 +238,24 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
}
|
||||
|
||||
// check if the document is still active
|
||||
TRI_WriteLockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
|
||||
deleted = found == NULL || found->_deletion != 0;
|
||||
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// update datafile
|
||||
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid);
|
||||
found = TRI_LookupByKeyAssociativePointer(&sim->_primaryIndex, &d->_did);
|
||||
|
||||
if (found == NULL || found->_deletion != 0) {
|
||||
if (deleted) {
|
||||
dfi->_numberDead += 1;
|
||||
dfi->_sizeDead += marker->_size - markerSize;
|
||||
|
||||
LOG_DEBUG("found a stale document after copying: %lu", d->_did);
|
||||
TRI_WriteUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -262,14 +269,11 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
dfi->_numberAlive += 1;
|
||||
dfi->_sizeAlive += marker->_size - markerSize;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
// deletion
|
||||
else if (marker->_type == TRI_DOC_MARKER_DELETION) {
|
||||
// TRI_doc_deletion_marker_t const* d;
|
||||
// d = (TRI_doc_deletion_marker_t const*) marker;
|
||||
|
||||
// TODO: remove TRI_doc_deletion_marker_t from file
|
||||
|
||||
// write to compactor files
|
||||
|
@ -281,13 +285,12 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
}
|
||||
|
||||
// update datafile info
|
||||
TRI_WriteLockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
dfi = TRI_FindDatafileInfoDocCollection(&sim->base, fid);
|
||||
|
||||
dfi->_numberDeletion += 1;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -318,7 +321,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
|
|||
size_t i;
|
||||
|
||||
// locate the datafile
|
||||
TRI_ReadLockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
n = sim->base.base._datafiles._length;
|
||||
|
||||
|
@ -330,7 +333,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
if (i == n) {
|
||||
return;
|
||||
|
@ -350,7 +353,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
|
|||
WaitCompactSync(sim, df);
|
||||
|
||||
// remove the datafile from the list of datafiles
|
||||
TRI_ReadLockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
n = sim->base.base._datafiles._length;
|
||||
|
||||
|
@ -363,7 +366,7 @@ static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
if (i == n) {
|
||||
LOG_WARNING("failed to locate the datafile '%lu'", (unsigned long) df->_fid);
|
||||
|
@ -386,7 +389,7 @@ static void CompactifySimCollection (TRI_sim_collection_t* sim) {
|
|||
TRI_InitVector(&vector, sizeof(TRI_doc_datafile_info_t));
|
||||
|
||||
// copy datafile information
|
||||
TRI_ReadLockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
n = sim->base.base._datafiles._length;
|
||||
|
||||
|
@ -400,7 +403,7 @@ static void CompactifySimCollection (TRI_sim_collection_t* sim) {
|
|||
TRI_PushBackVector(&vector, dfi);
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&sim->_lock);
|
||||
TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);
|
||||
|
||||
// handle datafiles with dead objects
|
||||
for (i = 0; i < vector._length; ++i) {
|
||||
|
@ -532,9 +535,11 @@ void TRI_CompactorVocBase (void* data) {
|
|||
TRI_col_type_e type;
|
||||
|
||||
// copy all collections
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
n = collections._length;
|
||||
|
||||
|
@ -544,14 +549,15 @@ void TRI_CompactorVocBase (void* data) {
|
|||
|
||||
collection = collections._buffer[i];
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_LOADED && collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
doc = collection->_collection;
|
||||
|
||||
if (doc == NULL) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
continue;
|
||||
}
|
||||
|
||||
doc = collection->_collection;
|
||||
type = doc->base._type;
|
||||
|
||||
// for simple document collection, compactify datafiles
|
||||
|
@ -561,7 +567,7 @@ void TRI_CompactorVocBase (void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// now release the lock and maybe unload the collection or some datafiles
|
||||
if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {
|
||||
|
|
|
@ -811,7 +811,7 @@ bool TRI_CloseDatafile (TRI_datafile_t* datafile) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
|
||||
bool ok;
|
||||
int res;
|
||||
|
||||
if (TRI_ExistsFile(filename)) {
|
||||
LOG_ERROR("cannot overwrite datafile '%s'", filename);
|
||||
|
@ -820,9 +820,9 @@ bool TRI_RenameDatafile (TRI_datafile_t* datafile, char const* filename) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ok = TRI_RenameFile(datafile->_filename, filename);
|
||||
res = TRI_RenameFile(datafile->_filename, filename);
|
||||
|
||||
if (! ok) {
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
datafile->_state = TRI_DF_STATE_RENAME_ERROR;
|
||||
datafile->_lastError = TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ static TRI_json_t* JsonPrimary (TRI_index_t* idx, TRI_doc_collection_t* collecti
|
|||
/// to allow the gc to start when waiting for a journal to appear.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
|
||||
static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* sim,
|
||||
TRI_voc_size_t size,
|
||||
TRI_df_marker_t** result) {
|
||||
TRI_datafile_t* datafile;
|
||||
|
@ -114,34 +114,34 @@ static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
|
|||
size_t i;
|
||||
size_t n;
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
while (true) {
|
||||
n = collection->base.base._journals._length;
|
||||
n = sim->base.base._journals._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
|
||||
// select datafile
|
||||
datafile = collection->base.base._journals._buffer[i];
|
||||
datafile = sim->base.base._journals._buffer[i];
|
||||
|
||||
// try to reserve space
|
||||
res = TRI_ReserveElementDatafile(datafile, size, result);
|
||||
|
||||
// in case of full datafile, try next
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
return datafile;
|
||||
}
|
||||
else if (res != TRI_ERROR_AVOCADO_DATAFILE_FULL) {
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_WaitCondition(&collection->_journalsCondition);
|
||||
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -153,19 +153,21 @@ static TRI_datafile_t* SelectJournal (TRI_sim_collection_t* collection,
|
|||
/// datafile and has been synced.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void WaitSync (TRI_sim_collection_t* collection,
|
||||
static void WaitSync (TRI_sim_collection_t* sim,
|
||||
TRI_datafile_t* journal,
|
||||
char const* position) {
|
||||
TRI_collection_t* base;
|
||||
|
||||
base = &collection->base.base;
|
||||
base = &sim->base.base;
|
||||
|
||||
// no condition at all. Do NOT acquire a lock, in the worst
|
||||
// case we will miss a parameter change.
|
||||
|
||||
// no condition at all
|
||||
if (! base->_waitForSync) {
|
||||
return;
|
||||
}
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
// wait until the sync condition is fullfilled
|
||||
while (true) {
|
||||
|
@ -186,17 +188,17 @@ static void WaitSync (TRI_sim_collection_t* collection,
|
|||
}
|
||||
|
||||
// we have to wait a bit longer
|
||||
TRI_WaitCondition(&collection->_journalsCondition);
|
||||
TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief writes data to the journal and updates the barriers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int WriteElement (TRI_sim_collection_t* collection,
|
||||
static int WriteElement (TRI_sim_collection_t* sim,
|
||||
TRI_datafile_t* journal,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
|
@ -215,10 +217,12 @@ static int WriteElement (TRI_sim_collection_t* collection,
|
|||
return res;
|
||||
}
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
journal->_written = ((char*) result) + marker->_size;
|
||||
journal->_nWritten++;
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1145,11 +1149,11 @@ static int DeleteShapedJson (TRI_doc_collection_t* document,
|
|||
/// @brief read locks a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int BeginRead (TRI_doc_collection_t* document) {
|
||||
TRI_sim_collection_t* collection;
|
||||
static int BeginRead (TRI_doc_collection_t* doc) {
|
||||
TRI_sim_collection_t* sim;
|
||||
|
||||
collection = (TRI_sim_collection_t*) document;
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
sim = (TRI_sim_collection_t*) doc;
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1158,11 +1162,11 @@ static int BeginRead (TRI_doc_collection_t* document) {
|
|||
/// @brief read unlocks a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int EndRead (TRI_doc_collection_t* document) {
|
||||
TRI_sim_collection_t* collection;
|
||||
static int EndRead (TRI_doc_collection_t* doc) {
|
||||
TRI_sim_collection_t* sim;
|
||||
|
||||
collection = (TRI_sim_collection_t*) document;
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
sim = (TRI_sim_collection_t*) doc;
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1171,11 +1175,11 @@ static int EndRead (TRI_doc_collection_t* document) {
|
|||
/// @brief write locks a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int BeginWrite (TRI_doc_collection_t* document) {
|
||||
TRI_sim_collection_t* collection;
|
||||
static int BeginWrite (TRI_doc_collection_t* doc) {
|
||||
TRI_sim_collection_t* sim;
|
||||
|
||||
collection = (TRI_sim_collection_t*) document;
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
sim = (TRI_sim_collection_t*) doc;
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1185,10 +1189,10 @@ static int BeginWrite (TRI_doc_collection_t* document) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int EndWrite (TRI_doc_collection_t* document) {
|
||||
TRI_sim_collection_t* collection;
|
||||
TRI_sim_collection_t* sim;
|
||||
|
||||
collection = (TRI_sim_collection_t*) document;
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
sim = (TRI_sim_collection_t*) document;
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1197,15 +1201,15 @@ static int EndWrite (TRI_doc_collection_t* document) {
|
|||
/// @brief size of a document collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* document) {
|
||||
TRI_sim_collection_t* collection;
|
||||
static TRI_voc_size_t SizeSimCollection (TRI_doc_collection_t* doc) {
|
||||
TRI_sim_collection_t* sim;
|
||||
TRI_voc_size_t result;
|
||||
|
||||
collection = (TRI_sim_collection_t*) document;
|
||||
sim = (TRI_sim_collection_t*) doc;
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
result = collection->_primaryIndex._nrUsed;
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
result = sim->_primaryIndex._nrUsed;
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -2348,42 +2352,39 @@ static bool FillIndex (TRI_sim_collection_t* collection,
|
|||
/// @brief returns a description of all indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* collection) {
|
||||
TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim) {
|
||||
TRI_vector_pointer_t* vector;
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
||||
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
|
||||
if (!vector) {
|
||||
return NULL;
|
||||
}
|
||||
TRI_InitVectorPointer(vector);
|
||||
|
||||
// .............................................................................
|
||||
// within read-lock the collection
|
||||
// inside read-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
n = collection->_indexes._length;
|
||||
n = sim->_indexes._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_index_t* idx;
|
||||
TRI_json_t* json;
|
||||
|
||||
idx = collection->_indexes._buffer[i];
|
||||
idx = sim->_indexes._buffer[i];
|
||||
|
||||
json = idx->json(idx, &collection->base);
|
||||
json = idx->json(idx, &sim->base);
|
||||
|
||||
if (json != NULL) {
|
||||
TRI_PushBackVectorPointer(vector, json);
|
||||
}
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without read-lock
|
||||
// outside read-lock
|
||||
// .............................................................................
|
||||
|
||||
return vector;
|
||||
|
@ -2393,31 +2394,31 @@ TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* collection
|
|||
/// @brief returns a description of anindex
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t iid) {
|
||||
TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* sim, TRI_idx_iid_t iid) {
|
||||
TRI_index_t* idx = NULL;
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
||||
// .............................................................................
|
||||
// within read-lock the collection
|
||||
// inside read-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
n = collection->_indexes._length;
|
||||
n = sim->_indexes._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
idx = collection->_indexes._buffer[i];
|
||||
idx = sim->_indexes._buffer[i];
|
||||
|
||||
if (idx->_iid == iid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without read-lock
|
||||
// outside read-lock
|
||||
// .............................................................................
|
||||
|
||||
return i < n ? idx : NULL;
|
||||
|
@ -2427,8 +2428,7 @@ TRI_index_t* TRI_IndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_i
|
|||
/// @brief drops an index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t iid) {
|
||||
TRI_vector_pointer_t* vector;
|
||||
bool TRI_DropIndexSimCollection (TRI_sim_collection_t* sim, TRI_idx_iid_t iid) {
|
||||
TRI_index_t* found;
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
@ -2437,42 +2437,35 @@ bool TRI_DropIndexSimCollection (TRI_sim_collection_t* collection, TRI_idx_iid_t
|
|||
return true;
|
||||
}
|
||||
|
||||
vector = TRI_Allocate(sizeof(TRI_vector_pointer_t));
|
||||
|
||||
if (!vector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
found = NULL;
|
||||
TRI_InitVectorPointer(vector);
|
||||
|
||||
// .............................................................................
|
||||
// within write-lock
|
||||
// inside write-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
n = collection->_indexes._length;
|
||||
n = sim->_indexes._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_index_t* idx;
|
||||
|
||||
idx = collection->_indexes._buffer[i];
|
||||
idx = sim->_indexes._buffer[i];
|
||||
|
||||
if (idx->_iid == iid) {
|
||||
found = TRI_RemoveVectorPointer(&collection->_indexes, i);
|
||||
found = TRI_RemoveVectorPointer(&sim->_indexes, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without write-lock
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
if (found != NULL) {
|
||||
return TRI_RemoveIndexFile(&collection->base, found);
|
||||
return TRI_RemoveIndexFile(&sim->base, found);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
@ -2560,10 +2553,10 @@ static TRI_json_t* JsonPrimary (TRI_index_t* idx, TRI_doc_collection_t* collecti
|
|||
|
||||
json = TRI_CreateArrayJson();
|
||||
|
||||
TRI_Insert2ArrayJson(json, "iid", TRI_CreateNumberJson(0));
|
||||
TRI_Insert2ArrayJson(json, "type", TRI_CreateStringCopyJson("primary"));
|
||||
TRI_Insert2ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1));
|
||||
TRI_Insert2ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id"));
|
||||
TRI_Insert3ArrayJson(json, "iid", TRI_CreateNumberJson(0));
|
||||
TRI_Insert3ArrayJson(json, "type", TRI_CreateStringCopyJson("primary"));
|
||||
TRI_Insert3ArrayJson(json, "fieldCount", TRI_CreateNumberJson(1));
|
||||
TRI_Insert3ArrayJson(json, "field_0", TRI_CreateStringCopyJson("_id"));
|
||||
|
||||
return json;
|
||||
}
|
||||
|
@ -2639,7 +2632,7 @@ TRI_vector_pointer_t TRI_LookupEdgesSimCollection (TRI_sim_collection_t* edges,
|
|||
/// @brief adds a geo index to a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
||||
char const* location,
|
||||
char const* latitude,
|
||||
char const* longitude,
|
||||
|
@ -2657,7 +2650,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
loc = 0;
|
||||
idx = NULL;
|
||||
|
||||
shaper = collection->base._shaper;
|
||||
shaper = sim->base._shaper;
|
||||
|
||||
if (location != NULL) {
|
||||
loc = shaper->findAttributePathByName(shaper, location);
|
||||
|
@ -2673,10 +2666,10 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
|
||||
// check, if we know the index
|
||||
if (location != NULL) {
|
||||
idx = TRI_LookupGeoIndexSimCollection(collection, loc, geoJson);
|
||||
idx = TRI_LookupGeoIndexSimCollection(sim, loc, geoJson);
|
||||
}
|
||||
else if (longitude != NULL && latitude != NULL) {
|
||||
idx = TRI_LookupGeoIndex2SimCollection(collection, lat, lon);
|
||||
idx = TRI_LookupGeoIndex2SimCollection(sim, lat, lon);
|
||||
}
|
||||
else {
|
||||
TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
|
@ -2694,14 +2687,14 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
|
||||
// create a new index
|
||||
if (location != NULL) {
|
||||
idx = TRI_CreateGeoIndex(&collection->base, location, loc, geoJson);
|
||||
idx = TRI_CreateGeoIndex(&sim->base, location, loc, geoJson);
|
||||
|
||||
LOG_TRACE("created geo-index for location '%s': %d",
|
||||
location,
|
||||
(unsigned long) loc);
|
||||
}
|
||||
else if (longitude != NULL && latitude != NULL) {
|
||||
idx = TRI_CreateGeoIndex2(&collection->base, latitude, lat, longitude, lon);
|
||||
idx = TRI_CreateGeoIndex2(&sim->base, latitude, lat, longitude, lon);
|
||||
|
||||
LOG_TRACE("created geo-index for location '%s': %d, %d",
|
||||
location,
|
||||
|
@ -2714,7 +2707,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
}
|
||||
|
||||
// initialises the index with all existing documents
|
||||
ok = FillIndex(collection, idx);
|
||||
ok = FillIndex(sim, idx);
|
||||
|
||||
if (! ok) {
|
||||
TRI_FreeGeoIndex(idx);
|
||||
|
@ -2722,7 +2715,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
}
|
||||
|
||||
// and store index
|
||||
TRI_PushBackVectorPointer(&collection->_indexes, idx);
|
||||
TRI_PushBackVectorPointer(&sim->_indexes, idx);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
@ -2850,7 +2843,6 @@ static TRI_index_t* CreateSkiplistIndexSimCollection (TRI_sim_collection_t* coll
|
|||
TRI_PushBackVectorPointer(&fields, path);
|
||||
}
|
||||
|
||||
|
||||
// ...........................................................................
|
||||
// Attempt to find an existing index which matches the attributes above.
|
||||
// If a suitable index is found, return that one otherwise we need to create
|
||||
|
@ -2978,7 +2970,6 @@ TRI_index_t* TRI_LookupGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index (unique or non-unique)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3003,7 +2994,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
TRI_index_t* idx = collection->_indexes._buffer[j];
|
||||
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
|
||||
bool found = true;
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// check that the type of the index is in fact a hash index
|
||||
|
@ -3012,7 +3002,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
if (idx->_type != TRI_IDX_TYPE_HASH_INDEX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// check that the number of paths (fields) in the hash index matches that
|
||||
|
@ -3023,7 +3012,6 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// Go through all the attributes and see if they match
|
||||
// .........................................................................
|
||||
|
@ -3031,6 +3019,7 @@ TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
for (k = 0; k < paths->_length; ++k) {
|
||||
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths,k)));
|
||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
|
||||
|
||||
if (field != shape) {
|
||||
found = false;
|
||||
break;
|
||||
|
@ -3073,7 +3062,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
TRI_skiplist_index_t* skiplistIndex = (TRI_skiplist_index_t*) idx;
|
||||
bool found = true;
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// check that the type of the index is in fact a skiplist index
|
||||
// .........................................................................
|
||||
|
@ -3081,7 +3069,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
if (idx->_type != TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// check that the number of paths (fields) in the index matches that
|
||||
|
@ -3092,7 +3079,6 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// Go through all the attributes and see if they match
|
||||
// .........................................................................
|
||||
|
@ -3100,6 +3086,7 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
for (k = 0; k < paths->_length; ++k) {
|
||||
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&skiplistIndex->_paths,k)));
|
||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths,k)));
|
||||
|
||||
if (field != shape) {
|
||||
found = false;
|
||||
break;
|
||||
|
@ -3120,32 +3107,32 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
/// @brief ensures that a geo index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
||||
char const* location,
|
||||
bool geoJson) {
|
||||
TRI_index_t* idx;
|
||||
bool ok;
|
||||
|
||||
// .............................................................................
|
||||
// within write-lock the collection
|
||||
// inside write-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
idx = CreateGeoIndexSimCollection(collection, location, NULL, NULL, geoJson, 0);
|
||||
idx = CreateGeoIndexSimCollection(sim, location, NULL, NULL, geoJson, 0);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without write-lock
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
ok = TRI_SaveIndex(&collection->base, idx);
|
||||
ok = TRI_SaveIndex(&sim->base, idx);
|
||||
|
||||
return ok ? idx->_iid : 0;
|
||||
}
|
||||
|
@ -3154,32 +3141,32 @@ TRI_idx_iid_t TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
/// @brief ensures that a geo index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* sim,
|
||||
char const* latitude,
|
||||
char const* longitude) {
|
||||
TRI_index_t* idx;
|
||||
bool ok;
|
||||
|
||||
// .............................................................................
|
||||
// within write-lock the collection
|
||||
// inside write-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
idx = CreateGeoIndexSimCollection(collection, NULL, latitude, longitude, false, 0);
|
||||
idx = CreateGeoIndexSimCollection(sim, NULL, latitude, longitude, false, 0);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without write-lock
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
ok = TRI_SaveIndex(&collection->base, idx);
|
||||
ok = TRI_SaveIndex(&sim->base, idx);
|
||||
|
||||
return ok ? idx->_iid : 0;
|
||||
}
|
||||
|
@ -3189,43 +3176,37 @@ TRI_idx_iid_t TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection
|
|||
/// @brief ensures that a hash index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* collection,
|
||||
TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* sim,
|
||||
const TRI_vector_t* attributes,
|
||||
bool unique) {
|
||||
TRI_index_t* idx;
|
||||
bool ok;
|
||||
|
||||
// .............................................................................
|
||||
// within write-lock the collection
|
||||
// inside write-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// Given the list of attributes (as strings)
|
||||
// .............................................................................
|
||||
|
||||
idx = CreateHashIndexSimCollection(collection, attributes, 0, unique);
|
||||
idx = CreateHashIndexSimCollection(sim, attributes, 0, unique);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without write-lock
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
ok = TRI_SaveIndex(&collection->base, idx);
|
||||
ok = TRI_SaveIndex(&sim->base, idx);
|
||||
|
||||
if (ok) {
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return ok ? idx->_iid : 0;
|
||||
}
|
||||
|
||||
|
@ -3233,42 +3214,36 @@ TRI_idx_iid_t TRI_EnsureHashIndexSimCollection(TRI_sim_collection_t* collection,
|
|||
/// @brief ensures that a skiplist index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_idx_iid_t TRI_EnsureSkiplistIndexSimCollection(TRI_sim_collection_t* collection,
|
||||
TRI_idx_iid_t TRI_EnsureSkiplistIndexSimCollection(TRI_sim_collection_t* sim,
|
||||
const TRI_vector_t* attributes,
|
||||
bool unique) {
|
||||
TRI_index_t* idx;
|
||||
bool ok;
|
||||
|
||||
// .............................................................................
|
||||
// within write-lock the collection
|
||||
// inside write-lock the collection
|
||||
// .............................................................................
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// Given the list of attributes (as strings)
|
||||
// .............................................................................
|
||||
|
||||
idx = CreateSkiplistIndexSimCollection(collection, attributes, 0, unique);
|
||||
idx = CreateSkiplistIndexSimCollection(sim, attributes, 0, unique);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// without write-lock
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
ok = TRI_SaveIndex(&collection->base, idx);
|
||||
|
||||
if (ok) {
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
ok = TRI_SaveIndex(&sim->base, idx);
|
||||
|
||||
return ok ? idx->_iid : 0;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,103 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read locks the journal files and the parameter file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(a) \
|
||||
TRI_ReadLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read unlocks the journal files and the parameter file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(a) \
|
||||
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write locks the journal files and the parameter file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(a) \
|
||||
TRI_WriteLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write unlocks the journal files and the parameter file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(a) \
|
||||
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read locks the documents and indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
|
||||
TRI_ReadLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read unlocks the documents and indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
|
||||
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write locks the documents and indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
|
||||
TRI_WriteLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write unlocks the documents and indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(a) \
|
||||
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locks the journal entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
|
||||
TRI_LockCondition(&(a)->_journalsCondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unlocks the journal entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
|
||||
TRI_UnlockCondition(&(a)->_journalsCondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief waits for the journal entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WAIT_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
|
||||
TRI_WaitCondition(&(a)->_journalsCondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief signals the journal entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(a) \
|
||||
TRI_BroadcastCondition(&(a)->_journalsCondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
/// @brief checks if a file needs to be synced
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
|
||||
static bool CheckSyncSimCollection (TRI_sim_collection_t* sim) {
|
||||
TRI_collection_t* base;
|
||||
TRI_datafile_t* journal;
|
||||
TRI_voc_size_t nWritten;
|
||||
|
@ -57,7 +57,7 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
|
|||
size_t n;
|
||||
|
||||
worked = false;
|
||||
base = &collection->base.base;
|
||||
base = &sim->base.base;
|
||||
|
||||
// .............................................................................
|
||||
// the only thread MODIFYING the _journals variable is this thread,
|
||||
|
@ -69,21 +69,21 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
|
|||
for (i = 0; i < n; ++i) {
|
||||
journal = base->_journals._buffer[i];
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
synced = journal->_synced;
|
||||
|
||||
written = journal->_written;
|
||||
nWritten = journal->_nWritten;
|
||||
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (synced < written) {
|
||||
worked = true;
|
||||
ok = TRI_msync(journal->_fd, synced, written);
|
||||
ti = TRI_microtime();
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (ok) {
|
||||
journal->_synced = written;
|
||||
|
@ -94,8 +94,8 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
|
|||
journal->_state = TRI_DF_STATE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
TRI_BroadcastCondition(&collection->_journalsCondition);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (ok) {
|
||||
LOG_TRACE("msync succeeded %p, size %lu", synced, (unsigned long)(written - synced));
|
||||
|
@ -113,7 +113,7 @@ static bool CheckSyncSimCollection (TRI_sim_collection_t* collection) {
|
|||
/// @brief checks the journal of a document collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
|
||||
static bool CheckJournalSimCollection (TRI_sim_collection_t* sim) {
|
||||
TRI_collection_t* base;
|
||||
TRI_datafile_t* journal;
|
||||
bool worked;
|
||||
|
@ -121,7 +121,7 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
|
|||
size_t n;
|
||||
|
||||
worked = false;
|
||||
base = &collection->base.base;
|
||||
base = &sim->base.base;
|
||||
|
||||
// .............................................................................
|
||||
// the only thread MODIFYING the _journals variable is this thread,
|
||||
|
@ -138,9 +138,9 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
|
|||
|
||||
LOG_DEBUG("closing full journal '%s'", journal->_filename);
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_CloseJournalDocCollection(&collection->base, i);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_CloseJournalDocCollection(&sim->base, i);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
n = base->_journals._length;
|
||||
i = 0;
|
||||
|
@ -153,16 +153,16 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
|
|||
if (base->_journals._length == 0) {
|
||||
worked = true;
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
journal = TRI_CreateJournalDocCollection(&collection->base);
|
||||
journal = TRI_CreateJournalDocCollection(&sim->base);
|
||||
|
||||
if (journal != NULL) {
|
||||
LOG_DEBUG("created new journal '%s'", journal->_filename);
|
||||
}
|
||||
|
||||
TRI_BroadcastCondition(&collection->_journalsCondition);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
return worked;
|
||||
|
@ -172,10 +172,9 @@ static bool CheckJournalSimCollection (TRI_sim_collection_t* collection) {
|
|||
/// @brief checks if a compactor file needs to be synced
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
|
||||
static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* sim) {
|
||||
TRI_collection_t* base;
|
||||
TRI_datafile_t* journal;
|
||||
// TRI_voc_size_t nWritten;
|
||||
bool ok;
|
||||
bool worked;
|
||||
char const* synced;
|
||||
|
@ -185,7 +184,7 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
size_t n;
|
||||
|
||||
worked = false;
|
||||
base = &collection->base.base;
|
||||
base = &sim->base.base;
|
||||
|
||||
// .............................................................................
|
||||
// the only thread MODIFYING the _compactors variable is this thread,
|
||||
|
@ -197,22 +196,19 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
for (i = 0; i < n; ++i) {
|
||||
journal = base->_compactors._buffer[i];
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
synced = journal->_synced;
|
||||
|
||||
written = journal->_written;
|
||||
// TODO: remove if not used
|
||||
// nWritten = journal->_nWritten;
|
||||
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (synced < written) {
|
||||
worked = true;
|
||||
ok = TRI_msync(journal->_fd, synced, written);
|
||||
ti = TRI_microtime();
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (ok) {
|
||||
journal->_synced = written;
|
||||
|
@ -222,8 +218,8 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
journal->_state = TRI_DF_STATE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
TRI_BroadcastCondition(&collection->_journalsCondition);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
if (ok) {
|
||||
LOG_TRACE("msync succeeded %p, size %lu", synced, (unsigned long)(written - synced));
|
||||
|
@ -241,7 +237,7 @@ static bool CheckSyncCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
/// @brief checks the compactor of a document collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
|
||||
static bool CheckCompactorSimCollection (TRI_sim_collection_t* sim) {
|
||||
TRI_collection_t* base;
|
||||
TRI_datafile_t* compactor;
|
||||
bool worked;
|
||||
|
@ -249,7 +245,7 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
size_t n;
|
||||
|
||||
worked = false;
|
||||
base = &collection->base.base;
|
||||
base = &sim->base.base;
|
||||
|
||||
// .............................................................................
|
||||
// the only thread MODIFYING the _compactor variable is this thread,
|
||||
|
@ -266,9 +262,9 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
|
||||
LOG_DEBUG("closing full compactor '%s'", compactor->_filename);
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_CloseCompactorDocCollection(&collection->base, i);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_CloseCompactorDocCollection(&sim->base, i);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
n = base->_compactors._length;
|
||||
i = 0;
|
||||
|
@ -281,16 +277,16 @@ static bool CheckCompactorSimCollection (TRI_sim_collection_t* collection) {
|
|||
if (base->_compactors._length == 0) {
|
||||
worked = true;
|
||||
|
||||
TRI_LockCondition(&collection->_journalsCondition);
|
||||
TRI_LOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
|
||||
compactor = TRI_CreateCompactorDocCollection(&collection->base);
|
||||
compactor = TRI_CreateCompactorDocCollection(&sim->base);
|
||||
|
||||
if (compactor != NULL) {
|
||||
LOG_DEBUG("created new compactor '%s'", compactor->_filename);
|
||||
}
|
||||
|
||||
TRI_BroadcastCondition(&collection->_journalsCondition);
|
||||
TRI_UnlockCondition(&collection->_journalsCondition);
|
||||
TRI_BROADCAST_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
TRI_UNLOCK_JOURNAL_ENTRIES_SIM_COLLECTION(sim);
|
||||
}
|
||||
|
||||
return worked;
|
||||
|
@ -328,9 +324,11 @@ void TRI_SynchroniserVocBase (void* data) {
|
|||
worked = false;
|
||||
|
||||
// copy all collections
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
n = collections._length;
|
||||
|
||||
|
@ -341,10 +339,10 @@ void TRI_SynchroniserVocBase (void* data) {
|
|||
|
||||
collection = collections._buffer[i];
|
||||
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_LOADED) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -367,7 +365,7 @@ void TRI_SynchroniserVocBase (void* data) {
|
|||
worked |= result;
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
}
|
||||
|
||||
if (! worked) {
|
||||
|
|
|
@ -164,17 +164,17 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
|
|||
|
||||
collection = data;
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (collection->_collection == NULL) {
|
||||
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
|
|||
|
||||
collection->_status = TRI_VOC_COL_STATUS_LOADED;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
|
|||
|
||||
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,136 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
|
|||
collection->_status = TRI_VOC_COL_STATUS_UNLOADED;
|
||||
collection->_collection = NULL;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
|
||||
TRI_sim_collection_t* sim;
|
||||
TRI_vocbase_col_t* collection;
|
||||
TRI_vocbase_t* vocbase;
|
||||
regmatch_t matches[3];
|
||||
regex_t re;
|
||||
char* tmp1;
|
||||
char* tmp2;
|
||||
char* tmp3;
|
||||
char* newFilename;
|
||||
int res;
|
||||
int i;
|
||||
|
||||
collection = data;
|
||||
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_DELETED) {
|
||||
LOG_ERROR("someone resurrected the collection '%s'", collection->_name);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return false;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// unload collection
|
||||
// .............................................................................
|
||||
|
||||
if (collection->_collection != NULL) {
|
||||
if (collection->_collection->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
|
||||
LOG_ERROR("cannot drop collection '%s' of type '%d'",
|
||||
collection->_name,
|
||||
(int) collection->_collection->base._type);
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return false;
|
||||
}
|
||||
|
||||
sim = (TRI_sim_collection_t*) collection->_collection;
|
||||
|
||||
res = TRI_CloseSimCollection(sim);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("failed to close collection '%s': %s",
|
||||
collection->_name,
|
||||
TRI_last_error());
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRI_FreeSimCollection(sim);
|
||||
|
||||
collection->_collection = NULL;
|
||||
}
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// .............................................................................
|
||||
// remove from list of collections
|
||||
// .............................................................................
|
||||
|
||||
vocbase = collection->_vocbase;
|
||||
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
for (i = 0; i < vocbase->_collections._length; ++i) {
|
||||
if (vocbase->_collections._buffer[i] == collection) {
|
||||
TRI_RemoveVectorPointer(&vocbase->_collections, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// .............................................................................
|
||||
// rename collection directory
|
||||
// .............................................................................
|
||||
|
||||
if (collection->_path != NULL) {
|
||||
regcomp(&re, "^(.*)/collection-([0-9][0-9]*)$", REG_ICASE | REG_EXTENDED);
|
||||
|
||||
if (regexec(&re, collection->_path, sizeof(matches) / sizeof(matches[0]), matches, 0) == 0) {
|
||||
char const* first = collection->_path + matches[1].rm_so;
|
||||
size_t firstLen = matches[1].rm_eo - matches[1].rm_so;
|
||||
|
||||
char const* second = collection->_path + matches[2].rm_so;
|
||||
size_t secondLen = matches[2].rm_eo - matches[2].rm_so;
|
||||
|
||||
tmp1 = TRI_DuplicateString2(first, firstLen);
|
||||
tmp2 = TRI_DuplicateString2(second, secondLen);
|
||||
tmp3 = TRI_Concatenate2String("deleted-", tmp2);
|
||||
TRI_FreeString(tmp2);
|
||||
|
||||
newFilename = TRI_Concatenate2File(tmp1, tmp3);
|
||||
TRI_FreeString(tmp1);
|
||||
TRI_FreeString(tmp3);
|
||||
|
||||
res = TRI_RenameFile(collection->_path, newFilename);
|
||||
TRI_FreeString(newFilename);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot rename dropped collection '%s' from '%s' to '%s'",
|
||||
collection->_name,
|
||||
collection->_path,
|
||||
newFilename);
|
||||
}
|
||||
else {
|
||||
LOG_DEBUG("renamed dropped collection '%s' from '%s' to '%s'",
|
||||
collection->_name,
|
||||
collection->_path,
|
||||
newFilename);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("cannot rename dropped collection '%s': unknown path '%s'",
|
||||
collection->_name,
|
||||
collection->_path);
|
||||
}
|
||||
|
||||
regfree(&re);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -317,11 +446,15 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
|
|||
if (TRI_IsDirectory(file)) {
|
||||
TRI_col_info_t info;
|
||||
|
||||
res = TRI_LoadParameterInfo(file, &info);
|
||||
// no need to lock as we are scanning
|
||||
res = TRI_LoadParameterInfoCollection(file, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_DEBUG("ignoring directory '%s' without valid parameter file '%s'", file, TRI_COL_PARAMETER_FILE);
|
||||
}
|
||||
else if (info._deleted) {
|
||||
LOG_DEBUG("ignoring deleted collection '%s'", file);
|
||||
}
|
||||
else {
|
||||
type = info._type;
|
||||
|
||||
|
@ -351,6 +484,8 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) {
|
|||
TRI_FreeString(file);
|
||||
}
|
||||
|
||||
regfree(&re);
|
||||
|
||||
TRI_DestroyVectorString(&files);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -364,7 +499,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
|
|||
TRI_vocbase_col_t* collection;
|
||||
char wrong;
|
||||
|
||||
TRI_WriteLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// .............................................................................
|
||||
// check that we have an existing name
|
||||
|
@ -373,7 +508,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
|
|||
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||
|
||||
if (found.v != NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return found.c;
|
||||
}
|
||||
|
||||
|
@ -385,7 +520,7 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
|
|||
wrong = TRI_IsAllowedCollectionName(name);
|
||||
|
||||
if (wrong != 0) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
LOG_ERROR("found illegal character in name: %c", wrong);
|
||||
|
||||
|
@ -397,13 +532,13 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
|
|||
collection = AddCollection(vocbase, TRI_COL_TYPE_SIMPLE_DOCUMENT, name, TRI_NewTickVocBase(), NULL);
|
||||
|
||||
if (collection == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
collection->_status = TRI_VOC_COL_STATUS_NEW_BORN;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
@ -414,38 +549,38 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, char co
|
|||
static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
|
||||
TRI_col_type_e type;
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// cannot manifest a corrupted collection
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
// cannot manifest a deleted collection
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// loaded, unloaded, or unloading are manifested
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
|
@ -469,14 +604,15 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
|
|||
if (sim == NULL) {
|
||||
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_errno();
|
||||
}
|
||||
|
||||
collection->_status = TRI_VOC_COL_STATUS_LOADED;
|
||||
collection->_collection = &sim->base;
|
||||
collection->_path = TRI_DuplicateString(sim->base.base._directory);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -484,7 +620,7 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
|
|||
|
||||
LOG_ERROR("unknown collection type '%d' in collection '%s'", (int) type, collection->_name);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
|
||||
}
|
||||
}
|
||||
|
@ -505,7 +641,7 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
|
|||
// .............................................................................
|
||||
|
||||
// check if the collection is already loaded
|
||||
TRI_ReadLockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
|
||||
|
||||
|
@ -514,27 +650,27 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
|
|||
}
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
// release the read lock and acquire a write lock, we have to do some work
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// .............................................................................
|
||||
// write lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// someone else loaded the collection, release the WRITE lock and try again
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return LoadCollectionVocBase(vocbase, collection);
|
||||
}
|
||||
|
||||
|
@ -542,25 +678,25 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
|
|||
// release the WRITE lock and try again
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
collection->_status = TRI_VOC_COL_STATUS_LOADED;
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return LoadCollectionVocBase(vocbase, collection);
|
||||
}
|
||||
|
||||
// deleted, give up
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// corrupted, give up
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
// new born, manifest collection, release the WRITE lock and try again
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
res = ManifestCollectionVocBase(vocbase, collection);
|
||||
|
||||
|
@ -583,28 +719,29 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col
|
|||
if (sim == NULL) {
|
||||
collection->_status = TRI_VOC_COL_STATUS_CORRUPTED;
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
collection->_collection = &sim->base;
|
||||
collection->_status = TRI_VOC_COL_STATUS_LOADED;
|
||||
collection->_path = TRI_DuplicateString(sim->base.base._directory);
|
||||
|
||||
// release the WRITE lock and try again
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return LoadCollectionVocBase(vocbase, collection);
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("unknown collection type %d for '%s'", (int) type, collection->_name);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("unknown collection status %d for '%s'", (int) collection->_status, collection->_name);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
|
@ -899,7 +1036,7 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
|
|||
|
||||
TRI_InitVectorPointer(&result);
|
||||
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
for (i = 0; i < vocbase->_collectionsById._nrAlloc; ++i) {
|
||||
found = vocbase->_collectionsById._table[i];
|
||||
|
@ -909,7 +1046,7 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -921,9 +1058,9 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
|
|||
TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name) {
|
||||
union { void const* v; TRI_vocbase_col_t* c; } found;
|
||||
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
return found.c;
|
||||
}
|
||||
|
@ -935,9 +1072,9 @@ TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase, ch
|
|||
TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_voc_cid_t id) {
|
||||
union { void const* v; TRI_vocbase_col_t* c; } found;
|
||||
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id);
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
return found.c;
|
||||
}
|
||||
|
@ -949,9 +1086,9 @@ TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_
|
|||
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
|
||||
union { void const* v; TRI_vocbase_col_t* c; } found;
|
||||
|
||||
TRI_ReadLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||
TRI_ReadUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
if (found.v != NULL) {
|
||||
return found.c;
|
||||
|
@ -977,7 +1114,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
char wrong;
|
||||
void const* found;
|
||||
|
||||
TRI_WriteLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// .............................................................................
|
||||
// check that we have a new name
|
||||
|
@ -987,7 +1124,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||
|
||||
if (found != NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
LOG_ERROR("collection named '%s' already exists", name);
|
||||
|
||||
|
@ -999,7 +1136,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
wrong = TRI_IsAllowedCollectionName(name);
|
||||
|
||||
if (wrong != 0) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
LOG_ERROR("found illegal character in name: %c", wrong);
|
||||
|
||||
|
@ -1020,14 +1157,14 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
sim = TRI_CreateSimCollection(vocbase->_path, parameter, 0);
|
||||
|
||||
if (sim == NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
doc = &sim->base;
|
||||
}
|
||||
else {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
LOG_ERROR("unknown collection type: %d", parameter->_type);
|
||||
|
||||
|
@ -1048,14 +1185,15 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
TRI_FreeSimCollection((TRI_sim_collection_t*) doc);
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
collection->_status = TRI_VOC_COL_STATUS_LOADED;
|
||||
collection->_collection = doc;
|
||||
collection->_path = TRI_DuplicateString(doc->base._directory);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
@ -1064,41 +1202,41 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_col_
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
|
||||
TRI_WriteLockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// cannot unload a corrupted collection
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
// a unloaded collection is unloaded
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// a unloading collection is treated as unloaded
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// a new born collection is treated as unloaded
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// a deleted collection is treated as unloaded
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// must be loaded
|
||||
if (collection->_status != TRI_VOC_COL_STATUS_LOADED) {
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
|
@ -1112,24 +1250,130 @@ int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll
|
|||
collection);
|
||||
|
||||
// release locks
|
||||
TRI_WriteUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops a (document) collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
|
||||
TRI_col_info_t info;
|
||||
int res;
|
||||
|
||||
// remove name and id
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, collection->_name);
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsById, &collection->_cid);
|
||||
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// mark collection as deleted
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// .............................................................................
|
||||
// collection already deleted
|
||||
// .............................................................................
|
||||
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// new born collection, no datafile/parameter file exists
|
||||
// .............................................................................
|
||||
|
||||
else if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// collection is unloaded
|
||||
// .............................................................................
|
||||
|
||||
else if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
|
||||
res = TRI_LoadParameterInfoCollection(collection->_path, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
|
||||
if (! info._deleted) {
|
||||
info._deleted = true;
|
||||
|
||||
res = TRI_SaveParameterInfoCollection(collection->_path, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
}
|
||||
|
||||
collection->_status = TRI_VOC_COL_STATUS_DELETED;
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
DropCollectionCallback(0, collection);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// collection is loaded
|
||||
// .............................................................................
|
||||
|
||||
else if (collection->_status == TRI_VOC_COL_STATUS_LOADED || collection->_status == TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
collection->_collection->base._deleted = true;
|
||||
|
||||
res = TRI_UpdateParameterInfoCollection(&collection->_collection->base);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return res;
|
||||
}
|
||||
|
||||
collection->_status = TRI_VOC_COL_STATUS_DELETED;
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// added callback for dropping
|
||||
TRI_CreateBarrierCollection(&collection->_collection->_barrierList,
|
||||
&collection->_collection->base,
|
||||
DropCollectionCallback,
|
||||
collection);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// upps, unknown status
|
||||
// .............................................................................
|
||||
|
||||
else {
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a (document) collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col, char const* newName) {
|
||||
TRI_col_info_t info;
|
||||
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection, char const* newName) {
|
||||
union { TRI_vocbase_col_t* v; TRI_vocbase_col_t const* c; } cnv;
|
||||
TRI_col_info_t info;
|
||||
void* found;
|
||||
char wrong;
|
||||
char const* oldName;
|
||||
int res;
|
||||
|
||||
// old name should be different
|
||||
oldName = col->_name;
|
||||
oldName = collection->_name;
|
||||
|
||||
if (TRI_EqualString(oldName, newName)) {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -1144,34 +1388,34 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
|
|||
}
|
||||
|
||||
// lock collection because we are going to change the name
|
||||
TRI_WriteLockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
// the must be done after the collection lock
|
||||
TRI_WriteLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// cannot rename a corrupted collection
|
||||
if (col->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_CORRUPTED_COLLECTION);
|
||||
}
|
||||
|
||||
// cannot rename a deleted collection
|
||||
if (col->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// check if the new name is unused
|
||||
cnv.c = col;
|
||||
cnv.c = collection;
|
||||
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false);
|
||||
|
||||
if (found != NULL) {
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_NAME);
|
||||
}
|
||||
|
@ -1180,59 +1424,59 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
|
|||
// new born collection, no datafile/parameter file exists
|
||||
// .............................................................................
|
||||
|
||||
if (col->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_CopyString(col->_name, newName, sizeof(col->_name));
|
||||
if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) {
|
||||
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// collection is unloaded
|
||||
// .............................................................................
|
||||
|
||||
else if (col->_status == TRI_VOC_COL_STATUS_UNLOADED) {
|
||||
res = TRI_LoadParameterInfo(col->_path, &info);
|
||||
else if (collection->_status == TRI_VOC_COL_STATUS_UNLOADED) {
|
||||
res = TRI_LoadParameterInfoCollection(collection->_path, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
|
||||
TRI_CopyString(info._name, newName, sizeof(info._name));
|
||||
|
||||
res = TRI_SaveParameterInfo(col->_path, &info);
|
||||
res = TRI_SaveParameterInfoCollection(collection->_path, &info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
|
||||
TRI_CopyString(col->_name, newName, sizeof(col->_name));
|
||||
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// collection is loaded
|
||||
// .............................................................................
|
||||
|
||||
else if (col->_status != TRI_VOC_COL_STATUS_LOADED || col->_status != TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
res = TRI_RenameCollection(&col->_collection->base, newName);
|
||||
else if (collection->_status != TRI_VOC_COL_STATUS_LOADED || collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
|
||||
res = TRI_RenameCollection(&collection->_collection->base, newName);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
|
||||
TRI_CopyString(col->_name, newName, sizeof(col->_name));
|
||||
TRI_CopyString(collection->_name, newName, sizeof(collection->_name));
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
|
@ -1242,8 +1486,8 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
|
|||
else {
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
@ -1254,8 +1498,8 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
|
|||
|
||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName);
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WriteUnlockReadWriteLock(&col->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1273,7 +1517,7 @@ int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collect
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) {
|
||||
TRI_ReadUnlockReadWriteLock(&collection->_lock);
|
||||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1289,9 +1533,9 @@ TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t* vocbase, char
|
|||
// check that we have an existing name
|
||||
// .............................................................................
|
||||
|
||||
TRI_WriteLockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
collection = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
|
||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
if (collection == NULL) {
|
||||
LOG_ERROR("unknown collection '%s'", name);
|
||||
|
|
|
@ -40,10 +40,83 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- forward declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct TRI_doc_collection_s;
|
||||
struct TRI_col_parameter_s;
|
||||
struct TRI_shadow_store_s;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read locks the collections structure
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_LOCK_COLLECTIONS_VOCBASE(a) \
|
||||
TRI_ReadLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read unlocks the collections structure
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(a) \
|
||||
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write locks the collections structure
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(a) \
|
||||
TRI_WriteLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write unlocks the collections structure
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(a) \
|
||||
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read locks the vocbase collection status
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_LOCK_STATUS_VOCBASE_COL(a) \
|
||||
TRI_ReadLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read unlocks the vocbase collection status
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_READ_UNLOCK_STATUS_VOCBASE_COL(a) \
|
||||
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write locks the vocbase collection status
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_LOCK_STATUS_VOCBASE_COL(a) \
|
||||
TRI_WriteLockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief write unlocks the vocbase collection status
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(a) \
|
||||
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -311,7 +384,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t*);
|
|||
/// @brief returns all known collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase);
|
||||
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a (document) collection by name
|
||||
|
@ -341,13 +414,19 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t*, struct TRI_col_p
|
|||
/// @brief unloads a (document) collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
|
||||
int TRI_UnloadCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drops a (document) collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_DropCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a (document) collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col, char const* name);
|
||||
int TRI_RenameCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*, char const* name);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locks a (document) collection for usage, loading or manifesting it
|
||||
|
@ -356,7 +435,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col,
|
|||
/// collection lock by yourself.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
|
||||
int TRI_UseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locks a (document) collection for usage by name
|
||||
|
@ -366,19 +445,19 @@ int TRI_UseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
|
|||
/// when you are done with the collection.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name);
|
||||
TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t*, char const* name);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief releases a (document) collection from usage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
|
||||
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief releases a (document) collection from usage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* col);
|
||||
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
Loading…
Reference in New Issue