LTP GCOV extension - code coverage report
Current view: | directory - ept/debtags/maint - vocabularyindexer.cc
Test: | lcov.info
Date: | 2008-08-14 |  | Instrumented lines: | 94
Code covered: | 69.1 % |  | Executed lines: | 65

           1                 : #include <ept/debtags/maint/vocabularyindexer.h>
           2                 : #include <ept/debtags/vocabulary.h>
           3                 : #include <ept/debtags/maint/vocabularymerger.h>
           4                 : #include <ept/debtags/maint/path.h>
           5                 :
           6                 : namespace ept {
           7                 : namespace debtags {
           8                 :
           9              31 : VocabularyIndexer::VocabularyIndexer()
          10              31 :         : mainSource(Path::debtagsSourceDir()), userSource(Path::debtagsUserSourceDir())
          11                 : {
          12              31 :         rescan();
          13              31 : }
          14                 :
          15              31 : void VocabularyIndexer::rescan()
          16                 : {
          17              31 :         ts_main_src = mainSource.vocTimestamp();
          18              31 :         ts_user_src = userSource.vocTimestamp();
          19              31 :         ts_main_voc = Path::timestamp(Path::vocabulary());
          20              62 :         ts_main_idx = Path::timestamp(Path::vocabularyIndex());
          21              62 :         ts_user_voc = Path::timestamp(Path::userVocabulary());
          22              62 :         ts_user_idx = Path::timestamp(Path::userVocabularyIndex());
          23              31 : }
          24                 :
          25              31 : bool VocabularyIndexer::needsRebuild() const
          26                 : {
          27                 :         // If there are no indexes of any kind, then we need rebuilding
          28              31 :         if (ts_user_voc == 0 && ts_user_idx == 0 && ts_main_voc == 0 && ts_main_idx == 0)
          29               3 :                 return true;
          30                 :
          31                 :         // If the user index is ok, then we are fine
          32              28 :         if (ts_user_voc >= sourceTimestamp() && ts_user_idx >= sourceTimestamp())
          33              28 :                 return false;
          34                 :
          35                 :         // If there are user sources, then we cannot use the system index
          36               0 :         if (ts_user_src > 0)
          37               0 :                 return true;
          38                 :
          39                 :         // If there are no user sources, then we can fallback on the system
          40                 :         // indexes in case the user indexes are not up to date
          41               0 :         if (ts_main_voc >= sourceTimestamp() && ts_main_idx >= sourceTimestamp())
          42               0 :                 return false;
          43                 :
          44               0 :         return true;
          45                 : }
          46                 :
          47              31 : bool VocabularyIndexer::userIndexIsRedundant() const
          48                 : {
          49                 :         // If there is no user index, then it is not redundant
          50              31 :         if (ts_user_voc == 0 && ts_user_idx == 0)
          51               2 :                 return false;
          52                 :
          53                 :         // If we have user sources, then the user index is never redundant
          54              29 :         if (ts_user_src > 0)
          55              29 :                 return false;
          56                 :
          57                 :         // If the system index is not up to date, then the user index is not
          58                 :         // redundant
          59               0 :         if (ts_main_voc < sourceTimestamp() || ts_main_idx < sourceTimestamp())
          60               0 :                 return false;
          61                 :
          62               0 :         return true;
          63                 : }
          64                 :
          65               3 : bool VocabularyIndexer::rebuild(const std::string& vocfname, const std::string& idxfname)
          66                 : {
          67                 :         using namespace tagcoll;
          68                 :
          69                 :         // Create the master MMap index
          70               3 :         diskindex::MasterMMapIndexer master(idxfname);
          71                 :
          72                 :         // Read and merge vocabulary data
          73               3 :         VocabularyMerger voc;
          74               3 :         mainSource.readVocabularies(voc);
          75               3 :         userSource.readVocabularies(voc);
          76                 :
          77               3 :         if (voc.empty())
          78               2 :                 return false;
          79                 :                 //throw wibble::exception::Consistency("Reading debtags sources from " + mainSource.path() + " and " + userSource.path(), "Unable to find any vocabulary data");
          80                 :
          81                 :         // Write the merged vocabulary, and generate tag and facet IDs as a side
          82                 :         // effect
          83               1 :         std::string tmpvocfname = vocfname + ".tmp";
          84               1 :         voc.write(tmpvocfname);
          85                 :
          86                 :         // Add the indexed vocabulary data to the master index
          87                 :         // 0: facets
          88               1 :         master.append(voc.facetIndexer());
          89                 :         // 1: tags
          90               1 :         master.append(voc.tagIndexer());
          91                 :
          92               1 :         if (rename(tmpvocfname.c_str(), vocfname.c_str()) == -1)
          93               0 :                 throw wibble::exception::System("renaming " + tmpvocfname + " to " + vocfname);
          94                 :
          95               1 :         master.commit();
          96               1 :         return true;
          97                 : }
          98                 :
          99              31 : bool VocabularyIndexer::rebuildIfNeeded()
         100                 : {
         101              31 :         if (needsRebuild())
         102                 :         {
         103                 :                 // Decide if we rebuild the user index or the system index
         104                 :
         105               3 :                 if (ts_user_src == 0 && Path::access(Path::debtagsIndexDir(), W_OK) == 0)
         106                 :                 {
         107                 :                         // There are no user sources and we can write to the system index
         108                 :                         // directory: rebuild the system index
         109               1 :                         if (!rebuild(Path::vocabulary(), Path::vocabularyIndex()))
         110               1 :                                 return false;
         111               0 :                         ts_main_voc = Path::timestamp(Path::vocabulary());
         112               0 :                         ts_main_idx = Path::timestamp(Path::vocabularyIndex());
         113               0 :                         if (Path::vocabulary() == Path::userVocabulary())
         114               0 :                                 ts_user_voc = ts_main_voc;
         115               0 :                         if (Path::vocabularyIndex() == Path::userVocabularyIndex())
         116               0 :                                 ts_user_idx = ts_main_idx;
         117                 :                 } else {
         118               2 :                         wibble::sys::fs::mkFilePath(Path::userVocabulary());
         119               4 :                         wibble::sys::fs::mkFilePath(Path::userVocabularyIndex());
         120               4 :                         if (!rebuild(Path::userVocabulary(), Path::userVocabularyIndex()))
         121               1 :                                 return false;
         122               1 :                         ts_user_voc = Path::timestamp(Path::userVocabulary());
         123               2 :                         ts_user_idx = Path::timestamp(Path::userVocabularyIndex());
         124                 :                 }
         125               1 :                 return true;
         126                 :         }
         127              28 :         return false;
         128                 : }
         129                 :
         130              31 : bool VocabularyIndexer::deleteRedundantUserIndex()
         131                 : {
         132              31 :         if (userIndexIsRedundant())
         133                 :         {
         134                 :                 // Delete the user indexes if they exist
         135               0 :                 if (Path::vocabulary() != Path::userVocabulary())
         136                 :                 {
         137               0 :                         unlink(Path::userVocabulary().c_str());
         138               0 :                         ts_user_voc = 0;
         139                 :                 }
         140               0 :                 if (Path::vocabularyIndex() != Path::userVocabularyIndex())
         141                 :                 {
         142               0 :                         unlink(Path::userVocabularyIndex().c_str());
         143               0 :                         ts_user_idx = 0;
         144                 :                 }
         145               0 :                 return true;
         146                 :         }
         147              31 :         return false;
         148                 : }
         149                 :
         150              31 : bool VocabularyIndexer::getUpToDateVocabulary(std::string& vocfname, std::string& idxfname)
         151                 : {
         152                 :         // If there are no indexes of any kind, then we have nothing to return
         153              31 :         if (ts_user_voc == 0 && ts_user_idx == 0 && ts_main_voc == 0 && ts_main_idx == 0)
         154               2 :                 return false;
         155                 :
         156                 :         // If the user index is up to date, use it
         157              29 :         if (ts_user_voc >= sourceTimestamp() &&
         158                 :                 ts_user_idx >= sourceTimestamp())
         159                 :         {
         160              29 :                 vocfname = Path::userVocabulary();
         161              58 :                 idxfname = Path::userVocabularyIndex();
         162              29 :                 return true;
         163                 :         }
         164                 :
         165                 :         // If the user index is not up to date and we have user sources, we cannot
         166                 :         // fall back to the system index
         167               0 :         if (ts_user_src != 0)
         168               0 :                 return false;
         169                 :
         170                 :         // Fallback to the system index
         171               0 :         if (ts_main_voc >= sourceTimestamp() &&
         172                 :                 ts_main_idx >= sourceTimestamp())
         173                 :         {
         174               0 :                 vocfname = Path::vocabulary();
         175               0 :                 idxfname = Path::vocabularyIndex();
         176               0 :                 return true;
         177                 :         }
         178                 :
         179               0 :         return false;
         180                 : }
         181                 :
         182                 :
         183              31 : bool VocabularyIndexer::obtainWorkingVocabulary(std::string& vocfname, std::string& idxfname)
         184                 : {
         185              31 :         VocabularyIndexer v;
         186                 :
         187              31 :         v.rebuildIfNeeded();
         188              31 :         v.deleteRedundantUserIndex();
         189              31 :         return v.getUpToDateVocabulary(vocfname, idxfname);
         190                 : }
         191                 :
         192                 : }
         193               6 : }
         194                 :
         195                 : // vim:set ts=4 sw=4:

Generated by: LTP GCOV extension version 1.6