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); }