diff options
Diffstat (limited to 'ept/popcon/maint/popconindexer.cc')
-rw-r--r-- | ept/popcon/maint/popconindexer.cc | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/ept/popcon/maint/popconindexer.cc b/ept/popcon/maint/popconindexer.cc deleted file mode 100644 index a8dea69..0000000 --- a/ept/popcon/maint/popconindexer.cc +++ /dev/null @@ -1,248 +0,0 @@ -#include <ept/popcon/popcon.h> -#include <ept/popcon/maint/popconindexer.h> -#include <ept/popcon/maint/path.h> - -#include <wibble/exception.h> -#include <wibble/sys/fs.h> - -#include <tagcoll/diskindex/mmap.h> - -#include <unistd.h> -#include <set> -#include <string> -#include <cstdio> -#include <cstring> - -using namespace std; - -namespace ept { -namespace popcon { - -template<typename STRUCT> -struct StructIndexer : public tagcoll::diskindex::MMapIndexer -{ - const STRUCT& data; - StructIndexer(const STRUCT& data) : data(data) {} - - int encodedSize() const { return sizeof(STRUCT); } - void encode(char* buf) const { *(STRUCT*)buf = data; } -}; - -/// MMapIndexer that indexes the package names -struct PopconGenerator : public tagcoll::diskindex::MMapIndexer -{ - // Sorted set of all available package names and data - std::map<std::string, Score> data; - - int encodedSize() const - { - int size = data.size() * sizeof(Score); - for (std::map<std::string, Score>::const_iterator i = data.begin(); - i != data.end(); ++i) - size += i->first.size() + 1; - return tagcoll::diskindex::MMap::align(size); - } - - void encode(char* buf) const - { - int pos = data.size() * sizeof(Score); - int idx = 0; - for (std::map<std::string, Score>::const_iterator i = data.begin(); - i != data.end(); ++i) - { - ((Score*)buf)[idx] = i->second; - ((Score*)buf)[idx].offset = pos; - memcpy(buf + pos, i->first.c_str(), i->first.size() + 1); - pos += i->first.size() + 1; - ++idx; - } - } -}; - - -PopconIndexer::PopconIndexer() - : mainSource(Path::popconSourceDir()), - userSource(Path::popconUserSourceDir()) -{ - rescan(); -} - -void PopconIndexer::rescan() -{ - ts_main_src = mainSource.timestamp(); - ts_user_src = userSource.timestamp(); - ts_main_sco = Path::timestamp(Path::scores()); - ts_user_sco = Path::timestamp(Path::userScores()); - ts_main_idx = Path::timestamp(Path::scoresIndex()); - ts_user_idx = Path::timestamp(Path::userScoresIndex()); -} - -bool PopconIndexer::needsRebuild() const -{ - // If there are no indexes of any kind, then we need rebuilding - if (ts_user_sco == 0 || ts_main_sco == 0 || ts_user_idx == 0 && ts_main_idx == 0) - return true; - - // If the user index is ok, then we are fine - if (ts_user_sco >= sourceTimestamp() && ts_user_idx >= sourceTimestamp()) - return false; - - // If there are user sources, then we cannot use the system index - if (ts_user_src > 0) - return true; - - // If there are no user sources, then we can fallback on the system - // indexes in case the user indexes are not up to date - if (ts_main_sco >= sourceTimestamp() && ts_main_idx >= sourceTimestamp()) - return false; - - return true; -} - -bool PopconIndexer::userIndexIsRedundant() const -{ - // If there is no user index, then it is not redundant - if (ts_user_idx == 0) - return false; - - // If the system index is not up to date, then the user index is not - // redundant - if (ts_main_idx < sourceTimestamp()) - return false; - - return true; -} - -bool PopconIndexer::rebuild(const std::string& scofname, const std::string& idxfname) -{ - PopconGenerator gen; - InfoStruct is; - is.submissions = 0; - if (!mainSource.readScores(gen.data, is.submissions)) - userSource.readScores(gen.data, is.submissions); - if (gen.data.empty()) - return false; - - StructIndexer<InfoStruct> infoStruct(is); - - // Create the index - tagcoll::diskindex::MasterMMapIndexer master(idxfname); - master.append(gen); - master.append(infoStruct); - master.commit(); - -// for (map<string, Score>::const_iterator i = gen.data.begin(); i != gen.data.end(); ++i) -// { -// fprintf(stderr, "%s %d %f\n", i->first.c_str(), i->second.offset, i->second.score); -// } - - // Create the score file - FILE* out = fopen(scofname.c_str(), "wt"); - if (out == NULL) - throw wibble::exception::File(scofname, "opening and truncating file for writing"); - for (map<string, Score>::const_iterator i = gen.data.begin(); - i != gen.data.end(); ++i) - { - fprintf(out, "%s %f\n", i->first.c_str(), i->second.score); - } - fclose(out); - return true; -} - -bool PopconIndexer::rebuildIfNeeded() -{ - if (needsRebuild()) - { - // Decide if we rebuild the user index or the system index - if (Path::access(Path::popconIndexDir(), W_OK) == 0) - { - // Since we can write on the system index directory, we rebuild - // the system index - if (!rebuild(Path::scores(), Path::scoresIndex())) - return false; - ts_main_sco = Path::timestamp(Path::scores()); - ts_main_idx = Path::timestamp(Path::scoresIndex()); - if (Path::scores() == Path::userScores()) - ts_user_sco = ts_main_sco; - if (Path::scoresIndex() == Path::userScoresIndex()) - ts_user_idx = ts_main_idx; - } else { - wibble::sys::fs::mkFilePath(Path::userScores()); - wibble::sys::fs::mkFilePath(Path::userScoresIndex()); - if (!rebuild(Path::userScores(), Path::userScoresIndex())) - return false; - ts_user_sco = Path::timestamp(Path::userScores()); - ts_user_idx = Path::timestamp(Path::userScoresIndex()); - } - return true; - } - return false; -} - -bool PopconIndexer::deleteRedundantUserIndex() -{ - if (userIndexIsRedundant()) - { - // Delete the user indexes if they exist - if (Path::scores() != Path::userScores()) - { - unlink(Path::userScores().c_str()); - ts_user_sco = 0; - } - if (Path::scoresIndex() != Path::userScoresIndex()) - { - unlink(Path::userScoresIndex().c_str()); - ts_user_idx = 0; - } - return true; - } - return false; -} - -bool PopconIndexer::getUpToDatePopcon(std::string& scofname, std::string& idxfname) -{ - // If there are no indexes of any kind, then we have nothing to return - if (ts_user_sco == 0 && ts_main_sco == 0 && ts_user_idx == 0 && ts_main_idx == 0) - return false; - - // If the user index is up to date, use it - if (ts_user_sco >= sourceTimestamp() && - ts_user_idx >= sourceTimestamp()) - { - scofname = Path::userScores(); - idxfname = Path::userScoresIndex(); - return true; - } - - // If the user index is not up to date and we have user sources, we cannot - // fall back to the system index - if (ts_user_src != 0) - return false; - - // Fallback to the system index - if (ts_main_sco >= sourceTimestamp() && - ts_main_idx >= sourceTimestamp()) - { - scofname = Path::scores(); - idxfname = Path::scoresIndex(); - return true; - } - - return false; -} - - -bool PopconIndexer::obtainWorkingPopcon(std::string& scofname, std::string& idxfname) -{ - PopconIndexer indexer; - - indexer.rebuildIfNeeded(); - indexer.deleteRedundantUserIndex(); - return indexer.getUpToDatePopcon(scofname, idxfname); -} - - -} -} - -// vim:set ts=4 sw=4: |