mirror of https://gitee.com/bigwinds/arangodb
WAL DDL markers
This commit is contained in:
parent
d266bedd38
commit
6c0dcf85c4
|
@ -50,17 +50,6 @@ static void DestroyElement (TRI_hash_array_t* array,
|
||||||
element->_document = nullptr;
|
element->_document = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief determines if two elements are equal
|
|
||||||
///
|
|
||||||
/// Two elements are 'equal' if the document pointer is the same.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static inline bool IsEqualElementElement (TRI_hash_index_element_t* left,
|
|
||||||
TRI_hash_index_element_t* right) {
|
|
||||||
return (left->_document != nullptr && left->_document == right->_document);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief determines if a key corresponds to an element
|
/// @brief determines if a key corresponds to an element
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -459,9 +448,9 @@ int TRI_RemoveElementHashArray (TRI_hash_array_t* array,
|
||||||
|
|
||||||
i = k = HashElement(array, element) % n;
|
i = k = HashElement(array, element) % n;
|
||||||
|
|
||||||
for (; i < n && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (; i < n && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
if (i == n) {
|
if (i == n) {
|
||||||
for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (i = 0; i < k && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT_EXPENSIVE(i < n);
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
@ -572,9 +561,9 @@ int TRI_InsertElementHashArrayMulti (TRI_hash_array_t* array,
|
||||||
|
|
||||||
i = k = HashElement(array, element) % n;
|
i = k = HashElement(array, element) % n;
|
||||||
|
|
||||||
for (; i < n && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (; i < n && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
if (i == n) {
|
if (i == n) {
|
||||||
for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (i = 0; i < k && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT_EXPENSIVE(i < n);
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
@ -625,9 +614,9 @@ int TRI_RemoveElementHashArrayMulti (TRI_hash_array_t* array,
|
||||||
|
|
||||||
i = k = HashElement(array, element) % n;
|
i = k = HashElement(array, element) % n;
|
||||||
|
|
||||||
for (; i < n && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (; i < n && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
if (i == n) {
|
if (i == n) {
|
||||||
for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualElementElement(element, &array->_table[i]); ++i);
|
for (i = 0; i < k && array->_table[i]._document != nullptr && element->_document != array->_table[i]._document; ++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT_EXPENSIVE(i < n);
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
|
|
@ -6730,11 +6730,30 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_json_t* json = TRI_CreateJsonCollectionInfo(&base->_info);
|
TRI_json_t* json = TRI_CreateJsonCollectionInfo(&base->_info);
|
||||||
TRI_LogChangePropertiesCollectionReplication(base->_vocbase,
|
|
||||||
base->_info._cid,
|
// now log the property changes
|
||||||
base->_info._name,
|
res = TRI_ERROR_NO_ERROR;
|
||||||
json,
|
|
||||||
TRI_GetIdServer());
|
try {
|
||||||
|
triagens::wal::ChangeCollectionMarker marker(base->_vocbase->_id, base->_info._cid, JsonHelper::toString(json));
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
// TODO: what to do here
|
||||||
|
LOG_WARNING("could not save collection change marker in log: %s", TRI_errno_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1141,6 +1141,10 @@ char const* TRI_NameMarkerDatafile (TRI_df_marker_t const* marker) {
|
||||||
return "rename collection (wal)";
|
return "rename collection (wal)";
|
||||||
case TRI_WAL_MARKER_CHANGE_COLLECTION:
|
case TRI_WAL_MARKER_CHANGE_COLLECTION:
|
||||||
return "change collection (wal)";
|
return "change collection (wal)";
|
||||||
|
case TRI_WAL_MARKER_CREATE_INDEX:
|
||||||
|
return "create index (wal)";
|
||||||
|
case TRI_WAL_MARKER_DROP_INDEX:
|
||||||
|
return "drop index (wal)";
|
||||||
case TRI_WAL_MARKER_CREATE_DATABASE:
|
case TRI_WAL_MARKER_CREATE_DATABASE:
|
||||||
return "create database (wal)";
|
return "create database (wal)";
|
||||||
case TRI_WAL_MARKER_DROP_DATABASE:
|
case TRI_WAL_MARKER_DROP_DATABASE:
|
||||||
|
|
|
@ -171,6 +171,8 @@ typedef enum {
|
||||||
TRI_WAL_MARKER_DROP_COLLECTION = 4031,
|
TRI_WAL_MARKER_DROP_COLLECTION = 4031,
|
||||||
TRI_WAL_MARKER_RENAME_COLLECTION = 4032,
|
TRI_WAL_MARKER_RENAME_COLLECTION = 4032,
|
||||||
TRI_WAL_MARKER_CHANGE_COLLECTION = 4033,
|
TRI_WAL_MARKER_CHANGE_COLLECTION = 4033,
|
||||||
|
TRI_WAL_MARKER_CREATE_INDEX = 4035,
|
||||||
|
TRI_WAL_MARKER_DROP_INDEX = 4036,
|
||||||
|
|
||||||
TRI_WAL_MARKER_CREATE_DATABASE = 4040,
|
TRI_WAL_MARKER_CREATE_DATABASE = 4040,
|
||||||
TRI_WAL_MARKER_DROP_DATABASE = 4041,
|
TRI_WAL_MARKER_DROP_DATABASE = 4041,
|
||||||
|
|
|
@ -232,16 +232,12 @@ static TRI_datafile_t* CreateCompactor (TRI_document_collection_t* document,
|
||||||
|
|
||||||
if (document->_info._isVolatile) {
|
if (document->_info._isVolatile) {
|
||||||
// in-memory collection
|
// in-memory collection
|
||||||
journal = TRI_CreateDatafile(NULL, fid, maximalSize, true);
|
journal = TRI_CreateDatafile(nullptr, fid, maximalSize, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char* jname;
|
char* number = TRI_StringUInt64(fid);
|
||||||
char* number;
|
char* jname = TRI_Concatenate3String("compaction-", number, ".db");
|
||||||
char* filename;
|
char* filename = TRI_Concatenate2File(document->_directory, jname);
|
||||||
|
|
||||||
number = TRI_StringUInt64(fid);
|
|
||||||
jname = TRI_Concatenate3String("compaction-", number, ".db");
|
|
||||||
filename = TRI_Concatenate2File(document->_directory, jname);
|
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, jname);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, jname);
|
||||||
|
@ -255,7 +251,7 @@ static TRI_datafile_t* CreateCompactor (TRI_document_collection_t* document,
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (journal == NULL) {
|
if (journal == nullptr) {
|
||||||
if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
|
if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
|
||||||
document->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
|
document->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +259,7 @@ static TRI_datafile_t* CreateCompactor (TRI_document_collection_t* document,
|
||||||
document->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
|
document->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_TRACE("created new compactor '%s'", journal->getName(journal));
|
LOG_TRACE("created new compactor '%s'", journal->getName(journal));
|
||||||
|
@ -279,7 +275,7 @@ static TRI_datafile_t* CreateCompactor (TRI_document_collection_t* document,
|
||||||
|
|
||||||
TRI_FreeDatafile(journal);
|
TRI_FreeDatafile(journal);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -297,7 +293,7 @@ static TRI_datafile_t* CreateCompactor (TRI_document_collection_t* document,
|
||||||
|
|
||||||
TRI_FreeDatafile(journal);
|
TRI_FreeDatafile(journal);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT(fid == journal->_fid);
|
TRI_ASSERT(fid == journal->_fid);
|
||||||
|
@ -666,10 +662,10 @@ static int AddIndex (TRI_document_collection_t* document,
|
||||||
|
|
||||||
static void RebuildIndexInfo (TRI_document_collection_t* document) {
|
static void RebuildIndexInfo (TRI_document_collection_t* document) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
size_t const n = document->_allIndexes._length;
|
size_t const n = document->_allIndexes._length;
|
||||||
|
|
||||||
for (size_t i = 0 ; i < n ; ++i) {
|
for (size_t i = 0 ; i < n ; ++i) {
|
||||||
TRI_index_t* idx = (TRI_index_t*) document->_allIndexes._buffer[i];
|
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
||||||
|
|
||||||
if (idx->cleanup != nullptr) {
|
if (idx->cleanup != nullptr) {
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -2181,13 +2177,8 @@ static int IterateMarkersCollection (TRI_collection_t* collection) {
|
||||||
|
|
||||||
TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
char const* path,
|
char const* path,
|
||||||
TRI_col_info_t* parameter,
|
TRI_col_info_t* parameters,
|
||||||
TRI_voc_cid_t cid) {
|
TRI_voc_cid_t cid) {
|
||||||
TRI_collection_t* collection;
|
|
||||||
TRI_shaper_t* shaper;
|
|
||||||
TRI_document_collection_t* document;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (cid > 0) {
|
if (cid > 0) {
|
||||||
TRI_UpdateTickServer(cid);
|
TRI_UpdateTickServer(cid);
|
||||||
}
|
}
|
||||||
|
@ -2195,10 +2186,10 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
cid = TRI_NewTickServer();
|
cid = TRI_NewTickServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
parameter->_cid = cid;
|
parameters->_cid = cid;
|
||||||
|
|
||||||
// check if we can generate the key generator
|
// check if we can generate the key generator
|
||||||
KeyGenerator* keyGenerator = KeyGenerator::factory(parameter->_keyOptions);
|
KeyGenerator* keyGenerator = KeyGenerator::factory(parameters->_keyOptions);
|
||||||
|
|
||||||
if (keyGenerator == nullptr) {
|
if (keyGenerator == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_INVALID_KEY_GENERATOR);
|
TRI_set_errno(TRI_ERROR_ARANGO_INVALID_KEY_GENERATOR);
|
||||||
|
@ -2206,6 +2197,7 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
// first create the document collection
|
// first create the document collection
|
||||||
|
TRI_document_collection_t* document;
|
||||||
try {
|
try {
|
||||||
document = new TRI_document_collection_t();
|
document = new TRI_document_collection_t();
|
||||||
}
|
}
|
||||||
|
@ -2222,7 +2214,8 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
document->_keyGenerator = keyGenerator;
|
document->_keyGenerator = keyGenerator;
|
||||||
collection = TRI_CreateCollection(vocbase, document, path, parameter);
|
|
||||||
|
TRI_collection_t* collection = TRI_CreateCollection(vocbase, document, path, parameters);
|
||||||
|
|
||||||
if (collection == nullptr) {
|
if (collection == nullptr) {
|
||||||
delete document;
|
delete document;
|
||||||
|
@ -2231,9 +2224,9 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaper = TRI_CreateVocShaper(vocbase, document);
|
TRI_shaper_t* shaper = TRI_CreateVocShaper(vocbase, document);
|
||||||
|
|
||||||
if (shaper == NULL) {
|
if (shaper == nullptr) {
|
||||||
LOG_ERROR("cannot create shaper");
|
LOG_ERROR("cannot create shaper");
|
||||||
|
|
||||||
TRI_CloseCollection(collection);
|
TRI_CloseCollection(collection);
|
||||||
|
@ -2256,7 +2249,7 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
document->_keyGenerator = keyGenerator;
|
document->_keyGenerator = keyGenerator;
|
||||||
|
|
||||||
// save the parameter block (within create, no need to lock)
|
// save the parameter block (within create, no need to lock)
|
||||||
res = TRI_SaveCollectionInfo(collection->_directory, parameter, vocbase->_settings.forceSyncProperties);
|
int res = TRI_SaveCollectionInfo(collection->_directory, parameters, false);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
// TODO: shouldn't we destroy &document->_allIndexes, free document->_headersPtr etc.?
|
// TODO: shouldn't we destroy &document->_allIndexes, free document->_headersPtr etc.?
|
||||||
|
@ -2559,31 +2552,27 @@ size_t TRI_DocumentIteratorDocumentCollection (TransactionBase const*,
|
||||||
int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
TRI_json_t const* json,
|
TRI_json_t const* json,
|
||||||
TRI_index_t** idx) {
|
TRI_index_t** idx) {
|
||||||
TRI_json_t const* type;
|
TRI_ASSERT(json != nullptr);
|
||||||
TRI_json_t const* iis;
|
|
||||||
char const* typeStr;
|
|
||||||
TRI_idx_iid_t iid;
|
|
||||||
|
|
||||||
TRI_ASSERT(json != NULL);
|
|
||||||
TRI_ASSERT(json->_type == TRI_JSON_ARRAY);
|
TRI_ASSERT(json->_type == TRI_JSON_ARRAY);
|
||||||
|
|
||||||
if (idx != NULL) {
|
if (idx != nullptr) {
|
||||||
*idx = NULL;
|
*idx = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the type
|
// extract the type
|
||||||
type = TRI_LookupArrayJson(json, "type");
|
TRI_json_t const* type = TRI_LookupArrayJson(json, "type");
|
||||||
|
|
||||||
if (! TRI_IsStringJson(type)) {
|
if (! TRI_IsStringJson(type)) {
|
||||||
return TRI_ERROR_INTERNAL;
|
return TRI_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeStr = type->_value._string.data;
|
char const* typeStr = type->_value._string.data;
|
||||||
|
|
||||||
// extract the index identifier
|
// extract the index identifier
|
||||||
iis = TRI_LookupArrayJson(json, "id");
|
TRI_json_t const* iis = TRI_LookupArrayJson(json, "id");
|
||||||
|
|
||||||
if (iis != NULL && iis->_type == TRI_JSON_NUMBER) {
|
TRI_idx_iid_t iid;
|
||||||
|
if (iis != nullptr && iis->_type == TRI_JSON_NUMBER) {
|
||||||
iid = (TRI_idx_iid_t) iis->_value._number;
|
iid = (TRI_idx_iid_t) iis->_value._number;
|
||||||
}
|
}
|
||||||
else if (TRI_IsStringJson(iis)) {
|
else if (TRI_IsStringJson(iis)) {
|
||||||
|
@ -2603,9 +2592,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
if (TRI_EqualString(typeStr, "cap")) {
|
if (TRI_EqualString(typeStr, "cap")) {
|
||||||
int res = CapConstraintFromJson(document, json, iid, idx);
|
return CapConstraintFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2613,9 +2600,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
else if (TRI_EqualString(typeStr, "bitarray")) {
|
else if (TRI_EqualString(typeStr, "bitarray")) {
|
||||||
int res = BitarrayIndexFromJson(document, json, iid, idx);
|
return BitarrayIndexFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2623,9 +2608,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
else if (TRI_EqualString(typeStr, "geo1") || TRI_EqualString(typeStr, "geo2")) {
|
else if (TRI_EqualString(typeStr, "geo1") || TRI_EqualString(typeStr, "geo2")) {
|
||||||
int res = GeoIndexFromJson(document, json, iid, idx);
|
return GeoIndexFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2633,9 +2616,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
else if (TRI_EqualString(typeStr, "hash")) {
|
else if (TRI_EqualString(typeStr, "hash")) {
|
||||||
int res = HashIndexFromJson(document, json, iid, idx);
|
return HashIndexFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2643,9 +2624,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
else if (TRI_EqualString(typeStr, "skiplist")) {
|
else if (TRI_EqualString(typeStr, "skiplist")) {
|
||||||
int res = SkiplistIndexFromJson(document, json, iid, idx);
|
return SkiplistIndexFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2653,9 +2632,7 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
else if (TRI_EqualString(typeStr, "fulltext")) {
|
else if (TRI_EqualString(typeStr, "fulltext")) {
|
||||||
int res = FulltextIndexFromJson(document, json, iid, idx);
|
return FulltextIndexFromJson(document, json, iid, idx);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
@ -2665,8 +2642,6 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
else if (TRI_EqualString(typeStr, "edge")) {
|
else if (TRI_EqualString(typeStr, "edge")) {
|
||||||
// we should never get here, as users cannot create their own edge indexes
|
// we should never get here, as users cannot create their own edge indexes
|
||||||
LOG_ERROR("logic error. there should never be a JSON file describing an edges index");
|
LOG_ERROR("logic error. there should never be a JSON file describing an edges index");
|
||||||
|
|
||||||
return TRI_ERROR_INTERNAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
|
@ -2677,9 +2652,9 @@ int TRI_FromJsonIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
LOG_ERROR("ignoring unknown index type '%s' for index %llu",
|
LOG_ERROR("ignoring unknown index type '%s' for index %llu",
|
||||||
typeStr,
|
typeStr,
|
||||||
(unsigned long long) iid);
|
(unsigned long long) iid);
|
||||||
|
|
||||||
return TRI_ERROR_INTERNAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRI_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2738,10 +2713,6 @@ bool TRI_CloseJournalDocumentCollection (TRI_document_collection_t* document,
|
||||||
|
|
||||||
TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase,
|
TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_vocbase_col_t* col) {
|
TRI_vocbase_col_t* col) {
|
||||||
TRI_collection_t* collection;
|
|
||||||
TRI_shaper_t* shaper;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
char const* path = col->_path;
|
char const* path = col->_path;
|
||||||
|
|
||||||
// first open the document collection
|
// first open the document collection
|
||||||
|
@ -2757,7 +2728,7 @@ TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
collection = TRI_OpenCollection(vocbase, document, path);
|
TRI_collection_t* collection = TRI_OpenCollection(vocbase, document, path);
|
||||||
|
|
||||||
if (collection == nullptr) {
|
if (collection == nullptr) {
|
||||||
delete document;
|
delete document;
|
||||||
|
@ -2766,7 +2737,7 @@ TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaper = TRI_CreateVocShaper(vocbase, document);
|
TRI_shaper_t* shaper = TRI_CreateVocShaper(vocbase, document);
|
||||||
|
|
||||||
if (shaper == nullptr) {
|
if (shaper == nullptr) {
|
||||||
LOG_ERROR("cannot create shaper");
|
LOG_ERROR("cannot create shaper");
|
||||||
|
@ -2803,7 +2774,7 @@ TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
TransactionBase trx(true);
|
TransactionBase trx(true);
|
||||||
|
|
||||||
// iterate over all markers of the collection
|
// iterate over all markers of the collection
|
||||||
res = IterateMarkersCollection(collection);
|
int res = IterateMarkersCollection(collection);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
if (document->_failedTransactions != nullptr) {
|
if (document->_failedTransactions != nullptr) {
|
||||||
|
@ -2880,28 +2851,25 @@ pid_name_t;
|
||||||
static TRI_json_t* ExtractFields (TRI_json_t const* json,
|
static TRI_json_t* ExtractFields (TRI_json_t const* json,
|
||||||
size_t* fieldCount,
|
size_t* fieldCount,
|
||||||
TRI_idx_iid_t iid) {
|
TRI_idx_iid_t iid) {
|
||||||
TRI_json_t* fld;
|
TRI_json_t* fld = TRI_LookupArrayJson(json, "fields");
|
||||||
size_t j;
|
|
||||||
|
|
||||||
fld = TRI_LookupArrayJson(json, "fields");
|
if (! TRI_IsListJson(fld)) {
|
||||||
|
|
||||||
if (fld == NULL || fld->_type != TRI_JSON_LIST) {
|
|
||||||
LOG_ERROR("ignoring index %llu, 'fields' must be a list", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, 'fields' must be a list", (unsigned long long) iid);
|
||||||
|
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fieldCount = fld->_value._objects._length;
|
*fieldCount = fld->_value._objects._length;
|
||||||
|
|
||||||
for (j = 0; j < *fieldCount; ++j) {
|
for (size_t j = 0; j < *fieldCount; ++j) {
|
||||||
TRI_json_t* sub = static_cast<TRI_json_t*>(TRI_AtVector(&fld->_value._objects, j));
|
TRI_json_t* sub = static_cast<TRI_json_t*>(TRI_AtVector(&fld->_value._objects, j));
|
||||||
|
|
||||||
if (! TRI_IsStringJson(sub)) {
|
if (! TRI_IsStringJson(sub)) {
|
||||||
LOG_ERROR("ignoring index %llu, 'fields' must be a list of attribute paths", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, 'fields' must be a list of attribute paths", (unsigned long long) iid);
|
||||||
|
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2920,16 +2888,13 @@ static TRI_json_t* ExtractFields (TRI_json_t const* json,
|
||||||
static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
size_t* fieldCount,
|
size_t* fieldCount,
|
||||||
TRI_idx_iid_t iid) {
|
TRI_idx_iid_t iid) {
|
||||||
TRI_json_t* keyValues;
|
TRI_json_t* keyValues = TRI_LookupArrayJson(jsonIndex, "fields");
|
||||||
size_t j;
|
|
||||||
|
|
||||||
keyValues = TRI_LookupArrayJson(jsonIndex, "fields");
|
if (! TRI_IsListJson(keyValues)) {
|
||||||
|
|
||||||
if (keyValues == NULL || keyValues->_type != TRI_JSON_LIST) {
|
|
||||||
LOG_ERROR("ignoring index %llu, 'fields' must be a list", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, 'fields' must be a list", (unsigned long long) iid);
|
||||||
|
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2940,7 +2905,7 @@ static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
// Some simple checks
|
// Some simple checks
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
for (j = 0; j < *fieldCount; ++j) {
|
for (size_t j = 0; j < *fieldCount; ++j) {
|
||||||
|
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
// Extract the jth key value pair
|
// Extract the jth key value pair
|
||||||
|
@ -2952,10 +2917,10 @@ static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
// The length of this key value pair must be two
|
// The length of this key value pair must be two
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
|
|
||||||
if (keyValue == NULL || keyValue->_value._objects._length != 2) {
|
if (keyValue == nullptr || keyValue->_value._objects._length != 2) {
|
||||||
LOG_ERROR("ignoring index %llu, 'fields' must be a list of key value pairs", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, 'fields' must be a list of key value pairs", (unsigned long long) iid);
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2968,7 +2933,7 @@ static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
if (! TRI_IsStringJson(key)) {
|
if (! TRI_IsStringJson(key)) {
|
||||||
LOG_ERROR("ignoring index %llu, key in 'fields' pair must be an attribute (string)", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, key in 'fields' pair must be an attribute (string)", (unsigned long long) iid);
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2978,10 +2943,10 @@ static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
|
|
||||||
TRI_json_t* value = static_cast<TRI_json_t*>(TRI_AtVector(&keyValue->_value._objects, 1));
|
TRI_json_t* value = static_cast<TRI_json_t*>(TRI_AtVector(&keyValue->_value._objects, 1));
|
||||||
|
|
||||||
if (value == NULL || value->_type != TRI_JSON_LIST) {
|
if (! TRI_IsListJson(value)) {
|
||||||
LOG_ERROR("ignoring index %llu, value in 'fields' pair must be a list ([...])", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, value in 'fields' pair must be a list ([...])", (unsigned long long) iid);
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2989,84 +2954,6 @@ static TRI_json_t* ExtractFieldValues (TRI_json_t const* jsonIndex,
|
||||||
return keyValues;
|
return keyValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief drops an index
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool DropIndex (TRI_document_collection_t* document,
|
|
||||||
TRI_idx_iid_t iid,
|
|
||||||
TRI_server_id_t generatingServer,
|
|
||||||
bool full) {
|
|
||||||
if (iid == 0) {
|
|
||||||
// invalid index id or primary index
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_index_t* found = nullptr;
|
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = document->_vocbase;
|
|
||||||
TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock);
|
|
||||||
|
|
||||||
// .............................................................................
|
|
||||||
// inside write-lock
|
|
||||||
// .............................................................................
|
|
||||||
|
|
||||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(document);
|
|
||||||
|
|
||||||
size_t const n = document->_allIndexes._length;
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
|
||||||
|
|
||||||
if (idx->_iid == iid) {
|
|
||||||
if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX ||
|
|
||||||
idx->_type == TRI_IDX_TYPE_EDGE_INDEX) {
|
|
||||||
// cannot remove these index types
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = static_cast<TRI_index_t*>(TRI_RemoveVectorPointer(&document->_allIndexes, i));
|
|
||||||
|
|
||||||
if (found != nullptr && found->removeIndex != nullptr) {
|
|
||||||
// notify the index about its removal
|
|
||||||
found->removeIndex(found, document);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RebuildIndexInfo(document);
|
|
||||||
|
|
||||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(document);
|
|
||||||
|
|
||||||
TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock);
|
|
||||||
|
|
||||||
// .............................................................................
|
|
||||||
// outside write-lock
|
|
||||||
// .............................................................................
|
|
||||||
|
|
||||||
if (found != nullptr) {
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if (full) {
|
|
||||||
result = TRI_RemoveIndexFile(document, found);
|
|
||||||
|
|
||||||
// it is safe to use _name as we hold a read-lock on the collection status
|
|
||||||
TRI_LogDropIndexReplication(vocbase,
|
|
||||||
document->_info._cid,
|
|
||||||
document->_info._name,
|
|
||||||
iid,
|
|
||||||
generatingServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_FreeIndex(found);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief initialises an index with all existing documents
|
/// @brief initialises an index with all existing documents
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -3124,31 +3011,20 @@ static TRI_index_t* LookupPathIndexDocumentCollection (TRI_document_collection_t
|
||||||
TRI_idx_type_e type,
|
TRI_idx_type_e type,
|
||||||
bool unique,
|
bool unique,
|
||||||
bool allowAnyAttributeOrder) {
|
bool allowAnyAttributeOrder) {
|
||||||
TRI_vector_t* indexPaths = NULL;
|
TRI_vector_t* indexPaths = nullptr;
|
||||||
size_t j;
|
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
// go through every index and see if we have a match
|
// go through every index and see if we have a match
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
for (j = 0; j < collection->_allIndexes._length; ++j) {
|
for (size_t j = 0; j < collection->_allIndexes._length; ++j) {
|
||||||
TRI_index_t* idx = static_cast<TRI_index_t*>(collection->_allIndexes._buffer[j]);
|
TRI_index_t* idx = static_cast<TRI_index_t*>(collection->_allIndexes._buffer[j]);
|
||||||
bool found;
|
|
||||||
size_t k;
|
|
||||||
|
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
// check if the type of the index matches
|
// check if the type of the index matches
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
|
|
||||||
if (idx->_type != type) {
|
if (idx->_type != type || idx->_unique != unique) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .........................................................................
|
|
||||||
// check if uniqueness matches
|
|
||||||
// .........................................................................
|
|
||||||
|
|
||||||
if (idx->_unique != unique) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3182,9 +3058,9 @@ static TRI_index_t* LookupPathIndexDocumentCollection (TRI_document_collection_t
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexPaths == NULL) {
|
if (indexPaths == nullptr) {
|
||||||
// this may actually happen if compiled with -DNDEBUG
|
// this may actually happen if compiled with -DNDEBUG
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
|
@ -3200,17 +3076,16 @@ static TRI_index_t* LookupPathIndexDocumentCollection (TRI_document_collection_t
|
||||||
// go through all the attributes and see if they match
|
// go through all the attributes and see if they match
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
|
|
||||||
found = true;
|
bool found = true;
|
||||||
|
|
||||||
if (allowAnyAttributeOrder) {
|
if (allowAnyAttributeOrder) {
|
||||||
// any permutation of attributes is allowed
|
// any permutation of attributes is allowed
|
||||||
for (k = 0; k < paths->_length; ++k) {
|
for (size_t k = 0; k < paths->_length; ++k) {
|
||||||
TRI_shape_pid_t indexShape = *((TRI_shape_pid_t*) TRI_AtVector(indexPaths, k));
|
TRI_shape_pid_t indexShape = *((TRI_shape_pid_t*) TRI_AtVector(indexPaths, k));
|
||||||
size_t l;
|
|
||||||
|
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
for (l = 0; l < paths->_length; ++l) {
|
for (size_t l = 0; l < paths->_length; ++l) {
|
||||||
TRI_shape_pid_t givenShape = *((TRI_shape_pid_t*) TRI_AtVector(paths, l));
|
TRI_shape_pid_t givenShape = *((TRI_shape_pid_t*) TRI_AtVector(paths, l));
|
||||||
|
|
||||||
if (indexShape == givenShape) {
|
if (indexShape == givenShape) {
|
||||||
|
@ -3226,7 +3101,7 @@ static TRI_index_t* LookupPathIndexDocumentCollection (TRI_document_collection_t
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// attributes need to present in a given order
|
// attributes need to present in a given order
|
||||||
for (k = 0; k < paths->_length; ++k) {
|
for (size_t k = 0; k < paths->_length; ++k) {
|
||||||
TRI_shape_pid_t indexShape = *((TRI_shape_pid_t*) TRI_AtVector(indexPaths, k));
|
TRI_shape_pid_t indexShape = *((TRI_shape_pid_t*) TRI_AtVector(indexPaths, k));
|
||||||
TRI_shape_pid_t givenShape = *((TRI_shape_pid_t*) TRI_AtVector(paths, k));
|
TRI_shape_pid_t givenShape = *((TRI_shape_pid_t*) TRI_AtVector(paths, k));
|
||||||
|
|
||||||
|
@ -3243,7 +3118,7 @@ static TRI_index_t* LookupPathIndexDocumentCollection (TRI_document_collection_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -3401,22 +3276,19 @@ static int PathBasedIndexFromJson (TRI_document_collection_t* document,
|
||||||
bool,
|
bool,
|
||||||
bool*),
|
bool*),
|
||||||
TRI_index_t** dst) {
|
TRI_index_t** dst) {
|
||||||
TRI_index_t* idx;
|
|
||||||
TRI_json_t* bv;
|
TRI_json_t* bv;
|
||||||
TRI_json_t* fld;
|
|
||||||
TRI_vector_pointer_t attributes;
|
TRI_vector_pointer_t attributes;
|
||||||
bool unique;
|
bool unique;
|
||||||
size_t fieldCount;
|
size_t fieldCount;
|
||||||
size_t j;
|
|
||||||
|
|
||||||
if (dst != NULL) {
|
if (dst != nullptr) {
|
||||||
*dst = NULL;
|
*dst = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract fields
|
// extract fields
|
||||||
fld = ExtractFields(definition, &fieldCount, iid);
|
TRI_json_t* fld = ExtractFields(definition, &fieldCount, iid);
|
||||||
|
|
||||||
if (fld == NULL) {
|
if (fld == nullptr) {
|
||||||
return TRI_errno();
|
return TRI_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3430,7 +3302,7 @@ static int PathBasedIndexFromJson (TRI_document_collection_t* document,
|
||||||
// determine if the hash index is unique or non-unique
|
// determine if the hash index is unique or non-unique
|
||||||
bv = TRI_LookupArrayJson(definition, "unique");
|
bv = TRI_LookupArrayJson(definition, "unique");
|
||||||
|
|
||||||
if (bv == NULL || bv->_type != TRI_JSON_BOOLEAN) {
|
if (! TRI_IsBooleanJson(bv)) {
|
||||||
LOG_ERROR("ignoring index %llu, could not determine if unique or non-unique", (unsigned long long) iid);
|
LOG_ERROR("ignoring index %llu, could not determine if unique or non-unique", (unsigned long long) iid);
|
||||||
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
@ -3442,24 +3314,24 @@ static int PathBasedIndexFromJson (TRI_document_collection_t* document,
|
||||||
TRI_InitVectorPointer(&attributes, TRI_CORE_MEM_ZONE);
|
TRI_InitVectorPointer(&attributes, TRI_CORE_MEM_ZONE);
|
||||||
|
|
||||||
// find fields
|
// find fields
|
||||||
for (j = 0; j < fieldCount; ++j) {
|
for (size_t j = 0; j < fieldCount; ++j) {
|
||||||
TRI_json_t* fieldStr = static_cast<TRI_json_t*>(TRI_AtVector(&fld->_value._objects, j));
|
TRI_json_t* fieldStr = static_cast<TRI_json_t*>(TRI_AtVector(&fld->_value._objects, j));
|
||||||
|
|
||||||
TRI_PushBackVectorPointer(&attributes, fieldStr->_value._string.data);
|
TRI_PushBackVectorPointer(&attributes, fieldStr->_value._string.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the index
|
// create the index
|
||||||
idx = creator(document, &attributes, iid, unique, NULL);
|
TRI_index_t* idx = creator(document, &attributes, iid, unique, nullptr);
|
||||||
|
|
||||||
if (dst != NULL) {
|
if (dst != nullptr) {
|
||||||
*dst = idx;
|
*dst = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
TRI_DestroyVectorPointer(&attributes);
|
TRI_DestroyVectorPointer(&attributes);
|
||||||
|
|
||||||
if (idx == NULL) {
|
if (idx == nullptr) {
|
||||||
LOG_ERROR("cannot create hash index %llu", (unsigned long long) iid);
|
LOG_ERROR("cannot create index %llu", (unsigned long long) iid);
|
||||||
return TRI_errno();
|
return TRI_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3544,17 +3416,87 @@ TRI_vector_pointer_t* TRI_IndexesDocumentCollection (TRI_document_collection_t*
|
||||||
bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document,
|
bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document,
|
||||||
TRI_idx_iid_t iid,
|
TRI_idx_iid_t iid,
|
||||||
TRI_server_id_t generatingServer) {
|
TRI_server_id_t generatingServer) {
|
||||||
return DropIndex(document, iid, generatingServer, true);
|
if (iid == 0) {
|
||||||
}
|
// invalid index id or primary index
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
TRI_index_t* found = nullptr;
|
||||||
/// @brief drops an index, without index file removal and replication
|
TRI_vocbase_t* vocbase = document->_vocbase;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool TRI_DropIndex2DocumentCollection (TRI_document_collection_t* document,
|
TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock);
|
||||||
TRI_idx_iid_t iid,
|
|
||||||
TRI_server_id_t generatingServer) {
|
// .............................................................................
|
||||||
return DropIndex(document, iid, generatingServer, false);
|
// inside write-lock
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(document);
|
||||||
|
|
||||||
|
size_t const n = document->_allIndexes._length;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
||||||
|
|
||||||
|
if (idx->_iid == iid) {
|
||||||
|
if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX ||
|
||||||
|
idx->_type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||||
|
// cannot remove these index types
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
found = static_cast<TRI_index_t*>(TRI_RemoveVectorPointer(&document->_allIndexes, i));
|
||||||
|
|
||||||
|
if (found != nullptr && found->removeIndex != nullptr) {
|
||||||
|
// notify the index about its removal
|
||||||
|
found->removeIndex(found, document);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found != nullptr) {
|
||||||
|
RebuildIndexInfo(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(document);
|
||||||
|
|
||||||
|
TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock);
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// outside write-lock
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
if (found != nullptr) {
|
||||||
|
bool result = TRI_RemoveIndexFile(document, found);
|
||||||
|
|
||||||
|
TRI_FreeIndex(found);
|
||||||
|
|
||||||
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
try {
|
||||||
|
triagens::wal::DropIndexMarker marker(vocbase->_id, document->_info._cid, iid);
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_WARNING("could not save index drop marker in log: %s", TRI_errno_string(res));
|
||||||
|
|
||||||
|
// TODO: what to do here?
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -3571,7 +3513,6 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||||
bool sorted,
|
bool sorted,
|
||||||
bool create) {
|
bool create) {
|
||||||
pid_name_t* pidnames;
|
pid_name_t* pidnames;
|
||||||
size_t j;
|
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// sorted case
|
// sorted case
|
||||||
|
@ -3586,7 +3527,7 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||||
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < attributes->_length; ++j) {
|
for (size_t j = 0; j < attributes->_length; ++j) {
|
||||||
pidnames[j]._name = static_cast<char*>(attributes->_buffer[j]);
|
pidnames[j]._name = static_cast<char*>(attributes->_buffer[j]);
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
|
@ -3610,7 +3551,7 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||||
TRI_InitVector(pids, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
TRI_InitVector(pids, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
||||||
TRI_InitVectorPointer(names, TRI_CORE_MEM_ZONE);
|
TRI_InitVectorPointer(names, TRI_CORE_MEM_ZONE);
|
||||||
|
|
||||||
for (j = 0; j < attributes->_length; ++j) {
|
for (size_t j = 0; j < attributes->_length; ++j) {
|
||||||
TRI_PushBackVector(pids, &pidnames[j]._pid);
|
TRI_PushBackVector(pids, &pidnames[j]._pid);
|
||||||
TRI_PushBackVectorPointer(names, pidnames[j]._name);
|
TRI_PushBackVectorPointer(names, pidnames[j]._name);
|
||||||
}
|
}
|
||||||
|
@ -3626,7 +3567,7 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||||
TRI_InitVector(pids, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
TRI_InitVector(pids, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
||||||
TRI_InitVectorPointer(names, TRI_CORE_MEM_ZONE);
|
TRI_InitVectorPointer(names, TRI_CORE_MEM_ZONE);
|
||||||
|
|
||||||
for (j = 0; j < attributes->_length; ++j) {
|
for (size_t j = 0; j < attributes->_length; ++j) {
|
||||||
char* name = static_cast<char*>(attributes->_buffer[j]);
|
char* name = static_cast<char*>(attributes->_buffer[j]);
|
||||||
|
|
||||||
TRI_shape_pid_t pid;
|
TRI_shape_pid_t pid;
|
||||||
|
@ -3732,34 +3673,29 @@ static int CapConstraintFromJson (TRI_document_collection_t* document,
|
||||||
TRI_json_t const* definition,
|
TRI_json_t const* definition,
|
||||||
TRI_idx_iid_t iid,
|
TRI_idx_iid_t iid,
|
||||||
TRI_index_t** dst) {
|
TRI_index_t** dst) {
|
||||||
TRI_json_t* val1;
|
|
||||||
TRI_json_t* val2;
|
|
||||||
TRI_index_t* idx;
|
TRI_index_t* idx;
|
||||||
size_t count;
|
|
||||||
int64_t size;
|
|
||||||
|
|
||||||
if (dst != NULL) {
|
if (dst != nullptr) {
|
||||||
*dst = NULL;
|
*dst = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
val1 = TRI_LookupArrayJson(definition, "size");
|
TRI_json_t* val1 = TRI_LookupArrayJson(definition, "size");
|
||||||
val2 = TRI_LookupArrayJson(definition, "byteSize");
|
TRI_json_t* val2 = TRI_LookupArrayJson(definition, "byteSize");
|
||||||
|
|
||||||
if ((val1 == NULL || val1->_type != TRI_JSON_NUMBER) &&
|
if (! TRI_IsNumberJson(val1) && ! TRI_IsNumberJson(val2)) {
|
||||||
(val2 == NULL || val2->_type != TRI_JSON_NUMBER)) {
|
|
||||||
LOG_ERROR("ignoring cap constraint %llu, 'size' and 'byteSize' missing",
|
LOG_ERROR("ignoring cap constraint %llu, 'size' and 'byteSize' missing",
|
||||||
(unsigned long long) iid);
|
(unsigned long long) iid);
|
||||||
|
|
||||||
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
size_t count = 0;
|
||||||
if (val1 != NULL && val1->_value._number > 0.0) {
|
if (TRI_IsNumberJson(val1) && val1->_value._number > 0.0) {
|
||||||
count = (size_t) val1->_value._number;
|
count = (size_t) val1->_value._number;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = 0;
|
int64_t size = 0;
|
||||||
if (val2 != NULL && val2->_value._number > (double) TRI_CAP_CONSTRAINT_MIN_SIZE) {
|
if (TRI_IsNumberJson(val2) && val2->_value._number > (double) TRI_CAP_CONSTRAINT_MIN_SIZE) {
|
||||||
size = (int64_t) val2->_value._number;
|
size = (int64_t) val2->_value._number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3772,12 +3708,12 @@ static int CapConstraintFromJson (TRI_document_collection_t* document,
|
||||||
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = CreateCapConstraintDocumentCollection(document, count, size, iid, NULL);
|
idx = CreateCapConstraintDocumentCollection(document, count, size, iid, nullptr);
|
||||||
if (dst != NULL) {
|
if (dst != nullptr) {
|
||||||
*dst = idx;
|
*dst = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx == NULL ? TRI_errno() : TRI_ERROR_NO_ERROR;
|
return idx == nullptr ? TRI_errno() : TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -771,14 +771,6 @@ bool TRI_DropIndexDocumentCollection (TRI_document_collection_t*,
|
||||||
TRI_idx_iid_t,
|
TRI_idx_iid_t,
|
||||||
TRI_server_id_t);
|
TRI_server_id_t);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief drops an index, without index file removal and replication
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool TRI_DropIndex2DocumentCollection (TRI_document_collection_t*,
|
|
||||||
TRI_idx_iid_t,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- CAP CONSTRAINT
|
// --SECTION-- CAP CONSTRAINT
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "BasicsC/tri-strings.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
#include "BasicsC/utf8-helper.h"
|
#include "BasicsC/utf8-helper.h"
|
||||||
#include "BasicsC/fasthash.h"
|
#include "BasicsC/fasthash.h"
|
||||||
#include "BasicsC/xxhash.h"
|
#include "Basics/JsonHelper.h"
|
||||||
#include "CapConstraint/cap-constraint.h"
|
#include "CapConstraint/cap-constraint.h"
|
||||||
#include "GeoIndex/geo-index.h"
|
#include "GeoIndex/geo-index.h"
|
||||||
#include "FulltextIndex/fulltext-index.h"
|
#include "FulltextIndex/fulltext-index.h"
|
||||||
|
@ -46,11 +46,14 @@
|
||||||
#include "HashIndex/hash-index.h"
|
#include "HashIndex/hash-index.h"
|
||||||
#include "ShapedJson/shape-accessor.h"
|
#include "ShapedJson/shape-accessor.h"
|
||||||
#include "ShapedJson/shaped-json.h"
|
#include "ShapedJson/shaped-json.h"
|
||||||
|
#include "Utils/Exception.h"
|
||||||
#include "VocBase/document-collection.h"
|
#include "VocBase/document-collection.h"
|
||||||
#include "VocBase/edge-collection.h"
|
#include "VocBase/edge-collection.h"
|
||||||
#include "VocBase/replication-logger.h"
|
#include "VocBase/replication-logger.h"
|
||||||
#include "VocBase/server.h"
|
#include "VocBase/server.h"
|
||||||
#include "VocBase/voc-shaper.h"
|
#include "VocBase/voc-shaper.h"
|
||||||
|
#include "Wal/LogfileManager.h"
|
||||||
|
#include "Wal/Marker.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- INDEX
|
// --SECTION-- INDEX
|
||||||
|
@ -117,8 +120,7 @@ bool TRI_NeedsFullCoverageIndex (TRI_idx_type_e type) {
|
||||||
case TRI_IDX_TYPE_CAP_CONSTRAINT:
|
case TRI_IDX_TYPE_CAP_CONSTRAINT:
|
||||||
return true;
|
return true;
|
||||||
case TRI_IDX_TYPE_BITARRAY_INDEX:
|
case TRI_IDX_TYPE_BITARRAY_INDEX:
|
||||||
return false;
|
case TRI_IDX_TYPE_PRIORITY_QUEUE_INDEX: // removed
|
||||||
case TRI_IDX_TYPE_PRIORITY_QUEUE_INDEX:
|
|
||||||
case TRI_IDX_TYPE_UNKNOWN:
|
case TRI_IDX_TYPE_UNKNOWN:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -317,23 +319,18 @@ void TRI_FreeIndex (TRI_index_t* idx) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool TRI_RemoveIndexFile (TRI_document_collection_t* collection, TRI_index_t* idx) {
|
bool TRI_RemoveIndexFile (TRI_document_collection_t* collection, TRI_index_t* idx) {
|
||||||
char* filename;
|
|
||||||
char* name;
|
|
||||||
char* number;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
// construct filename
|
// construct filename
|
||||||
number = TRI_StringUInt64(idx->_iid);
|
char* number = TRI_StringUInt64(idx->_iid);
|
||||||
|
|
||||||
if (number == NULL) {
|
if (number == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
LOG_ERROR("out of memory when creating index number");
|
LOG_ERROR("out of memory when creating index number");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = TRI_Concatenate3String("index-", number, ".json");
|
char* name = TRI_Concatenate3String("index-", number, ".json");
|
||||||
|
|
||||||
if (name == NULL) {
|
if (name == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
|
@ -341,9 +338,9 @@ bool TRI_RemoveIndexFile (TRI_document_collection_t* collection, TRI_index_t* id
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = TRI_Concatenate2File(collection->_directory, name);
|
char* filename = TRI_Concatenate2File(collection->_directory, name);
|
||||||
|
|
||||||
if (filename == NULL) {
|
if (filename == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
|
@ -355,7 +352,7 @@ bool TRI_RemoveIndexFile (TRI_document_collection_t* collection, TRI_index_t* id
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, name);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, name);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
|
|
||||||
res = TRI_UnlinkFile(filename);
|
int res = TRI_UnlinkFile(filename);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -373,33 +370,26 @@ bool TRI_RemoveIndexFile (TRI_document_collection_t* collection, TRI_index_t* id
|
||||||
int TRI_SaveIndex (TRI_document_collection_t* document,
|
int TRI_SaveIndex (TRI_document_collection_t* document,
|
||||||
TRI_index_t* idx,
|
TRI_index_t* idx,
|
||||||
TRI_server_id_t generatingServer) {
|
TRI_server_id_t generatingServer) {
|
||||||
TRI_json_t* json;
|
|
||||||
TRI_vocbase_t* vocbase;
|
|
||||||
char* filename;
|
|
||||||
char* name;
|
|
||||||
char* number;
|
|
||||||
bool ok;
|
|
||||||
|
|
||||||
// convert into JSON
|
// convert into JSON
|
||||||
json = idx->json(idx);
|
TRI_json_t* json = idx->json(idx);
|
||||||
|
|
||||||
if (json == NULL) {
|
if (json == nullptr) {
|
||||||
LOG_TRACE("cannot save index definition: index cannot be jsonified");
|
LOG_TRACE("cannot save index definition: index cannot be jsonified");
|
||||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct filename
|
// construct filename
|
||||||
number = TRI_StringUInt64(idx->_iid);
|
char* number = TRI_StringUInt64(idx->_iid);
|
||||||
name = TRI_Concatenate3String("index-", number, ".json");
|
char* name = TRI_Concatenate3String("index-", number, ".json");
|
||||||
filename = TRI_Concatenate2File(document->_directory, name);
|
char* filename = TRI_Concatenate2File(document->_directory, name);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, name);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, name);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
|
|
||||||
vocbase = document->_vocbase;
|
TRI_vocbase_t* vocbase = document->_vocbase;
|
||||||
|
|
||||||
// and save
|
// and save
|
||||||
ok = TRI_SaveJson(filename, json, vocbase->_settings.forceSyncProperties);
|
bool ok = TRI_SaveJson(filename, json, vocbase->_settings.forceSyncProperties);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||||
|
|
||||||
|
@ -410,16 +400,29 @@ int TRI_SaveIndex (TRI_document_collection_t* document,
|
||||||
return TRI_errno();
|
return TRI_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is safe to use _name as we hold a read-lock on the collection status
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
TRI_LogCreateIndexReplication(vocbase,
|
|
||||||
document->_info._cid,
|
try {
|
||||||
document->_info._name,
|
triagens::wal::CreateIndexMarker marker(vocbase->_id, document->_info._cid, idx->_iid, triagens::basics::JsonHelper::toString(json));
|
||||||
idx->_iid,
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
json,
|
|
||||||
generatingServer);
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
|
||||||
|
// TODO: what to do here?
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +432,9 @@ int TRI_SaveIndex (TRI_document_collection_t* document,
|
||||||
|
|
||||||
TRI_index_t* TRI_LookupIndex (TRI_document_collection_t* document,
|
TRI_index_t* TRI_LookupIndex (TRI_document_collection_t* document,
|
||||||
TRI_idx_iid_t iid) {
|
TRI_idx_iid_t iid) {
|
||||||
for (size_t i = 0; i < document->_allIndexes._length; ++i) {
|
size_t const n = document->_allIndexes._length;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
||||||
|
|
||||||
if (idx->_iid == iid) {
|
if (idx->_iid == iid) {
|
||||||
|
@ -439,7 +444,7 @@ TRI_index_t* TRI_LookupIndex (TRI_document_collection_t* document,
|
||||||
|
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_NO_INDEX);
|
TRI_set_errno(TRI_ERROR_ARANGO_NO_INDEX);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -454,7 +459,7 @@ TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone,
|
||||||
|
|
||||||
json = TRI_CreateArrayJson(zone);
|
json = TRI_CreateArrayJson(zone);
|
||||||
|
|
||||||
if (json != NULL) {
|
if (json != nullptr) {
|
||||||
char* number;
|
char* number;
|
||||||
|
|
||||||
number = TRI_StringUInt64(idx->_iid);
|
number = TRI_StringUInt64(idx->_iid);
|
||||||
|
@ -473,7 +478,7 @@ TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_DestroyIndexResult (TRI_index_result_t* result) {
|
void TRI_DestroyIndexResult (TRI_index_result_t* result) {
|
||||||
if (result->_documents != NULL) {
|
if (result->_documents != nullptr) {
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, result->_documents);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, result->_documents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,11 +488,9 @@ void TRI_DestroyIndexResult (TRI_index_result_t* result) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_CopyPathVector (TRI_vector_t* dst, TRI_vector_t* src) {
|
void TRI_CopyPathVector (TRI_vector_t* dst, TRI_vector_t* src) {
|
||||||
size_t j;
|
|
||||||
|
|
||||||
TRI_InitVector(dst, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
TRI_InitVector(dst, TRI_CORE_MEM_ZONE, sizeof(TRI_shape_pid_t));
|
||||||
|
|
||||||
for (j = 0; j < src->_length; ++j) {
|
for (size_t j = 0; j < src->_length; ++j) {
|
||||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(src,j)));
|
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(src,j)));
|
||||||
|
|
||||||
TRI_PushBackVector(dst, &shape);
|
TRI_PushBackVector(dst, &shape);
|
||||||
|
@ -517,10 +520,10 @@ char const** TRI_FieldListByPathList (TRI_shaper_t const* shaper,
|
||||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths, j)));
|
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths, j)));
|
||||||
TRI_shape_path_t const* path = shaper->lookupAttributePathByPid(const_cast<TRI_shaper_t*>(shaper), shape);
|
TRI_shape_path_t const* path = shaper->lookupAttributePathByPid(const_cast<TRI_shaper_t*>(shaper), shape);
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, (void*) fieldList);
|
TRI_Free(TRI_CORE_MEM_ZONE, (void*) fieldList);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldList[j] = ((const char*) path) + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t);
|
fieldList[j] = ((const char*) path) + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t);
|
||||||
|
@ -1056,9 +1059,7 @@ TRI_index_t* TRI_CreateEdgeIndex (TRI_document_collection_t* document,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_DestroyEdgeIndex (TRI_index_t* idx) {
|
void TRI_DestroyEdgeIndex (TRI_index_t* idx) {
|
||||||
TRI_edge_index_t* edgesIndex;
|
TRI_edge_index_t* edgesIndex = (TRI_edge_index_t*) idx;
|
||||||
|
|
||||||
edgesIndex = (TRI_edge_index_t*) idx;
|
|
||||||
|
|
||||||
LOG_TRACE("destroying edge index");
|
LOG_TRACE("destroying edge index");
|
||||||
|
|
||||||
|
@ -1121,7 +1122,7 @@ static int FillLookupSLOperator (TRI_index_operator_t* slOperator,
|
||||||
relationOperator->_numFields = relationOperator->_parameters->_value._objects._length;
|
relationOperator->_numFields = relationOperator->_parameters->_value._objects._length;
|
||||||
relationOperator->_fields = static_cast<TRI_shaped_json_t*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false));
|
relationOperator->_fields = static_cast<TRI_shaped_json_t*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false));
|
||||||
|
|
||||||
if (relationOperator->_fields != NULL) {
|
if (relationOperator->_fields != nullptr) {
|
||||||
for (size_t j = 0; j < relationOperator->_numFields; ++j) {
|
for (size_t j = 0; j < relationOperator->_numFields; ++j) {
|
||||||
TRI_json_t* jsonObject = (TRI_json_t*) TRI_AtVector(&(relationOperator->_parameters->_value._objects), j);
|
TRI_json_t* jsonObject = (TRI_json_t*) TRI_AtVector(&(relationOperator->_parameters->_value._objects), j);
|
||||||
|
|
||||||
|
@ -1133,7 +1134,7 @@ static int FillLookupSLOperator (TRI_index_operator_t* slOperator,
|
||||||
|
|
||||||
TRI_shaped_json_t* shapedObject = TRI_ShapedJsonJson(document->getShaper(), jsonObject, false, false); // ONLY IN INDEX, PROTECTED by RUNTIME
|
TRI_shaped_json_t* shapedObject = TRI_ShapedJsonJson(document->getShaper(), jsonObject, false, false); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||||
|
|
||||||
if (shapedObject != NULL) {
|
if (shapedObject != nullptr) {
|
||||||
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
||||||
}
|
}
|
||||||
|
@ -1212,7 +1213,7 @@ static int SkiplistIndexHelper (const TRI_skiplist_index_t* skiplistIndex,
|
||||||
TRI_shaped_json_t shapedJson;
|
TRI_shaped_json_t shapedJson;
|
||||||
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, document->getDataPtr()); // ONLY IN INDEX, PROTECTED by RUNTIME
|
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, document->getDataPtr()); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||||
|
|
||||||
if (shapedJson._sid == 0) {
|
if (shapedJson._sid == TRI_SHAPE_ILLEGAL) {
|
||||||
LOG_WARNING("encountered invalid marker with shape id 0");
|
LOG_WARNING("encountered invalid marker with shape id 0");
|
||||||
|
|
||||||
return TRI_ERROR_INTERNAL;
|
return TRI_ERROR_INTERNAL;
|
||||||
|
@ -1382,7 +1383,7 @@ static TRI_json_t* JsonSkiplistIndex (TRI_index_t const* idx) {
|
||||||
if (path == nullptr) {
|
if (path == nullptr) {
|
||||||
TRI_Free(TRI_CORE_MEM_ZONE, (void*) fieldList);
|
TRI_Free(TRI_CORE_MEM_ZONE, (void*) fieldList);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
fieldList[j] = ((const char*) path) + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t);
|
fieldList[j] = ((const char*) path) + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t);
|
||||||
}
|
}
|
||||||
|
@ -1970,14 +1971,14 @@ TRI_index_iterator_t* TRI_LookupBitarrayIndex (TRI_index_t* idx,
|
||||||
errorResult = FillLookupBitarrayOperator(indexOperator, baIndex->base._collection);
|
errorResult = FillLookupBitarrayOperator(indexOperator, baIndex->base._collection);
|
||||||
|
|
||||||
if (errorResult != TRI_ERROR_NO_ERROR) {
|
if (errorResult != TRI_ERROR_NO_ERROR) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
iteratorResult = BitarrayIndex_find(baIndex->_bitarrayIndex,
|
iteratorResult = BitarrayIndex_find(baIndex->_bitarrayIndex,
|
||||||
indexOperator,
|
indexOperator,
|
||||||
&baIndex->_paths,
|
&baIndex->_paths,
|
||||||
baIndex,
|
baIndex,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
TRI_FreeIndexOperator(indexOperator);
|
TRI_FreeIndexOperator(indexOperator);
|
||||||
|
|
||||||
|
|
|
@ -213,9 +213,10 @@ static void FreeCap (TRI_replication_logger_t* logger) {
|
||||||
TRI_document_collection_t* document = logger->_trxCollection->_collection->_collection;
|
TRI_document_collection_t* document = logger->_trxCollection->_collection->_collection;
|
||||||
TRI_ASSERT(document != NULL);
|
TRI_ASSERT(document != NULL);
|
||||||
|
|
||||||
TRI_DropIndex2DocumentCollection(document,
|
// TODO: this wont work anymore - remove function altogether
|
||||||
logger->_cap->_iid,
|
TRI_DropIndexDocumentCollection(document,
|
||||||
TRI_GetIdServer());
|
logger->_cap->_iid,
|
||||||
|
TRI_GetIdServer());
|
||||||
|
|
||||||
logger->_cap = NULL;
|
logger->_cap = NULL;
|
||||||
}
|
}
|
||||||
|
@ -468,26 +469,6 @@ static int LogEvent (TRI_replication_logger_t* logger,
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a collection context
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyCollection (TRI_string_buffer_t* buffer,
|
|
||||||
const TRI_voc_cid_t cid,
|
|
||||||
char const* name) {
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_STRING(buffer, "\"cid\":\"");
|
|
||||||
APPEND_UINT64(buffer, (uint64_t) cid);
|
|
||||||
APPEND_STRING(buffer, "\",\"cname\":\"");
|
|
||||||
APPEND_STRING(buffer, name);
|
|
||||||
APPEND_CHAR(buffer, '"');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief stringify a "replication" operation with a tick
|
/// @brief stringify a "replication" operation with a tick
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -505,128 +486,6 @@ static bool StringifyTickReplication (TRI_string_buffer_t* buffer,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a "create collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyCreateCollection (TRI_string_buffer_t* buffer,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_json_t const* json) {
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_STRING(buffer, "{\"cid\":\"");
|
|
||||||
APPEND_UINT64(buffer, (uint64_t) cid);
|
|
||||||
APPEND_STRING(buffer, "\",\"cname\":\"");
|
|
||||||
APPEND_STRING(buffer, name);
|
|
||||||
APPEND_STRING(buffer, "\",\"collection\":");
|
|
||||||
APPEND_JSON(buffer, json);
|
|
||||||
APPEND_CHAR(buffer, '}');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a "drop collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyDropCollection (TRI_string_buffer_t* buffer,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name) {
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_CHAR(buffer, '{');
|
|
||||||
|
|
||||||
if (! StringifyCollection(buffer, cid, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_CHAR(buffer, '}');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a "rename collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyRenameCollection (TRI_string_buffer_t* buffer,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
char const* newName) {
|
|
||||||
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_CHAR(buffer, '{');
|
|
||||||
|
|
||||||
if (! StringifyCollection(buffer, cid, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_STRING(buffer, ",\"collection\":{\"name\":\"");
|
|
||||||
// name is user-defined, but does not need escaping as collection names are "safe"
|
|
||||||
APPEND_STRING(buffer, newName);
|
|
||||||
APPEND_STRING(buffer, "\"}}");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a "create index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyCreateIndex (TRI_string_buffer_t* buffer,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_json_t const* json) {
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_CHAR(buffer, '{');
|
|
||||||
|
|
||||||
if (! StringifyCollection(buffer, cid, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_STRING(buffer, ",\"index\":");
|
|
||||||
APPEND_JSON(buffer, json);
|
|
||||||
APPEND_CHAR(buffer, '}');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief stringify a "drop index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool StringifyDropIndex (TRI_string_buffer_t* buffer,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_idx_iid_t iid) {
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_CHAR(buffer, '{');
|
|
||||||
|
|
||||||
if (! StringifyCollection(buffer, cid, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APPEND_STRING(buffer, ",\"id\":\"");
|
|
||||||
APPEND_UINT64(buffer, (uint64_t) iid);
|
|
||||||
APPEND_STRING(buffer, "\"}");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get current state from the replication logger
|
/// @brief get current state from the replication logger
|
||||||
/// note: must hold the lock when calling this
|
/// note: must hold the lock when calling this
|
||||||
|
@ -911,37 +770,6 @@ static int InitBuffers (TRI_replication_logger_t* logger) {
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief lock the logger and check for inclusion of an event
|
|
||||||
/// if this function returns true, it has acquired a read-lock that the caller
|
|
||||||
/// must unlock!
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool CheckAndLock (TRI_replication_logger_t* logger,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
// acquire read-lock
|
|
||||||
TRI_ReadLockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
if (! logger->_state._active) {
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (generatingServer != 0 &&
|
|
||||||
generatingServer != logger->_localServerId &&
|
|
||||||
! logger->_configuration._logRemoteChanges) {
|
|
||||||
// read-unlock the read-lock
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we'll keep the lock!!
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the filename of the replication logger configuration file
|
/// @brief get the filename of the replication logger configuration file
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1448,262 +1276,6 @@ TRI_json_t* TRI_JsonReplicationLogger (TRI_replication_logger_t* logger) {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- public log functions
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "create collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogCreateCollectionReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_json_t const* json,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(name)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyCreateCollection(buffer, cid, name, json)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, COLLECTION_CREATE, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "drop collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogDropCollectionReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(name)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyDropCollection(buffer, cid, name)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, COLLECTION_DROP, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "rename collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogRenameCollectionReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* oldName,
|
|
||||||
char const* newName,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(oldName)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyRenameCollection(buffer, cid, oldName, newName)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, COLLECTION_RENAME, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "change collection properties" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogChangePropertiesCollectionReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_json_t const* json,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(name)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyCreateCollection(buffer, cid, name, json)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, COLLECTION_CHANGE, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "create index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogCreateIndexReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_idx_iid_t iid,
|
|
||||||
TRI_json_t const* json,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(name)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyCreateIndex(buffer, cid, name, json)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, INDEX_CREATE, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "drop index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogDropIndexReplication (TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
char const* name,
|
|
||||||
TRI_idx_iid_t iid,
|
|
||||||
TRI_server_id_t generatingServer) {
|
|
||||||
TRI_string_buffer_t* buffer;
|
|
||||||
TRI_replication_logger_t* logger;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (TRI_ExcludeCollectionReplication(name)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = vocbase->_replicationLogger;
|
|
||||||
|
|
||||||
if (! CheckAndLock(logger, generatingServer)) {
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = GetBuffer(logger);
|
|
||||||
|
|
||||||
if (! StringifyDropIndex(buffer, cid, name, iid)) {
|
|
||||||
ReturnBuffer(logger, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LogEvent(logger, 0, true, INDEX_DROP, buffer);
|
|
||||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: outline-minor
|
// mode: outline-minor
|
||||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||||
|
|
|
@ -199,70 +199,6 @@ struct TRI_json_s* TRI_JsonStateReplicationLogger (TRI_replication_logger_state_
|
||||||
|
|
||||||
struct TRI_json_s* TRI_JsonReplicationLogger (TRI_replication_logger_t*);
|
struct TRI_json_s* TRI_JsonReplicationLogger (TRI_replication_logger_t*);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- public log functions
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "create collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogCreateCollectionReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
struct TRI_json_s const*,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "drop collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogDropCollectionReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "rename collection" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogRenameCollectionReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
char const*,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "change collection properties" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogChangePropertiesCollectionReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
struct TRI_json_s const*,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "create index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogCreateIndexReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
TRI_idx_iid_t,
|
|
||||||
struct TRI_json_s const*,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief replicate a "drop index" operation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_LogDropIndexReplication (struct TRI_vocbase_s*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
char const*,
|
|
||||||
TRI_idx_iid_t iid,
|
|
||||||
TRI_server_id_t);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "BasicsC/logging.h"
|
#include "BasicsC/logging.h"
|
||||||
#include "BasicsC/tri-strings.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
#include "BasicsC/utf8-helper.h"
|
#include "BasicsC/utf8-helper.h"
|
||||||
|
#include "Utils/Exception.h"
|
||||||
#include "VocBase/document-collection.h"
|
#include "VocBase/document-collection.h"
|
||||||
#include "Wal/LogfileManager.h"
|
#include "Wal/LogfileManager.h"
|
||||||
|
|
||||||
|
@ -178,36 +179,50 @@ static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
|
||||||
|
|
||||||
TRI_document_collection_t* document = s->_collection;
|
TRI_document_collection_t* document = s->_collection;
|
||||||
|
|
||||||
triagens::wal::AttributeMarker marker(document->_vocbase->_id, document->_info._cid, aid, std::string(name));
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
try {
|
||||||
|
triagens::wal::AttributeMarker marker(document->_vocbase->_id, document->_info._cid, aid, std::string(name));
|
||||||
|
|
||||||
// lock the index and check that the element is still missing
|
// lock the index and check that the element is still missing
|
||||||
{
|
{
|
||||||
MUTEX_LOCKER(s->_attributeLock);
|
MUTEX_LOCKER(s->_attributeLock);
|
||||||
|
|
||||||
void const* p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
void const* p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
||||||
|
|
||||||
// if the element appeared, return the aid
|
// if the element appeared, return the aid
|
||||||
if (p != nullptr) {
|
if (p != nullptr) {
|
||||||
return GetAttributeId(p);
|
return GetAttributeId(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write marker into wal
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
// throw an exception which is caught at the end of this function
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, const_cast<void*>(slotInfo.mem), false);
|
||||||
|
TRI_ASSERT(f == nullptr);
|
||||||
|
|
||||||
|
// enter into the dictionaries
|
||||||
|
f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, const_cast<void*>(slotInfo.mem), false);
|
||||||
|
TRI_ASSERT(f == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write marker into wal
|
return aid;
|
||||||
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker.mem(), marker.size(), false);
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
res = ex.code();
|
||||||
LOG_WARNING("could not save attribute marker in log: %s", TRI_errno_string(slotInfo.errorCode));
|
}
|
||||||
return 0;
|
catch (...) {
|
||||||
}
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
|
||||||
void* f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, const_cast<void*>(slotInfo.mem), false);
|
|
||||||
TRI_ASSERT(f == nullptr);
|
|
||||||
|
|
||||||
// enter into the dictionaries
|
|
||||||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, const_cast<void*>(slotInfo.mem), false);
|
|
||||||
TRI_ASSERT(f == nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return aid;
|
LOG_WARNING("could not save attribute marker in log: %s", TRI_errno_string(res));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -321,15 +336,15 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
||||||
// get next shape id
|
// get next shape id
|
||||||
TRI_shape_sid_t const sid = s->_nextSid++;
|
TRI_shape_sid_t const sid = s->_nextSid++;
|
||||||
shape->_sid = sid;
|
shape->_sid = sid;
|
||||||
|
|
||||||
TRI_document_collection_t* document = s->_collection;
|
|
||||||
triagens::wal::ShapeMarker marker(document->_vocbase->_id, document->_info._cid, shape);
|
|
||||||
|
|
||||||
|
TRI_document_collection_t* document = s->_collection;
|
||||||
|
|
||||||
TRI_shape_t const* result;
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
// lock the index and check the element is still missing
|
try {
|
||||||
{
|
triagens::wal::ShapeMarker marker(document->_vocbase->_id, document->_info._cid, shape);
|
||||||
|
|
||||||
|
// lock the index and check the element is still missing
|
||||||
MUTEX_LOCKER(s->_shapeLock);
|
MUTEX_LOCKER(s->_shapeLock);
|
||||||
|
|
||||||
found = static_cast<TRI_shape_t const*>(TRI_LookupByElementAssociativeSynced(&s->_shapeDictionary, shape));
|
found = static_cast<TRI_shape_t const*>(TRI_LookupByElementAssociativeSynced(&s->_shapeDictionary, shape));
|
||||||
|
@ -341,26 +356,35 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
||||||
}
|
}
|
||||||
|
|
||||||
// write marker into wal
|
// write marker into wal
|
||||||
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker.mem(), marker.size(), false);
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
LOG_WARNING("could not save shape marker in log: %s", TRI_errno_string(slotInfo.errorCode));
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* m = static_cast<char const*>(slotInfo.mem) + sizeof(triagens::wal::shape_marker_t);
|
char const* m = static_cast<char const*>(slotInfo.mem) + sizeof(triagens::wal::shape_marker_t);
|
||||||
result = reinterpret_cast<TRI_shape_t const*>(m);
|
TRI_shape_t const* result = reinterpret_cast<TRI_shape_t const*>(m);
|
||||||
|
|
||||||
void* f = TRI_InsertKeyAssociativeSynced(&s->_shapeIds, &sid, (void*) m, false);
|
void* f = TRI_InsertKeyAssociativeSynced(&s->_shapeIds, &sid, (void*) m, false);
|
||||||
TRI_ASSERT(f == nullptr);
|
TRI_ASSERT(f == nullptr);
|
||||||
|
|
||||||
f = TRI_InsertElementAssociativeSynced(&s->_shapeDictionary, (void*) m, false);
|
f = TRI_InsertElementAssociativeSynced(&s->_shapeDictionary, (void*) m, false);
|
||||||
TRI_ASSERT(f == nullptr);
|
TRI_ASSERT(f == nullptr);
|
||||||
|
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||||
|
LOG_WARNING("could not save shape marker in log: %s", TRI_errno_string(res));
|
||||||
|
|
||||||
return result;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "BasicsC/tri-strings.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
#include "BasicsC/threads.h"
|
#include "BasicsC/threads.h"
|
||||||
|
|
||||||
|
#include "Utils/Exception.h"
|
||||||
#include "Utils/transactions.h"
|
#include "Utils/transactions.h"
|
||||||
#include "VocBase/auth.h"
|
#include "VocBase/auth.h"
|
||||||
#include "VocBase/barrier.h"
|
#include "VocBase/barrier.h"
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
#include "VocBase/server.h"
|
#include "VocBase/server.h"
|
||||||
#include "VocBase/transaction.h"
|
#include "VocBase/transaction.h"
|
||||||
#include "VocBase/vocbase-defaults.h"
|
#include "VocBase/vocbase-defaults.h"
|
||||||
|
#include "Wal/LogfileManager.h"
|
||||||
|
|
||||||
#include "Ahuacatl/ahuacatl-functions.h"
|
#include "Ahuacatl/ahuacatl-functions.h"
|
||||||
|
|
||||||
|
@ -187,15 +189,32 @@ static bool UnregisterCollection (TRI_vocbase_t* vocbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
// post-condition
|
// post-condition
|
||||||
TRI_ASSERT(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
TRI_ASSERT_EXPENSIVE(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
||||||
|
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
TRI_LogDropCollectionReplication(vocbase,
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
collection->_cid,
|
|
||||||
collection->_name,
|
|
||||||
generatingServer);
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
triagens::wal::DropCollectionMarker marker(vocbase->_id, collection->_cid);
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_WARNING("could not save collection drop marker in log: %s", TRI_errno_string(res));
|
||||||
|
|
||||||
|
// TODO: what to do here
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,9 +462,6 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
char const* name,
|
char const* name,
|
||||||
TRI_voc_cid_t cid,
|
TRI_voc_cid_t cid,
|
||||||
char const* path) {
|
char const* path) {
|
||||||
void const* found;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
// create the init object
|
// create the init object
|
||||||
TRI_vocbase_col_t init;
|
TRI_vocbase_col_t init;
|
||||||
|
|
||||||
|
@ -455,7 +471,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
init._type = static_cast<TRI_col_type_t>(type);
|
init._type = static_cast<TRI_col_type_t>(type);
|
||||||
|
|
||||||
init._status = TRI_VOC_COL_STATUS_CORRUPTED;
|
init._status = TRI_VOC_COL_STATUS_CORRUPTED;
|
||||||
init._collection = NULL;
|
init._collection = nullptr;
|
||||||
|
|
||||||
// default flags: everything is allowed
|
// default flags: everything is allowed
|
||||||
init._canDrop = true;
|
init._canDrop = true;
|
||||||
|
@ -481,7 +497,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_CopyString(init._dbName, vocbase->_name, strlen(vocbase->_name));
|
TRI_CopyString(init._dbName, vocbase->_name, strlen(vocbase->_name));
|
||||||
TRI_CopyString(init._name, name, sizeof(init._name) - 1);
|
TRI_CopyString(init._name, name, sizeof(init._name) - 1);
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == nullptr) {
|
||||||
init._path[0] = '\0';
|
init._path[0] = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -491,18 +507,19 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
// create a new proxy
|
// create a new proxy
|
||||||
TRI_vocbase_col_t* collection = static_cast<TRI_vocbase_col_t*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_vocbase_col_t), false));
|
TRI_vocbase_col_t* collection = static_cast<TRI_vocbase_col_t*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_vocbase_col_t), false));
|
||||||
|
|
||||||
if (collection == NULL) {
|
if (collection == nullptr) {
|
||||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(collection, &init, sizeof(TRI_vocbase_col_t));
|
memcpy(collection, &init, sizeof(TRI_vocbase_col_t));
|
||||||
collection->_isLocal = true;
|
collection->_isLocal = true;
|
||||||
|
|
||||||
// check name
|
// check name
|
||||||
res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsByName, name, collection, &found);
|
void const* found;
|
||||||
|
int res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsByName, name, collection, &found);
|
||||||
|
|
||||||
if (found != NULL) {
|
if (found != nullptr) {
|
||||||
LOG_ERROR("duplicate entry for collection name '%s'", name);
|
LOG_ERROR("duplicate entry for collection name '%s'", name);
|
||||||
LOG_ERROR("collection id %llu has same name as already added collection %llu",
|
LOG_ERROR("collection id %llu has same name as already added collection %llu",
|
||||||
(unsigned long long) cid,
|
(unsigned long long) cid,
|
||||||
|
@ -511,7 +528,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -520,14 +537,14 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
||||||
TRI_set_errno(res);
|
TRI_set_errno(res);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check collection identifier
|
// check collection identifier
|
||||||
TRI_ASSERT(collection->_cid == cid);
|
TRI_ASSERT(collection->_cid == cid);
|
||||||
res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsById, &cid, collection, &found);
|
res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsById, &cid, collection, &found);
|
||||||
|
|
||||||
if (found != NULL) {
|
if (found != nullptr) {
|
||||||
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||||
|
|
||||||
LOG_ERROR("duplicate collection identifier %llu for name '%s'",
|
LOG_ERROR("duplicate collection identifier %llu for name '%s'",
|
||||||
|
@ -536,7 +553,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_IDENTIFIER);
|
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_IDENTIFIER);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -546,10 +563,10 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
||||||
TRI_set_errno(res);
|
TRI_set_errno(res);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
TRI_ASSERT_EXPENSIVE(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
||||||
|
|
||||||
TRI_InitReadWriteLock(&collection->_lock);
|
TRI_InitReadWriteLock(&collection->_lock);
|
||||||
|
|
||||||
|
@ -566,13 +583,7 @@ static TRI_vocbase_col_t* CreateCollection (TRI_vocbase_t* vocbase,
|
||||||
TRI_col_info_t* parameter,
|
TRI_col_info_t* parameter,
|
||||||
TRI_voc_cid_t cid,
|
TRI_voc_cid_t cid,
|
||||||
TRI_server_id_t generatingServer) {
|
TRI_server_id_t generatingServer) {
|
||||||
TRI_vocbase_col_t* collection;
|
char const* name = parameter->_name;
|
||||||
TRI_collection_t* col;
|
|
||||||
TRI_json_t* json;
|
|
||||||
char const* name;
|
|
||||||
void const* found;
|
|
||||||
|
|
||||||
name = parameter->_name;
|
|
||||||
|
|
||||||
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
|
@ -580,15 +591,15 @@ static TRI_vocbase_col_t* CreateCollection (TRI_vocbase_t* vocbase,
|
||||||
// check that we have a new name
|
// check that we have a new name
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
void const* found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
|
||||||
|
|
||||||
if (found != NULL) {
|
if (found != nullptr) {
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
LOG_DEBUG("collection named '%s' already exists", name);
|
LOG_DEBUG("collection named '%s' already exists", name);
|
||||||
|
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
@ -597,20 +608,20 @@ static TRI_vocbase_col_t* CreateCollection (TRI_vocbase_t* vocbase,
|
||||||
|
|
||||||
TRI_document_collection_t* document = TRI_CreateDocumentCollection(vocbase, vocbase->_path, parameter, cid);
|
TRI_document_collection_t* document = TRI_CreateDocumentCollection(vocbase, vocbase->_path, parameter, cid);
|
||||||
|
|
||||||
if (document == NULL) {
|
if (document == nullptr) {
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
col = document;
|
TRI_collection_t* col = document;
|
||||||
|
|
||||||
// add collection container
|
// add collection container
|
||||||
collection = AddCollection(vocbase,
|
TRI_vocbase_col_t* collection = AddCollection(vocbase,
|
||||||
col->_info._type,
|
col->_info._type,
|
||||||
col->_info._name,
|
col->_info._name,
|
||||||
col->_info._cid,
|
col->_info._cid,
|
||||||
col->_directory);
|
col->_directory);
|
||||||
|
|
||||||
if (collection == nullptr) {
|
if (collection == nullptr) {
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
@ -635,19 +646,35 @@ static TRI_vocbase_col_t* CreateCollection (TRI_vocbase_t* vocbase,
|
||||||
document->_directory,
|
document->_directory,
|
||||||
sizeof(collection->_path) - 1);
|
sizeof(collection->_path) - 1);
|
||||||
|
|
||||||
json = TRI_CreateJsonCollectionInfo(&col->_info);
|
TRI_json_t* json = TRI_CreateJsonCollectionInfo(&col->_info);
|
||||||
|
|
||||||
// release the lock on the list of collections
|
// release the lock on the list of collections
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
// replicate and finally unlock the collection
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
TRI_LogCreateCollectionReplication(vocbase,
|
|
||||||
cid,
|
|
||||||
name,
|
|
||||||
json,
|
|
||||||
generatingServer);
|
|
||||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
triagens::wal::CreateCollectionMarker marker(vocbase->_id, cid, triagens::basics::JsonHelper::toString(json));
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
LOG_WARNING("could not save collection create marker in log: %s", TRI_errno_string(res));
|
||||||
|
|
||||||
|
// TODO: what to do here?
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,7 +715,7 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
|
||||||
// check if the new name is unused
|
// check if the new name is unused
|
||||||
found = (void*) TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
found = (void*) TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, newName);
|
||||||
|
|
||||||
if (found != NULL) {
|
if (found != nullptr) {
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||||
|
|
||||||
|
@ -761,18 +788,39 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
|
||||||
|
|
||||||
// this shouldn't fail, as we removed an element above so adding one should be ok
|
// this shouldn't fail, as we removed an element above so adding one should be ok
|
||||||
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, CONST_CAST(collection), false);
|
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, CONST_CAST(collection), false);
|
||||||
TRI_ASSERT(found == NULL);
|
TRI_ASSERT(found == nullptr);
|
||||||
|
|
||||||
TRI_ASSERT(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
TRI_ASSERT_EXPENSIVE(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
|
||||||
|
|
||||||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||||
|
|
||||||
// stay inside the outer lock to protect against unloading
|
|
||||||
TRI_LogRenameCollectionReplication(vocbase, collection->_cid, oldName, newName, generatingServer);
|
|
||||||
|
|
||||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
// now log the operation
|
||||||
|
res = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
try {
|
||||||
|
triagens::wal::RenameCollectionMarker marker(vocbase->_id, collection->_cid, std::string(newName));
|
||||||
|
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||||
|
|
||||||
|
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
catch (triagens::arango::Exception const& ex) {
|
||||||
|
res = ex.code();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG_WARNING("could not save collection rename marker in log: %s", TRI_errno_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1913,25 +1961,21 @@ TRI_vocbase_col_t* TRI_FindCollectionByNameOrCreateVocBase (TRI_vocbase_t* vocba
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase,
|
TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase,
|
||||||
TRI_col_info_t* parameter,
|
TRI_col_info_t* parameters,
|
||||||
TRI_voc_cid_t cid,
|
TRI_voc_cid_t cid,
|
||||||
TRI_server_id_t generatingServer) {
|
TRI_server_id_t generatingServer) {
|
||||||
TRI_vocbase_col_t* collection;
|
TRI_ASSERT(parameters != nullptr);
|
||||||
char* name;
|
|
||||||
|
|
||||||
TRI_ASSERT(parameter != NULL);
|
|
||||||
name = parameter->_name;
|
|
||||||
|
|
||||||
// check that the name does not contain any strange characters
|
// check that the name does not contain any strange characters
|
||||||
if (! TRI_IsAllowedNameCollection(parameter->_isSystem, name)) {
|
if (! TRI_IsAllowedNameCollection(parameters->_isSystem, parameters->_name)) {
|
||||||
TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
|
TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock);
|
TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock);
|
||||||
|
|
||||||
collection = CreateCollection(vocbase, parameter, cid, generatingServer);
|
TRI_vocbase_col_t* collection = CreateCollection(vocbase, parameters, cid, generatingServer);
|
||||||
|
|
||||||
TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock);
|
TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock);
|
||||||
|
|
||||||
|
|
|
@ -739,6 +739,16 @@ SlotInfoCopy LogfileManager::allocateAndWrite (void* src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief write data into the logfile
|
||||||
|
/// this is a convenience function that combines allocate, memcpy and finalise
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SlotInfoCopy LogfileManager::allocateAndWrite (Marker const& marker,
|
||||||
|
bool waitForSync) {
|
||||||
|
return allocateAndWrite(marker.mem(), marker.size(), waitForSync);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set all open logfiles to status sealed
|
/// @brief set all open logfiles to status sealed
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -295,6 +295,14 @@ struct RecoverState {
|
||||||
uint32_t,
|
uint32_t,
|
||||||
bool);
|
bool);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief write data into the logfile
|
||||||
|
/// this is a convenience function that combines allocate, memcpy and finalise
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SlotInfoCopy allocateAndWrite (Marker const&,
|
||||||
|
bool);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set all open logfiles to status sealed
|
/// @brief set all open logfiles to status sealed
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -583,6 +583,120 @@ void ChangeCollectionMarker::dump () const {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- CreateIndexMarker
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- constructors and destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CreateIndexMarker::CreateIndexMarker (TRI_voc_tick_t databaseId,
|
||||||
|
TRI_voc_cid_t collectionId,
|
||||||
|
TRI_idx_iid_t indexId,
|
||||||
|
string const& properties)
|
||||||
|
: Marker(TRI_WAL_MARKER_CREATE_INDEX, sizeof(index_create_marker_t) + alignedSize(properties.size() + 1)) {
|
||||||
|
|
||||||
|
index_create_marker_t* m = reinterpret_cast<index_create_marker_t*>(begin());
|
||||||
|
|
||||||
|
m->_databaseId = databaseId;
|
||||||
|
m->_collectionId = collectionId;
|
||||||
|
m->_indexId = indexId;
|
||||||
|
|
||||||
|
storeSizedString(sizeof(index_create_marker_t), properties);
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL
|
||||||
|
dump();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroy marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CreateIndexMarker::~CreateIndexMarker () {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief dump marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL
|
||||||
|
void CreateIndexMarker::dump () const {
|
||||||
|
index_create_marker_t* m = reinterpret_cast<index_create_marker_t*>(begin());
|
||||||
|
|
||||||
|
std::cout << "WAL CREATE INDEX MARKER FOR DB " << m->_databaseId
|
||||||
|
<< ", COLLECTION " << m->_collectionId
|
||||||
|
<< ", INDEX " << m->_indexId
|
||||||
|
<< ", PROPERTIES " << properties()
|
||||||
|
<< ", SIZE: " << size()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL_DETAIL
|
||||||
|
dumpBinary();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- DropIndexMarker
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- constructors and destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DropIndexMarker::DropIndexMarker (TRI_voc_tick_t databaseId,
|
||||||
|
TRI_voc_cid_t collectionId,
|
||||||
|
TRI_idx_iid_t indexId)
|
||||||
|
: Marker(TRI_WAL_MARKER_DROP_INDEX, sizeof(index_drop_marker_t)) {
|
||||||
|
|
||||||
|
index_drop_marker_t* m = reinterpret_cast<index_drop_marker_t*>(begin());
|
||||||
|
|
||||||
|
m->_databaseId = databaseId;
|
||||||
|
m->_collectionId = collectionId;
|
||||||
|
m->_indexId = indexId;
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL
|
||||||
|
dump();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroy marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DropIndexMarker::~DropIndexMarker () {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief dump marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL
|
||||||
|
void DropIndexMarker::dump () const {
|
||||||
|
index_drop_marker_t* m = reinterpret_cast<index_drop_marker_t*>(begin());
|
||||||
|
|
||||||
|
std::cout << "WAL DROP INDEX MARKER FOR DB " << m->_databaseId
|
||||||
|
<< ", COLLECTION " << m->_collectionId
|
||||||
|
<< ", INDEX " << m->_indexId
|
||||||
|
<< ", SIZE: " << size()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
#ifdef DEBUG_WAL_DETAIL
|
||||||
|
dumpBinary();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- BeginTransactionMarker
|
// --SECTION-- BeginTransactionMarker
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -807,7 +921,7 @@ void DocumentMarker::dump () const {
|
||||||
|
|
||||||
std::cout << "WAL DOCUMENT MARKER FOR DB " << m->_databaseId
|
std::cout << "WAL DOCUMENT MARKER FOR DB " << m->_databaseId
|
||||||
<< ", COLLECTION " << m->_collectionId
|
<< ", COLLECTION " << m->_collectionId
|
||||||
<< ", REV: " << m->_rid
|
<< ", REV: " << m->_revisionId
|
||||||
<< ", TRX: " << m->_transactionId
|
<< ", TRX: " << m->_transactionId
|
||||||
<< ", KEY: " << key()
|
<< ", KEY: " << key()
|
||||||
<< ", OFFSETKEY: " << m->_offsetKey
|
<< ", OFFSETKEY: " << m->_offsetKey
|
||||||
|
@ -946,8 +1060,8 @@ void EdgeMarker::dump () const {
|
||||||
|
|
||||||
std::cout << "WAL EDGE MARKER FOR DB " << m->_databaseId
|
std::cout << "WAL EDGE MARKER FOR DB " << m->_databaseId
|
||||||
<< ", COLLECTION " << m->_collectionId
|
<< ", COLLECTION " << m->_collectionId
|
||||||
<< ", REV: " << rid()
|
<< ", REV: " << m->_revisionId
|
||||||
<< ", TRX: " << tid()
|
<< ", TRX: " << m->_transactionId
|
||||||
<< ", KEY: " << key()
|
<< ", KEY: " << key()
|
||||||
<< ", FROMCID " << m->_fromCid
|
<< ", FROMCID " << m->_fromCid
|
||||||
<< ", TOCID " << m->_toCid
|
<< ", TOCID " << m->_toCid
|
||||||
|
@ -1076,7 +1190,7 @@ void RemoveMarker::dump () const {
|
||||||
|
|
||||||
std::cout << "WAL REMOVE MARKER FOR DB " << m->_databaseId
|
std::cout << "WAL REMOVE MARKER FOR DB " << m->_databaseId
|
||||||
<< ", COLLECTION " << m->_collectionId
|
<< ", COLLECTION " << m->_collectionId
|
||||||
<< ", REV: " << m->_rid
|
<< ", REV: " << m->_revisionId
|
||||||
<< ", TRX: " << m->_transactionId
|
<< ", TRX: " << m->_transactionId
|
||||||
<< ", KEY: " << key()
|
<< ", KEY: " << key()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
|
@ -123,6 +123,27 @@ namespace triagens {
|
||||||
// char* properties
|
// char* properties
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief wal create index marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct index_create_marker_t : TRI_df_marker_t {
|
||||||
|
TRI_voc_tick_t _databaseId;
|
||||||
|
TRI_voc_cid_t _collectionId;
|
||||||
|
TRI_idx_iid_t _indexId;
|
||||||
|
// char* properties
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief wal drop index marker
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct index_drop_marker_t : TRI_df_marker_t {
|
||||||
|
TRI_voc_tick_t _databaseId;
|
||||||
|
TRI_voc_cid_t _collectionId;
|
||||||
|
TRI_idx_iid_t _indexId;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief wal transaction begin marker
|
/// @brief wal transaction begin marker
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -502,6 +523,50 @@ namespace triagens {
|
||||||
void dump () const;
|
void dump () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- CreateIndexMarker
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CreateIndexMarker : public Marker {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CreateIndexMarker (TRI_voc_tick_t,
|
||||||
|
TRI_voc_cid_t,
|
||||||
|
TRI_idx_iid_t,
|
||||||
|
std::string const&);
|
||||||
|
|
||||||
|
~CreateIndexMarker ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline char* properties () const {
|
||||||
|
return begin() + sizeof(index_create_marker_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump () const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- DropIndexMarker
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class DropIndexMarker : public Marker {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DropIndexMarker (TRI_voc_tick_t,
|
||||||
|
TRI_voc_cid_t,
|
||||||
|
TRI_idx_iid_t);
|
||||||
|
|
||||||
|
~DropIndexMarker ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void dump () const;
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- BeginTransactionMarker
|
// --SECTION-- BeginTransactionMarker
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -34,6 +34,7 @@ var ArangoCollection = arangodb.ArangoCollection;
|
||||||
var db = arangodb.db;
|
var db = arangodb.db;
|
||||||
var ERRORS = arangodb.errors;
|
var ERRORS = arangodb.errors;
|
||||||
var wait = require("internal").wait;
|
var wait = require("internal").wait;
|
||||||
|
var testHelper = require("org/arangodb/test-helper").Helper;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- collection methods
|
// --SECTION-- collection methods
|
||||||
|
@ -253,20 +254,17 @@ function CollectionEdgeSuite () {
|
||||||
assertEqual("vx2", k2._key);
|
assertEqual("vx2", k2._key);
|
||||||
assertEqual(vn + "/vx2", k2._id);
|
assertEqual(vn + "/vx2", k2._id);
|
||||||
|
|
||||||
vertex.unload();
|
testHelper.waitUnload(vertex);
|
||||||
edge.unload();
|
testHelper.waitUnload(edge);
|
||||||
|
|
||||||
console.log("waiting for collections to unload");
|
|
||||||
wait(4);
|
|
||||||
|
|
||||||
var e1 = edge.save(vn + "/vx1", vn + "/vx2", { _key: "ex1", connect: "vx1->vx2" });
|
var e1 = edge.save(vn + "/vx1", vn + "/vx2", { _key: "ex1", connect: "vx1->vx2" });
|
||||||
var e2 = edge.save(vn + "/vx2", vn + "/vx1", { _key: "ex2", connect: "vx2->vx1" });
|
var e2 = edge.save(vn + "/vx2", vn + "/vx1", { _key: "ex2", connect: "vx2->vx1" });
|
||||||
|
|
||||||
|
testHelper.waitUnload(vertex);
|
||||||
|
testHelper.waitUnload(edge);
|
||||||
vertex.unload();
|
vertex.unload();
|
||||||
edge.unload();
|
edge.unload();
|
||||||
|
|
||||||
console.log("waiting for collections to unload");
|
|
||||||
wait(4);
|
|
||||||
var e3 = edge.save(k1, k2, { _key: "ex3", connect: "vx1->vx2" });
|
var e3 = edge.save(k1, k2, { _key: "ex3", connect: "vx1->vx2" });
|
||||||
|
|
||||||
d1 = edge.document("ex1");
|
d1 = edge.document("ex1");
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
error: function (msg) {
|
error: function (msg) {
|
||||||
console.error("In database '%s': %s", db._name(), msg);
|
console.error("In database '%s': %s", db._name(), msg);
|
||||||
},
|
},
|
||||||
|
warn: function (msg) {
|
||||||
|
console.warn("In database '%s': %s", db._name(), msg);
|
||||||
|
},
|
||||||
log: function (msg) {
|
log: function (msg) {
|
||||||
this.info(msg);
|
this.info(msg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue