static int ApplyCap (TRI_cap_constraint_t* cap, TRI_document_collection_t* document, TRI_transaction_collection_t* trxCollection) { TRI_headers_t* headers = document->_headersPtr; // PROTECTED by trx in trxCollection size_t currentCount = headers->count(); int64_t currentSize = headers->size(); int res = TRI_ERROR_NO_ERROR; // delete while at least one of the constraints is still violated while ((cap->_count > 0 && currentCount > cap->_count) || (cap->_size > 0 && currentSize > cap->_size)) { TRI_doc_mptr_t* oldest = headers->front(); if (oldest != nullptr) { TRI_ASSERT(oldest->getDataPtr() != nullptr); // ONLY IN INDEX, PROTECTED by RUNTIME size_t oldSize = ((TRI_df_marker_t*) (oldest->getDataPtr()))->_size; // ONLY IN INDEX, PROTECTED by RUNTIME TRI_ASSERT(oldSize > 0); if (trxCollection != nullptr) { res = TRI_DeleteDocumentDocumentCollection(trxCollection, nullptr, oldest); if (res != TRI_ERROR_NO_ERROR) { LOG_WARNING("cannot cap collection: %s", TRI_errno_string(res)); break; } } else { headers->unlink(oldest); } currentCount--; currentSize -= (int64_t) oldSize; } else { // we should not get here LOG_WARNING("logic error in %s", __FUNCTION__); break; } } return res; }
static int ApplyCap (TRI_cap_constraint_t* cap, TRI_primary_collection_t* primary, TRI_transaction_collection_t* trxCollection) { TRI_document_collection_t* document; TRI_headers_t* headers; size_t count; int res; document = (TRI_document_collection_t*) primary; headers = document->_headers; count = headers->count(headers); res = TRI_ERROR_NO_ERROR; while (count > cap->_size) { TRI_doc_mptr_t* oldest = headers->front(headers); if (oldest != NULL) { if (trxCollection != NULL) { res = TRI_DeleteDocumentDocumentCollection(trxCollection, NULL, oldest); if (res != TRI_ERROR_NO_ERROR) { LOG_WARNING("cannot cap collection: %s", TRI_errno_string(res)); break; } } else { headers->unlink(headers, oldest); } count--; } else { // we should not get here LOG_WARNING("logic error in %s", __FUNCTION__); break; } } return res; }
static int InitialiseCap (TRI_cap_constraint_t* cap, TRI_document_collection_t* document) { TRI_ASSERT(cap->_count > 0 || cap->_size > 0); TRI_headers_t* headers = document->_headersPtr; // ONLY IN INDEX (CAP) size_t currentCount = headers->count(); int64_t currentSize = headers->size(); if ((cap->_count > 0 && currentCount <= cap->_count) && (cap->_size > 0 && currentSize <= cap->_size)) { // nothing to do return TRI_ERROR_NO_ERROR; } else { TRI_vocbase_t* vocbase = document->_vocbase; TRI_voc_cid_t cid = document->_info._cid; triagens::arango::SingleCollectionWriteTransaction<UINT64_MAX> trx(new triagens::arango::StandaloneTransactionContext(), vocbase, cid); trx.addHint(TRI_TRANSACTION_HINT_LOCK_NEVER, false); trx.addHint(TRI_TRANSACTION_HINT_NO_BEGIN_MARKER, false); trx.addHint(TRI_TRANSACTION_HINT_NO_ABORT_MARKER, false); trx.addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION, false); // this is actually not true, but necessary to create trx id 0 int res = trx.begin(); if (res != TRI_ERROR_NO_ERROR) { return res; } TRI_transaction_collection_t* trxCollection = trx.trxCollection(); res = ApplyCap(cap, document, trxCollection); res = trx.finish(res); return res; } }
static int InitialiseCap (TRI_cap_constraint_t* cap, TRI_primary_collection_t* primary) { TRI_document_collection_t* document; TRI_headers_t* headers; size_t count; TRI_ASSERT_MAINTAINER(cap->_size > 0); document = (TRI_document_collection_t*) primary; headers = document->_headers; count = headers->count(headers); if (count <= cap->_size) { // nothing to do return TRI_ERROR_NO_ERROR; } else { TRI_vocbase_t* vocbase; TRI_transaction_t* trx; TRI_transaction_collection_t* trxCollection; TRI_voc_cid_t cid; int res; vocbase = primary->base._vocbase; cid = primary->base._info._cid; trx = TRI_CreateTransaction(vocbase->_transactionContext, 0.0, false); if (trx == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } res = TRI_AddCollectionTransaction(trx, cid, TRI_TRANSACTION_WRITE, TRI_TRANSACTION_TOP_LEVEL); if (res == TRI_ERROR_NO_ERROR) { trxCollection = TRI_GetCollectionTransaction(trx, cid, TRI_TRANSACTION_WRITE); if (trxCollection != NULL) { res = TRI_BeginTransaction(trx, (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_LOCK_NEVER, TRI_TRANSACTION_TOP_LEVEL); if (res == TRI_ERROR_NO_ERROR) { res = ApplyCap(cap, primary, trxCollection); if (res == TRI_ERROR_NO_ERROR) { res = TRI_CommitTransaction(trx, TRI_TRANSACTION_TOP_LEVEL); } else { TRI_AbortTransaction(trx, TRI_TRANSACTION_TOP_LEVEL); } } } else { res = TRI_ERROR_INTERNAL; } } TRI_FreeTransaction(trx); return res; } }