mirror of https://gitee.com/bigwinds/arangodb
fixed memleak
This commit is contained in:
parent
a8d5a06f57
commit
c473e42f77
|
@ -2193,7 +2193,7 @@ static v8::Handle<v8::Value> JS_NextGeneralCursor (v8::Arguments const& argv) {
|
|||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(
|
||||
TRI_CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION,
|
||||
"usage: count()")));
|
||||
"usage: next()")));
|
||||
}
|
||||
|
||||
TRI_vocbase_t* vocbase = GetContextVocBase();
|
||||
|
@ -3400,7 +3400,7 @@ static v8::Handle<v8::Value> JS_CountVocbaseCol (v8::Arguments const& argv) {
|
|||
// READ-LOCK start
|
||||
trx.lockRead();
|
||||
|
||||
size_t s = primary->size(primary);
|
||||
const TRI_voc_size_t s = primary->size(primary);
|
||||
|
||||
trx.finish(res);
|
||||
// READ-LOCK end
|
||||
|
|
|
@ -206,7 +206,7 @@ typedef struct TRI_col_header_marker_s {
|
|||
char _padding_col_header_marker[4];
|
||||
#endif
|
||||
|
||||
TRI_voc_cid_t _cid; // 8 bytes
|
||||
TRI_voc_cid_t _cid; // 8 bytes
|
||||
}
|
||||
TRI_col_header_marker_t;
|
||||
|
||||
|
|
|
@ -312,16 +312,16 @@ TRI_datafile_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_df_marker_s {
|
||||
TRI_voc_size_t _size; // 4 bytes, must be supplied
|
||||
TRI_voc_crc_t _crc; // 4 bytes, will be generated
|
||||
TRI_voc_size_t _size; // 4 bytes, must be supplied
|
||||
TRI_voc_crc_t _crc; // 4 bytes, will be generated
|
||||
|
||||
TRI_df_marker_type_t _type; // 4 bytes, must be supplied
|
||||
TRI_df_marker_type_t _type; // 4 bytes, must be supplied
|
||||
|
||||
#ifdef TRI_PADDING_32
|
||||
char _padding_df_marker[4];
|
||||
#endif
|
||||
|
||||
TRI_voc_tick_t _tick; // 8 bytes, will be generated
|
||||
TRI_voc_tick_t _tick; // 8 bytes, will be generated
|
||||
}
|
||||
TRI_df_marker_t;
|
||||
|
||||
|
|
|
@ -369,12 +369,10 @@ static int CloneDocumentMarker (TRI_df_marker_t const* original,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// copy non-changed data (e.g. key(s)) from old marker into new marker
|
||||
memcpy(marker, original, baseLength);
|
||||
|
||||
// set the marker type, size, revision id etc.
|
||||
tick = TRI_NewTickVocBase();
|
||||
TRI_InitMarker(&marker->base, markerType, *totalSize, tick);
|
||||
// copy non-changed data (e.g. key(s)) from old marker into new marker
|
||||
TRI_CloneMarker(&marker->base, original, baseLength, *totalSize, tick);
|
||||
|
||||
marker->_rid = tick;
|
||||
marker->_shape = shaped->_sid;
|
||||
|
||||
|
|
|
@ -36,11 +36,33 @@
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clones a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CloneMarker (TRI_df_marker_t* dst,
|
||||
TRI_df_marker_t const* src,
|
||||
TRI_voc_size_t copyLength,
|
||||
TRI_voc_size_t newSize,
|
||||
TRI_voc_tick_t tick) {
|
||||
TRI_ASSERT_DEBUG(src != NULL);
|
||||
TRI_ASSERT_DEBUG(dst != NULL);
|
||||
TRI_ASSERT_DEBUG(copyLength > 0);
|
||||
TRI_ASSERT_DEBUG(newSize > 0);
|
||||
TRI_ASSERT_DEBUG(tick > 0);
|
||||
|
||||
memcpy(dst, src, copyLength);
|
||||
|
||||
dst->_size = newSize;
|
||||
dst->_crc = 0;
|
||||
dst->_tick = tick;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialises a marker with the most basic information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitMarker (TRI_df_marker_t* const marker,
|
||||
void TRI_InitMarker (TRI_df_marker_t* marker,
|
||||
TRI_df_marker_type_e type,
|
||||
TRI_voc_size_t size,
|
||||
TRI_voc_tick_t tick) {
|
||||
|
@ -49,10 +71,13 @@ void TRI_InitMarker (TRI_df_marker_t* const marker,
|
|||
TRI_ASSERT_DEBUG(size > 0);
|
||||
TRI_ASSERT_DEBUG(tick > 0);
|
||||
|
||||
marker->_type = type;
|
||||
// initialise the basic byytes
|
||||
memset(marker, 0, size);
|
||||
|
||||
marker->_size = size;
|
||||
marker->_tick = tick;
|
||||
marker->_crc = 0;
|
||||
marker->_type = type;
|
||||
marker->_tick = tick;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -45,11 +45,21 @@ extern "C" {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clones a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CloneMarker (TRI_df_marker_t*,
|
||||
TRI_df_marker_t const*,
|
||||
TRI_voc_size_t,
|
||||
TRI_voc_size_t,
|
||||
TRI_voc_tick_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialises a marker with the most basic information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitMarker (TRI_df_marker_t* const,
|
||||
void TRI_InitMarker (TRI_df_marker_t*,
|
||||
TRI_df_marker_type_e,
|
||||
TRI_voc_size_t,
|
||||
TRI_voc_tick_t);
|
||||
|
|
|
@ -184,8 +184,8 @@ static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary,
|
|||
|
||||
|
||||
TRI_InitMarker(&cm.base, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t), TRI_NewTickVocBase());
|
||||
cm._cid = collection->_info._cid;
|
||||
cm._type = (TRI_col_type_t) collection->_info._type;
|
||||
cm._cid = collection->_info._cid;
|
||||
|
||||
res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true);
|
||||
|
||||
|
|
|
@ -50,27 +50,163 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the status of the transaction as a string
|
||||
/// @brief hashes the collection id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char* StatusTransaction (const TRI_transaction_status_e status) {
|
||||
switch (status) {
|
||||
case TRI_TRANSACTION_UNDEFINED:
|
||||
return "undefined";
|
||||
case TRI_TRANSACTION_CREATED:
|
||||
return "created";
|
||||
case TRI_TRANSACTION_RUNNING:
|
||||
return "running";
|
||||
case TRI_TRANSACTION_COMMITTED:
|
||||
return "committed";
|
||||
case TRI_TRANSACTION_ABORTED:
|
||||
return "aborted";
|
||||
case TRI_TRANSACTION_FAILED:
|
||||
return "failed";
|
||||
static uint64_t HashKeyCid (TRI_associative_pointer_t* array, void const* key) {
|
||||
TRI_transaction_cid_t const* k = key;
|
||||
|
||||
return (uint64_t) *k;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the collection id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashElementCid (TRI_associative_pointer_t* array, void const* element) {
|
||||
TRI_transaction_collection_global_t const* e = element;
|
||||
|
||||
return (uint64_t) e->_cid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares a collection id and a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool EqualKeyCid (TRI_associative_pointer_t* array, void const* key, void const* element) {
|
||||
TRI_transaction_cid_t const* k = key;
|
||||
TRI_transaction_collection_global_t const* e = element;
|
||||
|
||||
return *k == e->_cid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a global instance of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_transaction_collection_global_t* CreateGlobalInstance (TRI_transaction_cid_t cid) {
|
||||
TRI_transaction_collection_global_t* globalInstance;
|
||||
|
||||
globalInstance = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_collection_global_t), false);
|
||||
|
||||
if (globalInstance != NULL) {
|
||||
globalInstance->_cid = cid;
|
||||
globalInstance->_lastStartedReader = 0;
|
||||
globalInstance->_lastFinishedReader = 0;
|
||||
globalInstance->_lastStartedWriter = 0;
|
||||
globalInstance->_lastAbortedWriter = 0;
|
||||
globalInstance->_lastFinishedWriter = 0;
|
||||
|
||||
TRI_InitReadWriteLock(&globalInstance->_lock);
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return "unknown";
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a global instance of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void FreeGlobalInstance (TRI_transaction_collection_global_t* globalInstance) {
|
||||
TRI_DestroyReadWriteLock(&globalInstance->_lock);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, globalInstance);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the global instance of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_transaction_collection_global_t* GetGlobalInstance (TRI_transaction_context_t* context,
|
||||
TRI_transaction_cid_t cid,
|
||||
const bool create) {
|
||||
TRI_transaction_collection_global_t* globalInstance;
|
||||
TRI_transaction_collection_global_t* found;
|
||||
|
||||
// acquire a read-lock on the global list of collections
|
||||
TRI_ReadLockReadWriteLock(&context->_collectionsLock);
|
||||
globalInstance = TRI_LookupByKeyAssociativePointer(&context->_collections, &cid);
|
||||
TRI_ReadUnlockReadWriteLock(&context->_collectionsLock);
|
||||
|
||||
if (globalInstance != NULL) {
|
||||
// we already have a global instance
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
// collection not found
|
||||
|
||||
if (! create) {
|
||||
// not asked to create a new global instance
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create a new global instance
|
||||
globalInstance = CreateGlobalInstance(cid);
|
||||
|
||||
if (globalInstance == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// write lock and insert the new instance, but only if no one else has inserted it
|
||||
TRI_WriteLockReadWriteLock(&context->_collectionsLock);
|
||||
found = TRI_InsertKeyAssociativePointer(&context->_collections, &cid, globalInstance, false);
|
||||
TRI_WriteUnlockReadWriteLock(&context->_collectionsLock);
|
||||
|
||||
if (found != NULL) {
|
||||
// someone else inserted another global instance. so we'll return it
|
||||
FreeGlobalInstance(globalInstance);
|
||||
return found;
|
||||
}
|
||||
|
||||
// our own instance has been inserted
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief update the global transaction statistics
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int UpdateGlobalStats (const TRI_transaction_t const* trx,
|
||||
const TRI_transaction_status_e status) {
|
||||
size_t i, n;
|
||||
|
||||
n = trx->_collections._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
TRI_transaction_collection_global_t* globalInstance;
|
||||
|
||||
collection = (TRI_transaction_collection_t*) TRI_AtVectorPointer(&trx->_collections, i);
|
||||
|
||||
globalInstance = collection->_globalInstance;
|
||||
TRI_ASSERT_DEBUG(globalInstance != NULL);
|
||||
|
||||
TRI_WriteLockReadWriteLock(&globalInstance->_lock);
|
||||
|
||||
if (collection->_accessType == TRI_TRANSACTION_READ) {
|
||||
if (status == TRI_TRANSACTION_RUNNING) {
|
||||
globalInstance->_lastStartedReader = trx->_id;
|
||||
}
|
||||
else if (status == TRI_TRANSACTION_ABORTED ||
|
||||
status == TRI_TRANSACTION_COMMITTED) {
|
||||
globalInstance->_lastFinishedReader = trx->_id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (status == TRI_TRANSACTION_RUNNING) {
|
||||
globalInstance->_lastStartedWriter = trx->_id;
|
||||
}
|
||||
else if (status == TRI_TRANSACTION_ABORTED) {
|
||||
globalInstance->_lastAbortedWriter = trx->_id;
|
||||
}
|
||||
else if (status == TRI_TRANSACTION_COMMITTED) {
|
||||
globalInstance->_lastFinishedWriter = trx->_id;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_WriteUnlockReadWriteLock(&globalInstance->_lock);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -100,6 +236,14 @@ TRI_transaction_context_t* TRI_CreateTransactionContext (TRI_vocbase_t* const vo
|
|||
}
|
||||
|
||||
context->_vocbase = vocbase;
|
||||
|
||||
TRI_InitAssociativePointer(&context->_collections,
|
||||
TRI_UNKNOWN_MEM_ZONE,
|
||||
HashKeyCid,
|
||||
HashElementCid,
|
||||
EqualKeyCid,
|
||||
NULL);
|
||||
TRI_InitReadWriteLock(&context->_collectionsLock);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -109,6 +253,9 @@ TRI_transaction_context_t* TRI_CreateTransactionContext (TRI_vocbase_t* const vo
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeTransactionContext (TRI_transaction_context_t* const context) {
|
||||
TRI_DestroyAssociativePointer(&context->_collections);
|
||||
TRI_DestroyReadWriteLock(&context->_collectionsLock);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, context);
|
||||
}
|
||||
|
||||
|
@ -130,8 +277,20 @@ void TRI_FreeTransactionContext (TRI_transaction_context_t* const context) {
|
|||
/// this function gets called for all collections that are dropped
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const context,
|
||||
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* context,
|
||||
const TRI_transaction_cid_t cid) {
|
||||
TRI_transaction_collection_global_t* globalInstance;
|
||||
|
||||
globalInstance = GetGlobalInstance(context, cid, false);
|
||||
|
||||
if (globalInstance != NULL) {
|
||||
// write lock and remove the instance
|
||||
TRI_WriteLockReadWriteLock(&context->_collectionsLock);
|
||||
TRI_RemoveKeyAssociativePointer(&context->_collections, &cid);
|
||||
TRI_WriteUnlockReadWriteLock(&context->_collectionsLock);
|
||||
|
||||
FreeGlobalInstance(globalInstance);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -151,6 +310,30 @@ void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const co
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the status of the transaction as a string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char* StatusTransaction (const TRI_transaction_status_e status) {
|
||||
switch (status) {
|
||||
case TRI_TRANSACTION_UNDEFINED:
|
||||
return "undefined";
|
||||
case TRI_TRANSACTION_CREATED:
|
||||
return "created";
|
||||
case TRI_TRANSACTION_RUNNING:
|
||||
return "running";
|
||||
case TRI_TRANSACTION_COMMITTED:
|
||||
return "committed";
|
||||
case TRI_TRANSACTION_ABORTED:
|
||||
return "aborted";
|
||||
case TRI_TRANSACTION_FAILED:
|
||||
return "failed";
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find a collection in the transaction's list of collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -190,10 +373,18 @@ static TRI_transaction_collection_t* FindCollection (const TRI_transaction_t* co
|
|||
/// @brief create a transaction collection container
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_transaction_collection_t* CreateCollection (const TRI_transaction_cid_t cid,
|
||||
static TRI_transaction_collection_t* CreateCollection (TRI_transaction_context_t* context,
|
||||
const TRI_transaction_cid_t cid,
|
||||
const TRI_transaction_type_e accessType,
|
||||
const int nestingLevel) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
TRI_transaction_collection_global_t* globalInstance;
|
||||
|
||||
globalInstance = GetGlobalInstance(context, cid, true);
|
||||
|
||||
if (globalInstance == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
collection = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_collection_t), false);
|
||||
|
||||
|
@ -203,13 +394,12 @@ static TRI_transaction_collection_t* CreateCollection (const TRI_transaction_cid
|
|||
}
|
||||
|
||||
// initialise collection properties
|
||||
collection->_cid = cid;
|
||||
collection->_accessType = accessType;
|
||||
collection->_nestingLevel = nestingLevel;
|
||||
collection->_collection = NULL;
|
||||
collection->_locked = false;
|
||||
|
||||
collection->_numWrites = 0;
|
||||
collection->_cid = cid;
|
||||
collection->_accessType = accessType;
|
||||
collection->_nestingLevel = nestingLevel;
|
||||
collection->_collection = NULL;
|
||||
collection->_locked = false;
|
||||
collection->_globalInstance = globalInstance;
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
@ -426,8 +616,13 @@ static int UpdateTransactionStatus (TRI_transaction_t* const trx,
|
|||
TRI_ASSERT_DEBUG(status == TRI_TRANSACTION_COMMITTED || status == TRI_TRANSACTION_ABORTED);
|
||||
}
|
||||
|
||||
if (status == TRI_TRANSACTION_RUNNING || status == TRI_TRANSACTION_COMMITTED || status == TRI_TRANSACTION_ABORTED) {
|
||||
// notify all participating collections about the transaction status change
|
||||
if (status == TRI_TRANSACTION_RUNNING ||
|
||||
status == TRI_TRANSACTION_ABORTED ||
|
||||
status == TRI_TRANSACTION_COMMITTED) {
|
||||
// notify all participating collections about the status change
|
||||
UpdateGlobalStats(trx, status);
|
||||
|
||||
// update the global statistics
|
||||
NotifyCollections(trx, status);
|
||||
}
|
||||
|
||||
|
@ -491,9 +686,6 @@ void TRI_FreeTransaction (TRI_transaction_t* const trx) {
|
|||
TRI_AbortTransaction(trx, 0);
|
||||
}
|
||||
|
||||
// TODO: this shouldn't be necessary at all
|
||||
// ReleaseCollections(trx, 0);
|
||||
|
||||
// free all collections
|
||||
i = trx->_collections._length;
|
||||
while (i-- > 0) {
|
||||
|
@ -690,7 +882,7 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
|
|||
}
|
||||
|
||||
// collection was not contained. now create and insert it
|
||||
collection = CreateCollection(cid, accessType, nestingLevel);
|
||||
collection = CreateCollection(trx->_context, cid, accessType, nestingLevel);
|
||||
|
||||
if (collection == NULL) {
|
||||
// out of memory
|
||||
|
|
|
@ -59,6 +59,16 @@ struct TRI_vocbase_col_s;
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef uint64_t TRI_transaction_id_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collection id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef uint64_t TRI_transaction_cid_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -124,18 +134,10 @@ TRI_transaction_status_e;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_transaction_context_s {
|
||||
//TRI_transaction_id_t _id; // last transaction id assigned
|
||||
|
||||
TRI_read_write_lock_t _rwLock; // lock used to either simulatensously read this structure,
|
||||
// or uniquely modify this structure
|
||||
#if 0
|
||||
TRI_mutex_t _lock; // lock used to serialize starting/stopping transactions
|
||||
TRI_mutex_t _collectionLock; // lock used when accessing _collections
|
||||
TRI_transaction_list_t _readTransactions; // global list of currently ongoing read transactions
|
||||
TRI_transaction_list_t _writeTransactions; // global list of currently ongoing write transactions
|
||||
TRI_associative_pointer_t _collections; // list of collections (TRI_transaction_collection_global_t)
|
||||
#endif
|
||||
struct TRI_vocbase_s* _vocbase; // pointer to vocbase
|
||||
TRI_associative_pointer_t _collections;
|
||||
TRI_read_write_lock_t _collectionsLock;
|
||||
|
||||
struct TRI_vocbase_s* _vocbase;
|
||||
}
|
||||
TRI_transaction_context_t;
|
||||
|
||||
|
@ -182,7 +184,7 @@ void TRI_FreeTransactionContext (TRI_transaction_context_t* const);
|
|||
/// this function must be called for all collections that are dropped
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const,
|
||||
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t*,
|
||||
const TRI_transaction_cid_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -202,17 +204,35 @@ void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const,
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global instance of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_transaction_collection_global_s {
|
||||
TRI_transaction_cid_t _cid;
|
||||
|
||||
TRI_read_write_lock_t _lock;
|
||||
|
||||
TRI_transaction_id_t _lastStartedReader;
|
||||
TRI_transaction_id_t _lastFinishedReader;
|
||||
|
||||
TRI_transaction_id_t _lastStartedWriter;
|
||||
TRI_transaction_id_t _lastAbortedWriter;
|
||||
TRI_transaction_id_t _lastFinishedWriter;
|
||||
}
|
||||
TRI_transaction_collection_global_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collection used in a transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_transaction_collection_s {
|
||||
TRI_transaction_cid_t _cid; // collection id
|
||||
TRI_transaction_type_e _accessType; // access type (read|write)
|
||||
int _nestingLevel; // the transaction level that added this collection
|
||||
struct TRI_vocbase_col_s* _collection; // vocbase collection pointer
|
||||
uint64_t _numWrites; // number of writes performed for the collection
|
||||
bool _locked; // collection lock flag
|
||||
TRI_transaction_cid_t _cid; // collection id
|
||||
TRI_transaction_type_e _accessType; // access type (read|write)
|
||||
int _nestingLevel; // the transaction level that added this collection
|
||||
struct TRI_vocbase_col_s* _collection; // vocbase collection pointer
|
||||
TRI_transaction_collection_global_t* _globalInstance; // pointer to the global instance
|
||||
bool _locked; // collection lock flag
|
||||
}
|
||||
TRI_transaction_collection_t;
|
||||
|
||||
|
@ -238,14 +258,13 @@ TRI_transaction_hint_e;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_transaction_s {
|
||||
TRI_transaction_context_t* _context; // global context object
|
||||
// TODO: fix
|
||||
uint64_t _id;
|
||||
TRI_transaction_type_e _type; // access type (read|write)
|
||||
TRI_transaction_status_e _status; // current status
|
||||
TRI_vector_pointer_t _collections; // list of participating collections
|
||||
TRI_transaction_hint_t _hints; // hints;
|
||||
int _nestingLevel;
|
||||
TRI_transaction_context_t* _context; // global context object
|
||||
TRI_transaction_id_t _id;
|
||||
TRI_transaction_type_e _type; // access type (read|write)
|
||||
TRI_transaction_status_e _status; // current status
|
||||
TRI_vector_pointer_t _collections; // list of participating collections
|
||||
TRI_transaction_hint_t _hints; // hints;
|
||||
int _nestingLevel;
|
||||
}
|
||||
TRI_transaction_t;
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ static TRI_spin_t TickLock;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the auth info
|
||||
/// @brief hashes the auth info
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashKeyAuthInfo (TRI_associative_pointer_t* array, void const* key) {
|
||||
|
@ -111,7 +111,7 @@ static uint64_t HashKeyAuthInfo (TRI_associative_pointer_t* array, void const* k
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the auth info
|
||||
/// @brief hashes the auth info
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashElementAuthInfo (TRI_associative_pointer_t* array, void const* element) {
|
||||
|
@ -132,7 +132,7 @@ static bool EqualKeyAuthInfo (TRI_associative_pointer_t* array, void const* key,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the collection id
|
||||
/// @brief hashes the collection id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashKeyCid (TRI_associative_pointer_t* array, void const* key) {
|
||||
|
@ -142,7 +142,7 @@ static uint64_t HashKeyCid (TRI_associative_pointer_t* array, void const* key) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the collection id
|
||||
/// @brief hashes the collection id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashElementCid (TRI_associative_pointer_t* array, void const* element) {
|
||||
|
@ -163,7 +163,7 @@ static bool EqualKeyCid (TRI_associative_pointer_t* array, void const* key, void
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the collection name
|
||||
/// @brief hashes the collection name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashKeyCollectionName (TRI_associative_pointer_t* array, void const* key) {
|
||||
|
@ -173,7 +173,7 @@ static uint64_t HashKeyCollectionName (TRI_associative_pointer_t* array, void co
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashs the collection name
|
||||
/// @brief hashes the collection name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashElementCollectionName (TRI_associative_pointer_t* array, void const* element) {
|
||||
|
@ -1362,6 +1362,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase) {
|
|||
TRI_vocbase_col_t* collection;
|
||||
|
||||
collection = (TRI_vocbase_col_t*) vocbase->_deadCollections._buffer[i];
|
||||
TRI_RemoveCollectionTransactionContext(vocbase->_transactionContext, collection->_cid);
|
||||
FreeCollection(vocbase, collection);
|
||||
}
|
||||
|
||||
|
@ -1370,6 +1371,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase) {
|
|||
TRI_vocbase_col_t* collection;
|
||||
|
||||
collection = (TRI_vocbase_col_t*) vocbase->_collections._buffer[i];
|
||||
TRI_RemoveCollectionTransactionContext(vocbase->_transactionContext, collection->_cid);
|
||||
FreeCollection(vocbase, collection);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue