예제 #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;
}
예제 #2
0
TRI_doc_mptr_t* TRI_headers_t::request (size_t size) {
  TRI_doc_mptr_t* header;

  TRI_ASSERT(size > 0);

  if (_freelist == nullptr) {
    size_t blockSize = GetBlockSize(_blocks._length);
    TRI_ASSERT(blockSize > 0);

    TRI_doc_mptr_t* begin;
    try {
      begin = new TRI_doc_mptr_t[blockSize];
    }
    catch (std::exception&) {
      begin = nullptr;
    }

    // out of memory
    if (begin == nullptr) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
      return nullptr;
    }

    TRI_doc_mptr_t* ptr = begin + (blockSize - 1);

    header = nullptr;

    for (;  begin <= ptr;  ptr--) {
      ptr->setDataPtr(header); // ONLY IN HEADERS
      header = ptr;
    }

    _freelist = header;

    TRI_PushBackVectorPointer(&_blocks, begin);
  }

  TRI_ASSERT(_freelist != nullptr);

  TRI_doc_mptr_t* result = const_cast<TRI_doc_mptr_t*>(_freelist);
  TRI_ASSERT(result != nullptr);

  _freelist = static_cast<TRI_doc_mptr_t const*>(result->getDataPtr()); // ONLY IN HEADERS, PROTECTED by RUNTIME
  result->setDataPtr(nullptr); // ONLY IN HEADERS

  // put new header at the end of the list
  if (_begin == nullptr) {
    // list of headers is empty
    TRI_ASSERT(_nrLinked == 0);
    TRI_ASSERT(_totalSize == 0);

    _begin = result;
    _end   = result;

    result->_prev   = nullptr;
    result->_next   = nullptr;
  }
  else {
    // list is not empty
    TRI_ASSERT(_nrLinked > 0);
    TRI_ASSERT(_totalSize > 0);
    TRI_ASSERT(_nrAllocated > 0);
    TRI_ASSERT(_begin != nullptr);
    TRI_ASSERT(_end != nullptr);

    _end->_next   = result;
    result->_prev = _end;
    result->_next = nullptr;
    _end          = result;
  }

  _nrAllocated++;
  _nrLinked++;
  _totalSize += (int64_t) TRI_DF_ALIGN_BLOCK(size);

  return result;
}