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