void TRI_CompactorVocBase (void* data) { TRI_vocbase_t* vocbase = data; TRI_vector_pointer_t collections; assert(vocbase->_active); TRI_InitVectorPointer(&collections, TRI_UNKNOWN_MEM_ZONE); while (true) { size_t n; size_t i; TRI_col_type_e type; // keep initial _active value as vocbase->_active might change during compaction loop int active = vocbase->_active; if (active == 2) { // shadows must be cleaned before collections are handled // otherwise the shadows might still hold barriers on collections // and collections cannot be closed properly CleanupShadows(vocbase, true); } // copy all collections TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase); TRI_CopyDataVectorPointer(&collections, &vocbase->_collections); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase); n = collections._length; for (i = 0; i < n; ++i) { TRI_vocbase_col_t* collection; TRI_doc_collection_t* doc; collection = collections._buffer[i]; TRI_READ_LOCK_STATUS_VOCBASE_COL(collection); doc = collection->_collection; if (doc == NULL) { TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); continue; } type = doc->base._type; // for simple document collection, compactify datafiles if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) { if (collection->_status == TRI_VOC_COL_STATUS_LOADED) { CompactifySimCollection((TRI_sim_collection_t*) doc); } } TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); // now release the lock and maybe unload the collection or some datafiles if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) { CleanupSimCollection((TRI_sim_collection_t*) doc); } } if (vocbase->_active == 1) { // clean up unused shadows CleanupShadows(vocbase, false); // only sleep while server is still running usleep(COMPACTOR_INTERVAL); } if (active == 2) { // server shutdown break; } } TRI_DestroyVectorPointer(&collections); }
void TRI_CleanupVocBase (void* data) { TRI_vocbase_t* vocbase = data; TRI_vector_pointer_t collections; assert(vocbase->_state == 1); TRI_InitVectorPointer(&collections, TRI_UNKNOWN_MEM_ZONE); while (true) { size_t n; size_t i; TRI_col_type_e type; // keep initial _state value as vocbase->_state might change during compaction loop int state = vocbase->_state; if (state == 2) { // shadows must be cleaned before collections are handled // otherwise the shadows might still hold barriers on collections // and collections cannot be closed properly CleanupShadows(vocbase, true); } // copy all collections TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase); TRI_CopyDataVectorPointer(&collections, &vocbase->_collections); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase); n = collections._length; for (i = 0; i < n; ++i) { TRI_vocbase_col_t* collection; TRI_primary_collection_t* primary; collection = collections._buffer[i]; TRI_READ_LOCK_STATUS_VOCBASE_COL(collection); primary = collection->_collection; if (primary == NULL) { TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); continue; } type = primary->base._type; TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); // now release the lock and maybe unload the collection or some datafiles if (TRI_IS_DOCUMENT_COLLECTION(type)) { CleanupDocumentCollection((TRI_document_collection_t*) primary); } } if (vocbase->_state >= 1) { // server is still running, clean up unused shadows CleanupShadows(vocbase, false); TRI_LockCondition(&vocbase->_cleanupCondition); TRI_TimedWaitCondition(&vocbase->_cleanupCondition, CLEANUP_INTERVAL); TRI_UnlockCondition(&vocbase->_cleanupCondition); } if (state == 3) { // server shutdown break; } } TRI_DestroyVectorPointer(&collections); }
void TRI_CleanupVocBase (void* data) { TRI_vocbase_t* vocbase; TRI_vector_pointer_t collections; uint64_t iterations = 0; vocbase = data; assert(vocbase); assert(vocbase->_state == 1); TRI_InitVectorPointer(&collections, TRI_UNKNOWN_MEM_ZONE); while (true) { int state; // keep initial _state value as vocbase->_state might change during cleanup loop state = vocbase->_state; ++iterations; if (state == 2) { // shadows must be cleaned before collections are handled // otherwise the shadows might still hold barriers on collections // and collections cannot be closed properly CleanupCursors(vocbase, true); } // check if we can get the compactor lock exclusively if (TRI_CheckAndLockCompactorVocBase(vocbase)) { size_t i, n; TRI_col_type_e type; // copy all collections TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase); TRI_CopyDataVectorPointer(&collections, &vocbase->_collections); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase); n = collections._length; for (i = 0; i < n; ++i) { TRI_vocbase_col_t* collection; TRI_primary_collection_t* primary; collection = collections._buffer[i]; TRI_READ_LOCK_STATUS_VOCBASE_COL(collection); primary = collection->_collection; if (primary == NULL) { TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); continue; } type = primary->base._info._type; TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); // we're the only ones that can unload the collection, so using // the collection pointer outside the lock is ok // maybe cleanup indexes, unload the collection or some datafiles if (TRI_IS_DOCUMENT_COLLECTION(type)) { TRI_document_collection_t* document = (TRI_document_collection_t*) primary; // clean indexes? if (iterations % (uint64_t) CLEANUP_INDEX_ITERATIONS == 0) { document->cleanupIndexes(document); } CleanupDocumentCollection(document); } } TRI_UnlockCompactorVocBase(vocbase); } if (vocbase->_state >= 1) { // server is still running, clean up unused shadows if (iterations % CLEANUP_SHADOW_ITERATIONS == 0) { CleanupCursors(vocbase, false); } // clean up expired compactor locks TRI_CleanupCompactorVocBase(vocbase); if (state == 1) { TRI_LockCondition(&vocbase->_cleanupCondition); TRI_TimedWaitCondition(&vocbase->_cleanupCondition, (uint64_t) CLEANUP_INTERVAL); TRI_UnlockCondition(&vocbase->_cleanupCondition); } } if (state == 3) { // server shutdown break; } } TRI_DestroyVectorPointer(&collections); LOG_TRACE("shutting down cleanup thread"); }