Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
  }
}
Example #4
0
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;
  }
}