Exemple #1
0
void TRI_FreeShadowGeneralCursor (void* data) {
  TRI_general_cursor_t* cursor = (TRI_general_cursor_t*) data;

  TRI_FreeGeneralCursor(cursor);
}
void TRI_CleanupGeneralCursor (TRI_general_cursor_store_t* store,
                               bool force) {
  double compareStamp = TRI_microtime();
  size_t deleteCount = 0;

  // we need an exclusive lock on the index
  TRI_LockSpin(&store->_lock);

  if (store->_ids._nrUsed == 0) {
    // store is empty, nothing to do!
    TRI_UnlockSpin(&store->_lock);
    return;
  }

  LOG_TRACE("cleaning shadows. in store: %ld", (unsigned long) store->_ids._nrUsed);

  // loop until there's nothing to delete or
  // we have deleted CURSOR_MAX_DELETE elements
  while (deleteCount++ < CURSOR_MAX_DELETE || force) {
    bool deleted = false;
    size_t i;

    for (i = 0; i < store->_ids._nrAlloc; i++) {
      // enum all cursors
      TRI_general_cursor_t* cursor = (TRI_general_cursor_t*) store->_ids._table[i];

      if (cursor == NULL) {
        continue;
      }

      TRI_LockSpin(&cursor->_lock);

      if (force ||
          (cursor->_usage._refCount == 0 &&
           (cursor->_usage._isDeleted || cursor->_expires < compareStamp))) {
        LOG_TRACE("cleaning cursor %p, id: %llu, rc: %d, expires: %d, deleted: %d",
                  cursor,
                  (unsigned long long) cursor->_id,
                  (int) cursor->_usage._refCount,
                  (int) cursor->_expires,
                  (int) cursor->_usage._isDeleted);

        TRI_RemoveKeyAssociativePointer(&store->_ids, &cursor->_id);
        TRI_UnlockSpin(&cursor->_lock);
        TRI_FreeGeneralCursor(cursor);
        deleted = true;

        // the remove might reposition elements in the container.
        // therefore break here and start iteration anew
        break;
      }

      TRI_UnlockSpin(&cursor->_lock);
    }

    if (! deleted) {
      // we did not find anything to delete, so give up
      break;
    }
  }

  // release lock
  TRI_UnlockSpin(&store->_lock);
}