diff --git a/arangod/VocBase/collection.c b/arangod/VocBase/collection.c index ccc71e8746..1b1fc47d8e 100644 --- a/arangod/VocBase/collection.c +++ b/arangod/VocBase/collection.c @@ -571,6 +571,36 @@ static bool CloseDataFiles (const TRI_vector_pointer_t* const files) { return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief iterate over a set of datafiles +/// note: the files will be opened and closed +//////////////////////////////////////////////////////////////////////////////// + +static bool IterateFiles (TRI_vector_string_t* vector, + bool (*iterator)(TRI_df_marker_t const*, void*, TRI_datafile_t*, bool)) { + size_t i, n; + + n = vector->_length; + + for (i = 0; i < n ; ++i) { + TRI_datafile_t* datafile; + char* filename; + + filename = TRI_AtVectorString(vector, i); + LOG_DEBUG("iterating over collection journal file '%s'", filename); + datafile = TRI_OpenDatafile(filename); + + if (datafile != NULL) { + TRI_IterateDatafile(datafile, iterator, NULL, true); + TRI_CloseDatafile(datafile); + TRI_FreeDatafile(datafile); + } + } + + return true; +} + + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -1290,36 +1320,22 @@ void TRI_DestroyFileStructureCollection (TRI_col_file_structure_t* info) { //////////////////////////////////////////////////////////////////////////////// /// @brief iterate over the markers incollection journals journal /// -/// we do this on startup to find the most recent tick values +/// this function is called on server startup for all collections //////////////////////////////////////////////////////////////////////////////// -bool TRI_IterateJournalsCollection (const char* const path, - bool (*iterator)(TRI_df_marker_t const*, void*, TRI_datafile_t*, bool)) { +bool TRI_IterateStartupCollection (const char* const path, + bool (*iterator)(TRI_df_marker_t const*, void*, TRI_datafile_t*, bool)) { + TRI_col_file_structure_t structure = ScanCollectionDirectory(path); - TRI_vector_string_t* vector = &structure._journals; - size_t n = vector->_length; - - if (n > 0) { - size_t i; - - for (i = 0; i < n ; ++i) { - TRI_datafile_t* datafile; - char* filename; - - filename = TRI_AtVectorString(vector, i); - LOG_DEBUG("iterating over collection journal file '%s'", filename); - datafile = TRI_OpenDatafile(filename); - if (datafile != NULL) { - TRI_IterateDatafile(datafile, iterator, NULL, true); - TRI_CloseDatafile(datafile); - TRI_FreeDatafile(datafile); - } - } - } + bool result; + // iterate of journals & compactors, not datafiles + result = IterateFiles(&structure._journals, iterator); + result &= IterateFiles(&structure._compactors, iterator); + TRI_DestroyFileStructureCollection(&structure); - return true; + return result; } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/collection.h b/arangod/VocBase/collection.h index a74e1dbf83..874bfc4960 100644 --- a/arangod/VocBase/collection.h +++ b/arangod/VocBase/collection.h @@ -427,9 +427,10 @@ void TRI_DestroyFileStructureCollection (TRI_col_file_structure_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief iterate over markers in collection journals +/// this function is called on server startup for all collections //////////////////////////////////////////////////////////////////////////////// -bool TRI_IterateJournalsCollection (const char* const, +bool TRI_IterateStartupCollection (const char* const, bool (*)(TRI_df_marker_t const*, void*, TRI_datafile_t*, bool)); //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/vocbase.c b/arangod/VocBase/vocbase.c index 11e257b7b1..58829d9e00 100644 --- a/arangod/VocBase/vocbase.c +++ b/arangod/VocBase/vocbase.c @@ -211,6 +211,18 @@ static bool EqualKeyCollectionName (TRI_associative_pointer_t* array, void const /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief updates the tick counter, without using a lock +//////////////////////////////////////////////////////////////////////////////// + +static void UpdateTick (TRI_voc_tick_t tick) { + TRI_voc_tick_t s = tick >> 16; + + if (CurrentTick < s) { + CurrentTick = s; + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief free the memory associated with a collection //////////////////////////////////////////////////////////////////////////////// @@ -611,6 +623,22 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase, return collection; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief this iterator is called on startup for journal and compactor file +/// of a collection +/// it will check the ticks of all markers and update the internal tick +/// counter accordingly +//////////////////////////////////////////////////////////////////////////////// + +static bool StartupIterator (TRI_df_marker_t const* marker, + void* data, + TRI_datafile_t* datafile, + bool journal) { + UpdateTick(marker->_tick); + + return true; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief scans a directory and loads all collections //////////////////////////////////////////////////////////////////////////////// @@ -667,7 +695,7 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) { res = TRI_LoadCollectionInfo(file, &info, true); if (res == TRI_ERROR_NO_ERROR) { - TRI_UpdateTickVocBase(info._cid); + UpdateTick(info._cid); } if (res != TRI_ERROR_NO_ERROR) { @@ -724,6 +752,8 @@ static int ScanPath (TRI_vocbase_t* vocbase, char const* path) { TRI_vocbase_col_t* c; c = AddCollection(vocbase, type, info._name, info._cid, file); + + TRI_IterateStartupCollection(file, StartupIterator); if (c == NULL) { LOG_ERROR("failed to add document collection from '%s'", file); @@ -971,14 +1001,8 @@ TRI_voc_tick_t TRI_NewTickVocBase () { //////////////////////////////////////////////////////////////////////////////// void TRI_UpdateTickVocBase (TRI_voc_tick_t tick) { - TRI_voc_tick_t s = tick >> 16; - TRI_LockSpin(&TickLock); - - if (CurrentTick < s) { - CurrentTick = s; - } - + UpdateTick(tick); TRI_UnlockSpin(&TickLock); }