mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel
This commit is contained in:
commit
e294d1b8c4
File diff suppressed because it is too large
Load Diff
|
@ -187,21 +187,6 @@ typedef struct TRI_skiplistEx_s {
|
|||
TRI_skiplistEx_t;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief structure used for a skip list which only accepts unique entries and is thread safe
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// structure for a skiplist which allows unique entries -- with locking
|
||||
// available for its nearest neighbours.
|
||||
// TODO: implement locking for nearest neighbours rather than for all of index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_skiplistEx_synced_s {
|
||||
TRI_skiplistEx_t _base;
|
||||
TRI_read_write_lock_t _lock;
|
||||
} TRI_skiplistEx_synced_t;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -321,7 +306,8 @@ void* TRI_PrevNodeSkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RemoveElementSkipListEx (TRI_skiplistEx_t*, void*, void*,
|
||||
const int passLevel, const uint64_t thisTransID);
|
||||
const int passLevel, const uint64_t thisTransID,
|
||||
TRI_skiplistEx_node_t**);
|
||||
|
||||
|
||||
|
||||
|
@ -330,7 +316,8 @@ int TRI_RemoveElementSkipListEx (TRI_skiplistEx_t*, void*, void*,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RemoveKeySkipListEx (TRI_skiplistEx_t*, void*, void*,
|
||||
const int passLevel, const uint64_t thisTransID);
|
||||
const int passLevel, const uint64_t thisTransID,
|
||||
TRI_skiplistEx_node_t**);
|
||||
|
||||
|
||||
|
||||
|
@ -359,7 +346,7 @@ void* TRI_StartNodeSkipListEx (TRI_skiplistEx_t*);
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief structure used for a multi skiplist
|
||||
/// @brief structure used for skiplist accepting duplicate entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -387,17 +374,6 @@ typedef struct TRI_skiplistEx_multi_s {
|
|||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief structure used for a multi skip list and is thread safe
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_skiplistEx_synced_multi_s {
|
||||
TRI_skiplistEx_t _base;
|
||||
TRI_read_write_lock_t _lock;
|
||||
} TRI_skiplistEx_synced_multi_t;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -526,7 +502,8 @@ void* TRI_PrevNodeSkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t this
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RemoveElementSkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*,
|
||||
const int passLevel, const uint64_t thisTransID);
|
||||
const int passLevel, const uint64_t thisTransID,
|
||||
TRI_skiplistEx_node_t**);
|
||||
|
||||
|
||||
|
||||
|
@ -535,7 +512,8 @@ int TRI_RemoveElementSkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RemoveKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*,
|
||||
const int passLevel, const uint64_t thisTransID);
|
||||
const int passLevel, const uint64_t thisTransID,
|
||||
TRI_skiplistEx_node_t**);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "skiplistExIndex.h"
|
||||
#include "VocBase/index-garbage-collector.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -977,14 +978,98 @@ int SkiplistExIndex_insert(SkiplistExIndex* skiplistExIndex, SkiplistExIndexElem
|
|||
/// @brief removes an entry from the skip list
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CollectSkiplistExGarbage(TRI_index_gc_t* indexGCData) {
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
SkiplistExIndex* skiplistIndex;
|
||||
TRI_skiplistEx_node_t* passNode;
|
||||
TRI_skiplistEx_t* skiplist;
|
||||
|
||||
if (indexGCData == NULL) {
|
||||
abort(); // remove after debugging
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
skiplistIndex = (SkiplistExIndex*)(indexGCData->_index);
|
||||
if (skiplistIndex == NULL) {
|
||||
abort(); // remove after debugging
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
skiplist = (skiplistIndex->_skiplistEx).uniqueSkiplistEx;
|
||||
|
||||
passNode = (TRI_skiplistEx_node_t*)(indexGCData->_data);
|
||||
if (passNode == NULL) {
|
||||
abort(); // remove after debugging
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
|
||||
switch (indexGCData->_lastPass) {
|
||||
case 1: { // the first call from the garbage collector
|
||||
result = TRI_RemoveElementSkipListEx (skiplist, NULL, NULL, 2, passNode->_delTransID, &passNode);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
result = TRI_RemoveElementSkipListEx (skiplist, NULL, NULL, 3, passNode->_delTransID, &passNode);
|
||||
break;
|
||||
}
|
||||
|
||||
case 254: { // just before the node is excised from the skiplist
|
||||
result = TRI_ERROR_NO_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
case 255: { // just AFTER the node is excised from the skiplist
|
||||
result = TRI_ERROR_NO_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
default : {
|
||||
abort();
|
||||
}
|
||||
|
||||
} // end of switch statement
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int SkiplistExIndex_remove(SkiplistExIndex* skiplistExIndex, SkiplistExIndexElement* element, uint64_t thisTransID) {
|
||||
int result;
|
||||
TRI_skiplistEx_node_t* passNode;
|
||||
TRI_index_gc_t indexGCData;
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// This has been called from the database so it has a pass level of 1
|
||||
// ............................................................................
|
||||
|
||||
result = TRI_RemoveElementSkipListEx(skiplistExIndex->_skiplistEx.uniqueSkiplistEx, element, NULL, 1, thisTransID);
|
||||
result = TRI_RemoveElementSkipListEx(skiplistExIndex->_skiplistEx.uniqueSkiplistEx, element,
|
||||
NULL, 1, thisTransID, &passNode);
|
||||
if (result == TRI_ERROR_NO_ERROR) {
|
||||
|
||||
// ..........................................................................
|
||||
// add to garbage collection
|
||||
// ..........................................................................
|
||||
|
||||
indexGCData._index = (void*)(skiplistExIndex);
|
||||
indexGCData._passes = 2;
|
||||
indexGCData._lastPass = 0; // will be assigned correctly by the GC
|
||||
indexGCData._transID = 0; // will be assigned correctly by the GC
|
||||
indexGCData._data = passNode; // the address of the node in the linked list which will eventually be excised
|
||||
indexGCData._collectGarbage = CollectSkiplistExGarbage;
|
||||
|
||||
// ...........................................................................
|
||||
// Adds an item to the rubbish collection linked list.
|
||||
// This can fail if the GC is busy and the CAS statements in the GC fail.
|
||||
// It is up to the calling procedure to determine what to do with this failure,
|
||||
// generally a retry will suffice.
|
||||
// ...........................................................................
|
||||
result = TRI_AddToIndexGC(&indexGCData);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1358,14 +1443,37 @@ int MultiSkiplistExIndex_insert(SkiplistExIndex* skiplistExIndex, SkiplistExInde
|
|||
/// @brief removes an entry from the skiplist
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CollectSkiplistExMultiGarbage(TRI_index_gc_t* indexGCData) {
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int MultiSkiplistExIndex_remove(SkiplistExIndex* skiplistExIndex, SkiplistExIndexElement* element, uint64_t thisTransID) {
|
||||
int result;
|
||||
TRI_skiplistEx_node_t* passNode;
|
||||
TRI_index_gc_t indexGCData;
|
||||
|
||||
// ............................................................................
|
||||
// This has been called from the database so it has a pass level of 1
|
||||
// ............................................................................
|
||||
|
||||
result = TRI_RemoveElementSkipListExMulti(skiplistExIndex->_skiplistEx.nonUniqueSkiplistEx, element, NULL, 1, thisTransID);
|
||||
result = TRI_RemoveElementSkipListExMulti(skiplistExIndex->_skiplistEx.nonUniqueSkiplistEx,
|
||||
element, NULL, 1, thisTransID, &passNode);
|
||||
if (result == TRI_ERROR_NO_ERROR) {
|
||||
|
||||
// ..........................................................................
|
||||
// add to garbage collection
|
||||
// ..........................................................................
|
||||
|
||||
indexGCData._index = (void*)(skiplistExIndex);
|
||||
indexGCData._passes = 2;
|
||||
indexGCData._lastPass = 0; // will be assigned correctly by the GC
|
||||
indexGCData._transID = 0; // will be assigned correctly by the GC
|
||||
indexGCData._data = passNode; // the address of the node in the linked list which will eventually be excised
|
||||
indexGCData._collectGarbage = CollectSkiplistExMultiGarbage;
|
||||
result = TRI_AddToIndexGC(&indexGCData); // adds an item to the rubbish collection linked list
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1443,7 +1443,11 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, TRI_col_t
|
|||
TRI_V8_EXCEPTION_INTERNAL(scope, "cannot extract vocbase");
|
||||
}
|
||||
|
||||
// expecting at least one arguments
|
||||
|
||||
// ...........................................................................
|
||||
// We require exactly 1 or exactly 2 arguments -- anything else is an error
|
||||
// ...........................................................................
|
||||
|
||||
if (argv.Length() < 1 || argv.Length() > 2) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "_create(<name>, <properties>)");
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "VocBase/transaction.h"
|
||||
|
||||
|
||||
// @@@@@@@@ TODO: TRI_addToIOndexGC & ExciseNode
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private constants
|
||||
|
@ -50,7 +49,13 @@
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_INDEX_GC_CAS_RETRIES 100
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the number of times the Garbage Collector will retry when a CAS statement fails
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int const MAX_INDEX_GC_CAS_RETRIES = 100;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the period between garbage collection tries in microseconds
|
||||
|
@ -58,6 +63,13 @@
|
|||
|
||||
static int const INDEX_GC_INTERVAL = (1 * 1000 * 1000);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the amount of time to sleep when a CAS statement fails (in microseconds)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned int CAS_FAILURE_SLEEP_TIME = 1000;
|
||||
|
||||
// .............................................................................
|
||||
// The rubbish collection operates as a simple linked list. Whenever an index
|
||||
// requests an item to be added to the collector, we insert a node at the end
|
||||
|
@ -80,13 +92,17 @@ typedef struct linked_list_s {
|
|||
linked_list_node_t _startNode;
|
||||
linked_list_node_t _endNode;
|
||||
volatile uint32_t _listFlag;
|
||||
uint64_t _size;
|
||||
} linked_list_t;
|
||||
|
||||
|
||||
enum {
|
||||
INDEX_GC_LIST_NORMAL_FLAG,
|
||||
INDEX_GC_LIST_FORBIDDEN_FLAG,
|
||||
INDEX_GC_NODE_NORMAL_FLAG,
|
||||
INDEX_GC_NODE_BRICKED_FLAG,
|
||||
INDEX_GC_NODE_DELETED_FLAG,
|
||||
INDEX_GC_NODE_INSERTED_FLAG
|
||||
};
|
||||
|
||||
|
||||
|
@ -95,6 +111,8 @@ enum {
|
|||
// .............................................................................
|
||||
|
||||
static linked_list_t* INDEX_GC_LINKED_LIST = NULL;
|
||||
static void* INDEX_GC_DATA = NULL;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -111,10 +129,23 @@ static linked_list_t* INDEX_GC_LINKED_LIST = NULL;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int ExciseNode (linked_list_node_t*);
|
||||
static int ExciseNodeBrick (linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode);
|
||||
static int ExciseNodeBrickUndo (linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int bricked);
|
||||
static int ExciseNodeSwapPointers (linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode);
|
||||
static int ExciseNodeSwapPointersUndo(linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int swaped);
|
||||
|
||||
static void InitialiseStaticLinkedList (void);
|
||||
static void InnerThreadLoop (bool*);
|
||||
|
||||
static int InsertNode (linked_list_node_t*);
|
||||
static int InsertNodeBrick (linked_list_node_t* prevNode, linked_list_node_t* nextNode);
|
||||
static int InsertNodeBrickUndo (linked_list_node_t* prevNode, linked_list_node_t* nextNode, int bricked);
|
||||
static int InsertNodeSwapPointers (linked_list_node_t* nodeToInsert, linked_list_node_t* prevNode, linked_list_node_t* nextNode);
|
||||
static int InsertNodeSwapPointersUndo (linked_list_node_t* nodeToInsert, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int swaped);
|
||||
|
||||
static void RemoveLinkedList (void);
|
||||
static void SetForbiddenFlag (void);
|
||||
static void UnsetForbiddenFlag (void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -156,7 +187,8 @@ void TRI_IndexGCVocBase (void* data) {
|
|||
// Initialise the static linked list: INDEX_GC_LINKED_LIST
|
||||
// ..........................................................................
|
||||
|
||||
// InitialiseStaticLinkedList();
|
||||
InitialiseStaticLinkedList();
|
||||
INDEX_GC_DATA = data;
|
||||
|
||||
|
||||
// ..........................................................................
|
||||
|
@ -175,7 +207,7 @@ void TRI_IndexGCVocBase (void* data) {
|
|||
|
||||
int oldState = vocbase->_state;
|
||||
|
||||
/*
|
||||
|
||||
// ........................................................................
|
||||
// The loop goes to sleep whenever we are at the end of the linked list.
|
||||
// ........................................................................
|
||||
|
@ -185,9 +217,10 @@ void TRI_IndexGCVocBase (void* data) {
|
|||
&(INDEX_GC_LINKED_LIST->_endNode));
|
||||
|
||||
InnerThreadLoop (&goToSleep);
|
||||
*/
|
||||
|
||||
goToSleep = true;
|
||||
|
||||
// goToSleep = true;
|
||||
//printf("oreste:%s:%d:gotosleep=%d:state=%d\n",__FILE__,__LINE__,goToSleep,vocbase->_state);
|
||||
|
||||
if (vocbase->_state == 1 && goToSleep) { // only sleep while server is still running
|
||||
|
||||
|
@ -209,13 +242,22 @@ void TRI_IndexGCVocBase (void* data) {
|
|||
// can be made.
|
||||
// ..........................................................................
|
||||
|
||||
//SetForbiddenFlag();
|
||||
SetForbiddenFlag();
|
||||
|
||||
|
||||
// ..........................................................................
|
||||
// We need to wait a little while in case there are any other threads which
|
||||
// are busy adding things to the collector
|
||||
// ..........................................................................
|
||||
|
||||
usleep(INDEX_GC_INTERVAL);
|
||||
|
||||
|
||||
// ..........................................................................
|
||||
// Remove all memory we assigned to any structures
|
||||
// ..........................................................................
|
||||
|
||||
//RemoveLinkedList();
|
||||
RemoveLinkedList();
|
||||
|
||||
LOG_TRACE("the index garbage collector event loop has stopped");
|
||||
}
|
||||
|
@ -234,10 +276,38 @@ void TRI_IndexGCVocBase (void* data) {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Adds a node to the linked list, so that eventually the GC will remove an
|
||||
// item from the given index.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_AddToIndexGC(TRI_index_gc_t* indexData) {
|
||||
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
bool ok;
|
||||
linked_list_node_t* insertNode; // node to be inserted into our linked list
|
||||
TRI_vocbase_t* vocbase = (TRI_vocbase_t*)(INDEX_GC_DATA);
|
||||
|
||||
// ...........................................................................
|
||||
// Check if the gc has actually started
|
||||
// ...........................................................................
|
||||
|
||||
if (vocbase == NULL) {
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Check if the server has shut down?
|
||||
// ...........................................................................
|
||||
|
||||
if (vocbase->_state == -1) {
|
||||
return TRI_WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN;
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Check that we have something to add
|
||||
// ...........................................................................
|
||||
|
||||
|
||||
// ...........................................................................
|
||||
// Check that we have something to add
|
||||
|
@ -248,32 +318,137 @@ int TRI_AddToIndexGC(TRI_index_gc_t* indexData) {
|
|||
}
|
||||
|
||||
|
||||
// ...........................................................................
|
||||
// Check that the rubbish collector is accepting rubbish.
|
||||
// Generally this means that the server has been shut down. In this case we
|
||||
// will not accept anymore rubbish.
|
||||
// ...........................................................................
|
||||
insertNode = (linked_list_node_t*)(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(linked_list_node_t), true));
|
||||
|
||||
if (insertNode == NULL) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
insertNode->_indexData = (TRI_index_gc_t*)(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_index_gc_t), true));
|
||||
if (insertNode->_indexData == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, insertNode);
|
||||
}
|
||||
|
||||
|
||||
// ...........................................................................
|
||||
// The indexData structure whose memory has been allocated by the INDEX
|
||||
// (and not this function) will also be removed by the INDEX which called
|
||||
// this function. When indexData._lastPass = 254, then the collectGarbage
|
||||
// callback will be alerted to the fact that the excision of the item from the
|
||||
// rubbish collector will be imminent. When indexData._lastPass = 255, then the
|
||||
// collectGarbage callback will be alerted that the excision has occured and
|
||||
// that any memory allocated must be deallocated.
|
||||
// ...........................................................................
|
||||
insertNode->_indexData->_index = indexData->_index;
|
||||
insertNode->_indexData->_passes = indexData->_passes;
|
||||
insertNode->_indexData->_lastPass = 0;
|
||||
insertNode->_indexData->_data = indexData->_data;
|
||||
insertNode->_indexData->_collectGarbage = indexData->_collectGarbage;
|
||||
// TODO: get the current transaction id
|
||||
//insertNode->_indexData->_transID = vocbase->_transactionStuff->_GetGlobalTransactionFigures(0);
|
||||
++(insertNode->_indexData->_transID);
|
||||
|
||||
/*
|
||||
INDEX_GC_LIST_NORMAL_FLAG
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(leftNN->_nbFlag), INDEX_GC_LIST_NORMAL_FLAG, INDEX_GC_LIST_NORMAL_FLAG);
|
||||
*/
|
||||
|
||||
return result;
|
||||
// ...........................................................................
|
||||
// the assignment of the _next and _prev pointers must be done in a CAS loop
|
||||
// within the IndexNode(...) function.
|
||||
// ...........................................................................
|
||||
|
||||
insertNode->_next = NULL;
|
||||
insertNode->_prev = NULL;
|
||||
insertNode->_nodeFlag = INDEX_GC_NODE_NORMAL_FLAG;
|
||||
|
||||
result = InsertNode(insertNode);
|
||||
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, insertNode->_indexData);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, insertNode);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// For the given index, all nodes which match the index will be excised from
|
||||
// the linked list.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_ExpungeIndexGC (TRI_index_gc_t* indexData) {
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
linked_list_node_t* currentNode;
|
||||
bool finished = true;
|
||||
int casCounter = 0;
|
||||
|
||||
LOG_TRACE("the index garbage collector has commenced expunging all nodes for a given index");
|
||||
|
||||
CAS_LOOP: {
|
||||
|
||||
result = TRI_ERROR_NO_ERROR;
|
||||
currentNode = &(INDEX_GC_LINKED_LIST->_startNode);
|
||||
|
||||
if (casCounter > MAX_INDEX_GC_CAS_RETRIES) {
|
||||
LOG_ERROR("max cas loop exceeded");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
++casCounter;
|
||||
|
||||
while (currentNode != NULL) {
|
||||
linked_list_node_t* tempNode = currentNode->_next;
|
||||
|
||||
if (currentNode->_indexData == NULL) {
|
||||
currentNode = tempNode;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (indexData->_index != currentNode->_indexData->_index) {
|
||||
currentNode = tempNode;
|
||||
continue;
|
||||
}
|
||||
|
||||
// .......................................................................
|
||||
// Just before we remove the data and associated data, go to the index
|
||||
// and indicate that we are about to remove the node from the linked list
|
||||
// .......................................................................
|
||||
|
||||
indexData->_lastPass = 254;
|
||||
result = indexData->_collectGarbage(indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector called the callback which returend error %d", result);
|
||||
}
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// Actually remove the node from the linked list here
|
||||
// .......................................................................
|
||||
|
||||
result = ExciseNode(currentNode);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector function ExcisENode returned with error %d", result);
|
||||
finished = false;
|
||||
currentNode = tempNode;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// Inform the index that the node has been removed from the linked list
|
||||
// .......................................................................
|
||||
|
||||
indexData->_lastPass = 255;
|
||||
result = indexData->_collectGarbage(indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector called the callback which returend error %d", result);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, currentNode);
|
||||
currentNode = tempNode;
|
||||
|
||||
} // end of while loop
|
||||
|
||||
if (!finished) {
|
||||
goto CAS_LOOP;
|
||||
}
|
||||
|
||||
} // end of CAS_LOOP
|
||||
|
||||
LOG_TRACE("the index garbage collector has completed expunging nodes for a given index");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -288,10 +463,9 @@ int TRI_AddToIndexGC(TRI_index_gc_t* indexData) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
int ExciseNode(linked_list_node_t* nodeToExcise) {
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
return result;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Creates and initialises the linked list used by the garbage collector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void InitialiseStaticLinkedList(void) {
|
||||
|
||||
|
@ -310,6 +484,7 @@ void InitialiseStaticLinkedList(void) {
|
|||
// ..........................................................................
|
||||
|
||||
INDEX_GC_LINKED_LIST->_listFlag = INDEX_GC_LIST_FORBIDDEN_FLAG;
|
||||
INDEX_GC_LINKED_LIST->_size = 0;
|
||||
|
||||
|
||||
(INDEX_GC_LINKED_LIST->_startNode)._indexData = NULL;
|
||||
|
@ -327,7 +502,7 @@ void InitialiseStaticLinkedList(void) {
|
|||
// 'Unlock' the list so that other process can use it
|
||||
// ..........................................................................
|
||||
|
||||
if (TRI_CompareAndSwapIntegerUInt32 (&(INDEX_GC_LINKED_LIST->_listFlag),
|
||||
if (!TRI_CompareAndSwapIntegerUInt32 (&(INDEX_GC_LINKED_LIST->_listFlag),
|
||||
INDEX_GC_LIST_FORBIDDEN_FLAG,
|
||||
INDEX_GC_LIST_NORMAL_FLAG) ) {
|
||||
LOG_FATAL_AND_EXIT("Index garbage collector can not start - CAS failure");
|
||||
|
@ -343,6 +518,7 @@ void InnerThreadLoop (bool* goToSleep) {
|
|||
uint64_t lastCompleteGlobalTransID = 0;
|
||||
TRI_transaction_global_stats_t* stats = NULL;
|
||||
int result;
|
||||
TRI_vocbase_t* vocbase = (TRI_vocbase_t*)(INDEX_GC_DATA);
|
||||
|
||||
stats = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_global_stats_t), true);
|
||||
if (stats == NULL) {
|
||||
|
@ -405,42 +581,85 @@ void InnerThreadLoop (bool* goToSleep) {
|
|||
indexData = currentNode->_indexData;
|
||||
|
||||
|
||||
// ........................................................................
|
||||
// Check whether or not we can actually execute the call back for that
|
||||
// particular pass.
|
||||
// ........................................................................
|
||||
|
||||
/* TODO: this needs to be fixed with the transaction handling stuff
|
||||
if (stats->oldestGlobalTransID <= indexData->_transID) {
|
||||
currentNode = currentNode->_next;
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// ........................................................................
|
||||
// First lets check whether we have actually finished with this node.
|
||||
// ........................................................................
|
||||
|
||||
if (indexData->_passes == indexData->_lastPass) {
|
||||
if (indexData->_lastPass < indexData->_passes) {
|
||||
++(indexData->_lastPass);
|
||||
result = indexData->_collectGarbage(indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector called the callback which returend error %d", result);
|
||||
if (result == TRI_WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE) {
|
||||
// no harm done we simply try again later
|
||||
--(indexData->_lastPass);
|
||||
}
|
||||
}
|
||||
currentNode = currentNode->_next;
|
||||
}
|
||||
|
||||
|
||||
else if (indexData->_passes == indexData->_lastPass) {
|
||||
|
||||
// .......................................................................
|
||||
// We have finished essentially finished with the node and are about it
|
||||
// to remove the node from the linked list here.
|
||||
// .......................................................................
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// Just before we remove the data and associated data, go to the index
|
||||
// and indicate that we are about to remove the node from the linked list
|
||||
// .......................................................................
|
||||
|
||||
indexData->_lastPass = 254;
|
||||
result = indexData->_collectGarbage(indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector called the callback which returend error %d", result);
|
||||
}
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// Actually remove the node from the linked list here
|
||||
// .......................................................................
|
||||
|
||||
result = ExciseNode(currentNode);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector function ExcisENode returned with error %d", result);
|
||||
}
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// Inform the index that the node has been removed from the linked list
|
||||
// .......................................................................
|
||||
|
||||
indexData->_lastPass = 255;
|
||||
result = indexData->_collectGarbage(indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector called the callback which returend error %d", result);
|
||||
}
|
||||
|
||||
|
||||
tempNode = currentNode->_next;
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, currentNode);
|
||||
currentNode = tempNode;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ........................................................................
|
||||
// Check whether or not we can actually execute the call back for that
|
||||
// particular pass.
|
||||
// ........................................................................
|
||||
|
||||
if (lastCompleteGlobalTransID <= indexData->_transID) {
|
||||
currentNode = currentNode->_next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} // end of while loop
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -450,35 +669,20 @@ void RemoveLinkedList(void) {
|
|||
LOG_TRACE("the index garbage collector has commenced removing all allocated memory");
|
||||
currentNode = &(INDEX_GC_LINKED_LIST->_startNode);
|
||||
|
||||
if ( currentNode->_next != NULL ) {
|
||||
currentNode = currentNode->_next;
|
||||
}
|
||||
else {
|
||||
currentNode = NULL;
|
||||
}
|
||||
|
||||
while (currentNode != NULL) {
|
||||
int result;
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
linked_list_node_t* tempNode = currentNode->_next;
|
||||
|
||||
if (currentNode->_indexData == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
currentNode->_indexData->_lastPass = 255;
|
||||
|
||||
result = currentNode->_indexData->_collectGarbage(currentNode->_indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector executed the callback and has returned error code %d",result);
|
||||
}
|
||||
|
||||
if ( currentNode->_next != NULL ) {
|
||||
linked_list_node_t* tempNode = currentNode->_next;
|
||||
if (currentNode->_indexData != NULL) {
|
||||
currentNode->_indexData->_lastPass = 255;
|
||||
result = currentNode->_indexData->_collectGarbage(currentNode->_indexData);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TRACE("the index garbage collector executed the callback and has returned error code %d",result);
|
||||
}
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, currentNode);
|
||||
currentNode = tempNode;
|
||||
}
|
||||
else {
|
||||
currentNode = NULL;
|
||||
}
|
||||
|
||||
currentNode = tempNode;
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, INDEX_GC_LINKED_LIST);
|
||||
|
@ -488,26 +692,298 @@ void RemoveLinkedList(void) {
|
|||
|
||||
void SetForbiddenFlag(void) {
|
||||
int counter = 0;
|
||||
LOG_TRACE("the index garbage collector is attempting to block insertions");
|
||||
//LOG_TRACE("the index garbage collector is attempting to block insertions");
|
||||
|
||||
while (counter < MAX_INDEX_GC_CAS_RETRIES) {
|
||||
while (counter < MAX_INDEX_GC_CAS_RETRIES) {
|
||||
if (TRI_CompareAndSwapIntegerUInt32 (&(INDEX_GC_LINKED_LIST->_listFlag),
|
||||
INDEX_GC_LIST_NORMAL_FLAG,
|
||||
INDEX_GC_LIST_FORBIDDEN_FLAG) ) {
|
||||
counter = -1;
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
usleep(CAS_FAILURE_SLEEP_TIME);
|
||||
}
|
||||
|
||||
if (counter == -1) {
|
||||
LOG_TRACE("the index garbage collector has succeeded in blocking insertions");
|
||||
//LOG_TRACE("the index garbage collector has succeeded in blocking insertions");
|
||||
}
|
||||
else {
|
||||
LOG_TRACE("the index garbage collector has failed in blocking insertions");
|
||||
}
|
||||
}
|
||||
|
||||
void UnsetForbiddenFlag(void) {
|
||||
int counter = 0;
|
||||
|
||||
//LOG_TRACE("the index garbage collector is attempting to unblock insertions");
|
||||
|
||||
while (counter < MAX_INDEX_GC_CAS_RETRIES) {
|
||||
if (TRI_CompareAndSwapIntegerUInt32 (&(INDEX_GC_LINKED_LIST->_listFlag),
|
||||
INDEX_GC_LIST_FORBIDDEN_FLAG,
|
||||
INDEX_GC_LIST_NORMAL_FLAG) ) {
|
||||
counter = -1;
|
||||
break;
|
||||
}
|
||||
usleep(CAS_FAILURE_SLEEP_TIME);
|
||||
}
|
||||
|
||||
if (counter == -1) {
|
||||
//LOG_TRACE("the index garbage collector has succeeded in unblocking insertions");
|
||||
}
|
||||
else {
|
||||
LOG_TRACE("the index garbage collector has failed in unblocking insertions\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of static functions for insertion of a node
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int InsertNode(linked_list_node_t* insertNode) {
|
||||
int casCounter = 0;
|
||||
int bricked = 0;
|
||||
int swaped = 0;
|
||||
int result;
|
||||
linked_list_node_t* nextNode;
|
||||
linked_list_node_t* prevNode;
|
||||
|
||||
CAS_LOOP: {
|
||||
|
||||
// ..........................................................................
|
||||
// We can not assign these pointers outside this loop, since these may change
|
||||
// any time with threads busy inserting entries into the list.
|
||||
// ..........................................................................
|
||||
|
||||
insertNode->_next = &(INDEX_GC_LINKED_LIST->_endNode);
|
||||
nextNode = (linked_list_node_t*)(insertNode->_next);
|
||||
|
||||
insertNode->_prev = (linked_list_node_t*)(nextNode->_prev);
|
||||
prevNode = (linked_list_node_t*)(insertNode->_prev);
|
||||
|
||||
|
||||
if (casCounter > 1) {
|
||||
usleep(CAS_FAILURE_SLEEP_TIME);
|
||||
}
|
||||
|
||||
if (casCounter > MAX_INDEX_GC_CAS_RETRIES) {
|
||||
LOG_ERROR("max cas loop exceeded");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
bricked = InsertNodeBrick(prevNode, nextNode);
|
||||
if (bricked != 2) {
|
||||
int tempResult = InsertNodeBrickUndo(prevNode, nextNode, bricked);
|
||||
if (tempResult != TRI_ERROR_NO_ERROR) {
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
++casCounter;
|
||||
goto CAS_LOOP;
|
||||
}
|
||||
|
||||
swaped = InsertNodeSwapPointers(insertNode, prevNode, nextNode);
|
||||
if (swaped != 2) {
|
||||
int tempResult1 = InsertNodeBrickUndo(prevNode, nextNode, bricked);
|
||||
int tempResult2 = InsertNodeSwapPointersUndo(insertNode, prevNode, nextNode, swaped);
|
||||
if ((tempResult1 != TRI_ERROR_NO_ERROR) || (tempResult2 != TRI_ERROR_NO_ERROR)) {
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
++casCounter;
|
||||
goto CAS_LOOP;
|
||||
}
|
||||
|
||||
result = InsertNodeBrickUndo(prevNode, nextNode, bricked);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
++INDEX_GC_LINKED_LIST->_size;
|
||||
|
||||
} // end of CAS_LOOP
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
static int InsertNodeBrick(linked_list_node_t* prevNode, linked_list_node_t* nextNode) {
|
||||
bool ok;
|
||||
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(prevNode->_nodeFlag), INDEX_GC_NODE_NORMAL_FLAG, INDEX_GC_NODE_BRICKED_FLAG);
|
||||
if (!ok) { return 0; }
|
||||
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(nextNode->_nodeFlag), INDEX_GC_NODE_NORMAL_FLAG, INDEX_GC_NODE_BRICKED_FLAG);
|
||||
if (!ok) { return 1; }
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int InsertNodeBrickUndo(linked_list_node_t* prevNode, linked_list_node_t* nextNode, int bricked) {
|
||||
bool ok;
|
||||
|
||||
if (bricked > 0) {
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(prevNode->_nodeFlag), INDEX_GC_NODE_BRICKED_FLAG, INDEX_GC_NODE_NORMAL_FLAG);
|
||||
if (bricked > 1) {
|
||||
ok = (TRI_CompareAndSwapIntegerUInt32 (&(nextNode->_nodeFlag), INDEX_GC_NODE_BRICKED_FLAG, INDEX_GC_NODE_NORMAL_FLAG)) && (ok);
|
||||
}
|
||||
if (!ok) {
|
||||
LOG_ERROR("InsertNodeBrickUndo failed here");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static int InsertNodeSwapPointers(linked_list_node_t* nodeToInsert, linked_list_node_t* prevNode, linked_list_node_t* nextNode) {
|
||||
bool ok;
|
||||
|
||||
ok = TRI_CompareAndSwapPointer(&(prevNode->_next), nextNode, nodeToInsert);
|
||||
if (!ok) { return 0; }
|
||||
|
||||
ok = TRI_CompareAndSwapPointer(&(nextNode->_prev), prevNode, nodeToInsert);
|
||||
if (!ok) { return 1; }
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int InsertNodeSwapPointersUndo(linked_list_node_t* nodeToInsert, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int swaped) {
|
||||
bool ok;
|
||||
|
||||
if (swaped > 0) {
|
||||
ok = TRI_CompareAndSwapPointer(&(prevNode->_next), nodeToInsert, nextNode);
|
||||
if (swaped > 1) {
|
||||
ok = ok && TRI_CompareAndSwapPointer(&(nextNode->_prev), nodeToInsert, prevNode);
|
||||
}
|
||||
if (!ok) {
|
||||
LOG_ERROR("InsertNodeSwapPointersUndo failed here");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of static functions for removal of a node
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int ExciseNode(linked_list_node_t* nodeToExcise) {
|
||||
int result = TRI_ERROR_NO_ERROR;
|
||||
int casCounter = 0;
|
||||
int bricked = 0;
|
||||
int swaped = 0;
|
||||
linked_list_node_t* nextNode;
|
||||
linked_list_node_t* prevNode;
|
||||
|
||||
|
||||
SetForbiddenFlag();
|
||||
|
||||
CAS_LOOP: {
|
||||
|
||||
result = TRI_ERROR_NO_ERROR;
|
||||
nextNode = nodeToExcise->_next;
|
||||
prevNode = nodeToExcise->_prev;
|
||||
|
||||
if (casCounter > 1) {
|
||||
usleep(CAS_FAILURE_SLEEP_TIME);
|
||||
}
|
||||
|
||||
if (casCounter > MAX_INDEX_GC_CAS_RETRIES) {
|
||||
LOG_ERROR("max cas loop exceeded");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
bricked = ExciseNodeBrick(nodeToExcise, prevNode, nextNode);
|
||||
|
||||
if (bricked != 3) {
|
||||
result = ExciseNodeBrickUndo(nodeToExcise, prevNode, nextNode, bricked);
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
return result;
|
||||
}
|
||||
++casCounter;
|
||||
goto CAS_LOOP;
|
||||
}
|
||||
|
||||
|
||||
swaped = ExciseNodeSwapPointers(nodeToExcise, prevNode, nextNode);
|
||||
if (swaped != 2) {
|
||||
ExciseNodeBrickUndo(nodeToExcise, prevNode, nextNode, bricked);
|
||||
ExciseNodeSwapPointersUndo(nodeToExcise, prevNode, nextNode, swaped);
|
||||
++casCounter;
|
||||
goto CAS_LOOP;
|
||||
}
|
||||
|
||||
--INDEX_GC_LINKED_LIST->_size;
|
||||
ExciseNodeBrickUndo(nodeToExcise, prevNode, nextNode, bricked);
|
||||
|
||||
} // end of CAS_LOOP
|
||||
|
||||
UnsetForbiddenFlag();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ExciseNodeBrick(linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode) {
|
||||
bool ok;
|
||||
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(nodeToExcise->_nodeFlag), INDEX_GC_NODE_NORMAL_FLAG, INDEX_GC_NODE_BRICKED_FLAG);
|
||||
if (!ok) { return 0; }
|
||||
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(prevNode->_nodeFlag), INDEX_GC_NODE_NORMAL_FLAG, INDEX_GC_NODE_BRICKED_FLAG);
|
||||
if (!ok) { return 1; }
|
||||
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(nextNode->_nodeFlag), INDEX_GC_NODE_NORMAL_FLAG, INDEX_GC_NODE_BRICKED_FLAG);
|
||||
if (!ok) { return 2; }
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int ExciseNodeBrickUndo(linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int bricked) {
|
||||
bool ok;
|
||||
|
||||
if (bricked > 0) {
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(nodeToExcise->_nodeFlag), INDEX_GC_NODE_BRICKED_FLAG, INDEX_GC_NODE_NORMAL_FLAG);
|
||||
if (bricked > 1) {
|
||||
ok = ok && TRI_CompareAndSwapIntegerUInt32 (&(prevNode->_nodeFlag), INDEX_GC_NODE_BRICKED_FLAG, INDEX_GC_NODE_NORMAL_FLAG);
|
||||
if (bricked > 2) {
|
||||
ok = TRI_CompareAndSwapIntegerUInt32 (&(nextNode->_nodeFlag), INDEX_GC_NODE_BRICKED_FLAG, INDEX_GC_NODE_NORMAL_FLAG);
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
LOG_ERROR("ExciseNodeBrickUndo failed here");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
static int ExciseNodeSwapPointers(linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode) {
|
||||
bool ok;
|
||||
|
||||
ok = TRI_CompareAndSwapPointer(&(prevNode->_next), nodeToExcise, nextNode);
|
||||
if (!ok) { return 0; }
|
||||
|
||||
ok = TRI_CompareAndSwapPointer(&(nextNode->_prev), nodeToExcise, prevNode);
|
||||
if (!ok) { return 1; }
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ExciseNodeSwapPointersUndo(linked_list_node_t* nodeToExcise, linked_list_node_t* prevNode, linked_list_node_t* nextNode, int swaped) {
|
||||
bool ok;
|
||||
|
||||
if (swaped > 0) {
|
||||
ok = TRI_CompareAndSwapPointer(&(prevNode->_next), nextNode, nodeToExcise);
|
||||
if (swaped > 1) {
|
||||
ok = ok && TRI_CompareAndSwapPointer(&(nextNode->_prev), prevNode, nodeToExcise);
|
||||
}
|
||||
if (!ok) {
|
||||
LOG_ERROR("ExciseNodeSwapPointersUndo failed here");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -46,22 +46,25 @@ extern "C" {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_index_s;
|
||||
struct TRI_transaction_context_s;
|
||||
|
||||
typedef struct TRI_index_gc_s {
|
||||
struct TRI_index_s* _index; // index which requires rubbish collection
|
||||
uint8_t _passes; // the number of passes to complete the rubbish collection
|
||||
uint8_t _lastPass; // the last pass performed (_lastPass = 0, implies no passes performed)
|
||||
uint64_t _transID; // the transaction id which must have completed before the current pass can come into effect
|
||||
void* _data; // storage of data which may be required by the index
|
||||
void* _index; // struct TRI_index_s* index which requires rubbish collection
|
||||
uint8_t _passes; // the number of passes to complete the rubbish collection
|
||||
uint8_t _lastPass; // the last pass performed (_lastPass = 0, implies no passes performed)
|
||||
uint64_t _transID; // the transaction id which must have completed before the current pass can come into effect
|
||||
void* _data; // storage of data which may be required by the index
|
||||
int (*_collectGarbage) (struct TRI_index_gc_s*); // callback which actually does the work (defined where the index is defined)
|
||||
} TRI_index_gc_t;
|
||||
|
||||
|
||||
int TRI_AddToIndexGC (TRI_index_gc_t*); // adds an item to the rubbish collection linked list
|
||||
int TRI_AddToIndexGC (TRI_index_gc_t*); // adds an item to the rubbish collection linked list
|
||||
|
||||
void TRI_IndexGCVocBase (void*); // essentially a loop called by the thread and runs 'forever'
|
||||
int TRI_ExpungeIndexGC (TRI_index_gc_t*); // removes all references of an index from the garbage collector
|
||||
|
||||
uint64_t TRI_GetIndexGCSize (void); // returns the number of entries in the linked list used by the garabage collector
|
||||
|
||||
void TRI_IndexGCVocBase (void*); // essentially a loop called by the thread and runs 'forever'
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief index garbage collector event loop
|
||||
|
|
10
build_win.h
10
build_win.h
|
@ -1,14 +1,14 @@
|
|||
#ifdef _WIN64
|
||||
#define WINDOWS_ARRANGO_VERSION_NUMBER 1.3.0
|
||||
#define WINDOWS_ARRANGO_VERSION_NUMBER 1.4
|
||||
#ifdef _DEBUG
|
||||
#define TRIAGENS_VERSION "1.3.0 [WIN64-DEBUG ALPHA 2]"
|
||||
#define TRIAGENS_VERSION "1.4 [WIN64-DEBUG DEVEL]"
|
||||
#else
|
||||
#define TRIAGENS_VERSION "1.3.0 [WIN64-RELEASE ALPHA 2]"
|
||||
#define TRIAGENS_VERSION "1.4 [WIN64-RELEASE DEVEL]"
|
||||
#endif
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#define TRIAGENS_VERSION "1.3.0 [WIN32-DEBUG ALPHA 2]"
|
||||
#define TRIAGENS_VERSION "1.4 [WIN32-DEBUG DEVEL]"
|
||||
#else
|
||||
#define TRIAGENS_VERSION "1.3.0 [WIN32-RELEASE ALPHA 2]"
|
||||
#define TRIAGENS_VERSION "1.4 [WIN32-RELEASE DEVEL]"
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -167,6 +167,8 @@
|
|||
"WARNING_ARANGO_INDEX_SKIPLIST_INSERT_CAS_FAILURE" : { "code" : 3304, "message" : "skiplist index insertion warning - CAS failure while attempting to insert document" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_MISSING" : { "code" : 3311, "message" : "skiplist index remove failure - item missing in index" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE" : { "code" : 3313, "message" : "skiplist index remove warning - CAS failure while attempting to remove document" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED" : { "code" : 3315, "message" : "skiplist index remove failure - item inserted post this transaction in the index" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED" : { "code" : 3317, "message" : "skiplist index remove failure - item removed prior this transaction in the index" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_DOCUMENT_ATTRIBUTE_MISSING" : { "code" : 3400, "message" : "bitarray index insertion warning - attribute missing in document" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_UPDATE_ATTRIBUTE_MISSING" : { "code" : 3402, "message" : "bitarray index update warning - attribute missing in revised document" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_REMOVE_ITEM_MISSING" : { "code" : 3411, "message" : "bitarray index remove failure - item missing in index" },
|
||||
|
@ -176,7 +178,8 @@
|
|||
"RESULT_KEY_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because key already exists" },
|
||||
"RESULT_ELEMENT_EXISTS" : { "code" : 10001, "message" : "element not inserted into structure, because it already exists" },
|
||||
"RESULT_KEY_NOT_FOUND" : { "code" : 10002, "message" : "key not found in structure" },
|
||||
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10003, "message" : "element not found in structure" }
|
||||
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10003, "message" : "element not found in structure" },
|
||||
"WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN" : { "code" : 11000, "message" : "the index garbage collector has shutdown and no further entries can be processed" }
|
||||
};
|
||||
}());
|
||||
|
||||
|
|
|
@ -167,6 +167,8 @@
|
|||
"WARNING_ARANGO_INDEX_SKIPLIST_INSERT_CAS_FAILURE" : { "code" : 3304, "message" : "skiplist index insertion warning - CAS failure while attempting to insert document" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_MISSING" : { "code" : 3311, "message" : "skiplist index remove failure - item missing in index" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE" : { "code" : 3313, "message" : "skiplist index remove warning - CAS failure while attempting to remove document" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED" : { "code" : 3315, "message" : "skiplist index remove failure - item inserted post this transaction in the index" },
|
||||
"WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED" : { "code" : 3317, "message" : "skiplist index remove failure - item removed prior this transaction in the index" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_DOCUMENT_ATTRIBUTE_MISSING" : { "code" : 3400, "message" : "bitarray index insertion warning - attribute missing in document" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_UPDATE_ATTRIBUTE_MISSING" : { "code" : 3402, "message" : "bitarray index update warning - attribute missing in revised document" },
|
||||
"WARNING_ARANGO_INDEX_BITARRAY_REMOVE_ITEM_MISSING" : { "code" : 3411, "message" : "bitarray index remove failure - item missing in index" },
|
||||
|
@ -176,7 +178,8 @@
|
|||
"RESULT_KEY_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because key already exists" },
|
||||
"RESULT_ELEMENT_EXISTS" : { "code" : 10001, "message" : "element not inserted into structure, because it already exists" },
|
||||
"RESULT_KEY_NOT_FOUND" : { "code" : 10002, "message" : "key not found in structure" },
|
||||
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10003, "message" : "element not found in structure" }
|
||||
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10003, "message" : "element not found in structure" },
|
||||
"WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN" : { "code" : 11000, "message" : "the index garbage collector has shutdown and no further entries can be processed" }
|
||||
};
|
||||
}());
|
||||
|
||||
|
|
|
@ -251,6 +251,8 @@ WARNING_ARANGO_INDEX_SKIPLIST_UPDATE_ATTRIBUTE_MISSING,3302,"skiplist index upda
|
|||
WARNING_ARANGO_INDEX_SKIPLIST_INSERT_CAS_FAILURE,3304,"skiplist index insertion warning - CAS failure while attempting to insert document","Will be raised when an attempt to insert a document into a skiplist index fails due to repeated CAS failures/clashes."
|
||||
WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_MISSING,3311,"skiplist index remove failure - item missing in index","Will be raised when an attempt to remove a document from a skiplist index fails when document can not be located within that index."
|
||||
WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE,3313,"skiplist index remove warning - CAS failure while attempting to remove document","Will be raised when an attempt to remove a document into a skiplist index fails due to repeated CAS failures/clashes."
|
||||
WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED,3315,"skiplist index remove failure - item inserted post this transaction in the index","Will be raised when an attempt to remove a document from a skiplist index fails due to the fact that the document to be removed was inserted in a transaction post this removal transaction."
|
||||
WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED,3317,"skiplist index remove failure - item removed prior this transaction in the index","Will be raised when an attempt to remove a document from a skiplist index fails due to the fact that the document to be removed was removed in a transaction prior this removal transaction."
|
||||
|
||||
|
||||
WARNING_ARANGO_INDEX_BITARRAY_DOCUMENT_ATTRIBUTE_MISSING,3400,"bitarray index insertion warning - attribute missing in document","Will be raised when an attempt to insert a document into a bitarray index is caused by in the document not having one or more attributes which are required by the bitarray index."
|
||||
|
@ -269,3 +271,9 @@ RESULT_KEY_EXISTS,10000,"element not inserted into structure, because key alread
|
|||
RESULT_ELEMENT_EXISTS,10001,"element not inserted into structure, because it already exists","Will be returned if the element was not insert because it already exists."
|
||||
RESULT_KEY_NOT_FOUND,10002,"key not found in structure","Will be returned if the key was not found in the structure."
|
||||
RESULT_ELEMENT_NOT_FOUND,10003,"element not found in structure","Will be returned if the element was not found in the structure."
|
||||
|
||||
################################################################################
|
||||
## WARNING when a thread is in a state of shutdown
|
||||
################################################################################
|
||||
|
||||
WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN,11000,"the index garbage collector has shutdown and no further entries can be processed","Will be raised when an attempt to add an item to the index garbage collector fails due to the fact that the state of the collector is in shutdown mode."
|
||||
|
|
|
@ -1080,7 +1080,7 @@ int TRI_VerifyLockFile (char const* filename) {
|
|||
TRI_CLOSE(fd);
|
||||
|
||||
// file empty or pid too long
|
||||
if (n == 0 || n == sizeof(buf)) {
|
||||
if (n == 0 || n == sizeof(buffer)) {
|
||||
return TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER);
|
||||
}
|
||||
|
||||
|
|
|
@ -574,7 +574,7 @@ bool TRI_CompareAndSwapIntegerInt32 (volatile int32_t* theValue, int32_t oldValu
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerInt32 implementation defined
|
||||
#endif
|
||||
|
@ -584,7 +584,7 @@ bool TRI_CompareIntegerInt32 (volatile int32_t* theValue, int32_t oldValue) {
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap32Barrier(oldValue, oldValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, oldValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, oldValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerInt32 implementation defined
|
||||
#endif
|
||||
|
@ -594,7 +594,7 @@ bool TRI_CompareAndSwapIntegerUInt32 (volatile uint32_t* theValue, uint32_t oldV
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap32Barrier((int32_t)(oldValue), (int32_t)(newValue), (volatile int32_t*)(theValue));
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerUInt32 implementation defined
|
||||
#endif
|
||||
|
@ -604,7 +604,7 @@ bool TRI_CompareIntegerUInt32 (volatile uint32_t* theValue, uint32_t oldValue) {
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap32Barrier((int32_t)(oldValue), (int32_t)(oldValue), (volatile int32_t*)(theValue));
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, oldValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, oldValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerUInt32 implementation defined
|
||||
#endif
|
||||
|
@ -618,7 +618,7 @@ bool TRI_CompareAndSwapIntegerInt64 (volatile int64_t* theValue, int64_t oldValu
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap64Barrier(oldValue, newValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerInt64 implementation defined
|
||||
#endif
|
||||
|
@ -628,7 +628,7 @@ bool TRI_CompareIntegerInt64 (volatile int64_t* theValue, int64_t oldValue) {
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap64Barrier(oldValue, oldValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, oldValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, oldValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerInt64 implementation defined
|
||||
#endif
|
||||
|
@ -638,7 +638,7 @@ bool TRI_CompareAndSwapIntegerUInt64 (volatile uint64_t* theValue, uint64_t oldV
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap64Barrier((int64_t)(oldValue), (int64_t)(newValue), (volatile int64_t*)(theValue));
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerUInt64 implementation defined
|
||||
#endif
|
||||
|
@ -648,7 +648,7 @@ bool TRI_CompareIntegerUInt64 (volatile uint64_t* theValue, uint64_t oldValue) {
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwap64Barrier((int64_t)(oldValue), (int64_t)(oldValue), (volatile int64_t*)(theValue));
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, oldValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, oldValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapIntegerUInt64 implementation defined
|
||||
#endif
|
||||
|
@ -662,7 +662,7 @@ bool TRI_CompareAndSwapPointer(void* volatile* theValue, void* oldValue, void* n
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwapPtrBarrier(oldValue, newValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapPointer implementation defined
|
||||
#endif
|
||||
|
@ -672,7 +672,7 @@ bool TRI_ComparePointer(void* volatile* theValue, void* oldValue) {
|
|||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
return OSAtomicCompareAndSwapPtrBarrier(oldValue, oldValue, theValue);
|
||||
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
return __sync_val_compare_and_swap(theValue, oldValue, oldValue);
|
||||
return __sync_bool_compare_and_swap(theValue, oldValue, oldValue);
|
||||
#else
|
||||
#error No TRI_CompareAndSwapPointer implementation defined
|
||||
#endif
|
||||
|
|
|
@ -163,6 +163,8 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(WARNING_ARANGO_INDEX_SKIPLIST_INSERT_CAS_FAILURE, "skiplist index insertion warning - CAS failure while attempting to insert document");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_MISSING, "skiplist index remove failure - item missing in index");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE, "skiplist index remove warning - CAS failure while attempting to remove document");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED, "skiplist index remove failure - item inserted post this transaction in the index");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED, "skiplist index remove failure - item removed prior this transaction in the index");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_BITARRAY_DOCUMENT_ATTRIBUTE_MISSING, "bitarray index insertion warning - attribute missing in document");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_BITARRAY_UPDATE_ATTRIBUTE_MISSING, "bitarray index update warning - attribute missing in revised document");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_BITARRAY_REMOVE_ITEM_MISSING, "bitarray index remove failure - item missing in index");
|
||||
|
@ -173,6 +175,7 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(RESULT_ELEMENT_EXISTS, "element not inserted into structure, because it already exists");
|
||||
REG_ERROR(RESULT_KEY_NOT_FOUND, "key not found in structure");
|
||||
REG_ERROR(RESULT_ELEMENT_NOT_FOUND, "element not found in structure");
|
||||
REG_ERROR(WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN, "the index garbage collector has shutdown and no further entries can be processed");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -371,6 +371,14 @@ extern "C" {
|
|||
/// - 3313: @LIT{skiplist index remove warning - CAS failure while attempting to remove document}
|
||||
/// Will be raised when an attempt to remove a document into a skiplist index
|
||||
/// fails due to repeated CAS failures/clashes.
|
||||
/// - 3315: @LIT{skiplist index remove failure - item inserted post this transaction in the index}
|
||||
/// Will be raised when an attempt to remove a document from a skiplist index
|
||||
/// fails due to the fact that the document to be removed was inserted in a
|
||||
/// transaction post this removal transaction.
|
||||
/// - 3317: @LIT{skiplist index remove failure - item removed prior this transaction in the index}
|
||||
/// Will be raised when an attempt to remove a document from a skiplist index
|
||||
/// fails due to the fact that the document to be removed was removed in a
|
||||
/// transaction prior this removal transaction.
|
||||
/// - 3400: @LIT{bitarray index insertion warning - attribute missing in document}
|
||||
/// Will be raised when an attempt to insert a document into a bitarray index
|
||||
/// is caused by in the document not having one or more attributes which are
|
||||
|
@ -401,6 +409,10 @@ extern "C" {
|
|||
/// Will be returned if the key was not found in the structure.
|
||||
/// - 10003: @LIT{element not found in structure}
|
||||
/// Will be returned if the element was not found in the structure.
|
||||
/// - 11000: @LIT{the index garbage collector has shutdown and no further entries can be processed}
|
||||
/// Will be raised when an attempt to add an item to the index garbage
|
||||
/// collector fails due to the fact that the state of the collector is in
|
||||
/// shutdown mode.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1989,6 +2001,32 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_CAS_FAILURE (3313)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3315: WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED
|
||||
///
|
||||
/// skiplist index remove failure - item inserted post this transaction in the
|
||||
/// index
|
||||
///
|
||||
/// Will be raised when an attempt to remove a document from a skiplist index
|
||||
/// fails due to the fact that the document to be removed was inserted in a
|
||||
/// transaction post this removal transaction.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_POST_INSERTED (3315)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3317: WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED
|
||||
///
|
||||
/// skiplist index remove failure - item removed prior this transaction in the
|
||||
/// index
|
||||
///
|
||||
/// Will be raised when an attempt to remove a document from a skiplist index
|
||||
/// fails due to the fact that the document to be removed was removed in a
|
||||
/// transaction prior this removal transaction.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WARNING_ARANGO_INDEX_SKIPLIST_REMOVE_ITEM_PRIOR_REMOVED (3317)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3400: WARNING_ARANGO_INDEX_BITARRAY_DOCUMENT_ATTRIBUTE_MISSING
|
||||
///
|
||||
|
@ -2102,6 +2140,19 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_RESULT_ELEMENT_NOT_FOUND (10003)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 11000: WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN
|
||||
///
|
||||
/// the index garbage collector has shutdown and no further entries can be
|
||||
/// processed
|
||||
///
|
||||
/// Will be raised when an attempt to add an item to the index garbage
|
||||
/// collector fails due to the fact that the state of the collector is in
|
||||
/// shutdown mode.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_WARNING_ARANGO_INDEX_GARBAGE_COLLECTOR_SHUTDOWN (11000)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
Loading…
Reference in New Issue