LCOV - code coverage report
Current view: top level - harness - backendmanager_multi.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core r Lines: 44 53 83.0 %
Date: 2011-08-21 Functions: 4 6 66.7 %
Branches: 25 42 59.5 %

           Branch data     Line data    Source code
       1                 :            : /** @file backendmanager_multi.cc
       2                 :            :  * @brief BackendManager subclass for multi databases.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009 Olly Betts
       5                 :            :  * Copyright (C) 2008 Lemur Consulting Ltd
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU General Public License as
       9                 :            :  * published by the Free Software Foundation; either version 2 of the
      10                 :            :  * License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : 
      24                 :            : #include "backendmanager_multi.h"
      25                 :            : 
      26                 :            : #include "index_utils.h"
      27                 :            : #include "str.h"
      28                 :            : #include "utils.h"
      29                 :            : 
      30                 :            : #include <cstdio> // For rename().
      31                 :            : #include <cstring>
      32                 :            : #include "safeerrno.h"
      33                 :            : 
      34                 :            : using namespace std;
      35                 :            : 
      36                 :          3 : BackendManagerMulti::BackendManagerMulti(const std::string & subtype_)
      37                 :          3 :         : subtype(subtype_)
      38                 :            : {
      39   [ +  +  +  + ]:          3 :     if (!(false
                 [ -  + ]
           [ -  +  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      40                 :            : #ifdef XAPIAN_HAS_BRASS_BACKEND
      41                 :            :           || subtype == "brass"
      42                 :            : #endif
      43                 :            : #ifdef XAPIAN_HAS_CHERT_BACKEND
      44                 :            :           || subtype == "chert"
      45                 :            : #endif
      46                 :            : #ifdef XAPIAN_HAS_FLINT_BACKEND
      47                 :            :           || subtype == "flint"
      48                 :            : #endif
      49                 :            :          )) {
      50                 :          0 :         throw ("Unknown backend type \"" + subtype + "\" specified for multi database subdatabases");
      51                 :            :     }
      52                 :          3 : }
      53                 :            : 
      54                 :            : std::string
      55                 :         32 : BackendManagerMulti::get_dbtype() const
      56                 :            : {
      57                 :         32 :     return "multi_" + subtype;
      58                 :            : }
      59                 :            : 
      60                 :            : #define NUMBER_OF_SUB_DBS 2
      61                 :            : 
      62                 :            : string
      63                 :        475 : BackendManagerMulti::createdb_multi(const vector<string> & files)
      64                 :            : {
      65                 :        475 :     string dbdir = ".multi" + subtype;
      66                 :        475 :     create_dir_if_needed(dbdir);
      67                 :            : 
      68                 :        475 :     string dbname = "db";
      69                 :        475 :     vector<string>::const_iterator i;
      70         [ +  + ]:        959 :     for (i = files.begin(); i != files.end(); ++i) {
      71                 :        484 :         dbname += "__";
      72                 :        484 :         dbname += *i;
      73                 :            :     }
      74                 :        475 :     string dbpath = dbdir + "/" + dbname;
      75                 :            : 
      76         [ +  + ]:        475 :     if (file_exists(dbpath)) return dbpath;
      77                 :            : 
      78                 :         54 :     string tmpfile = dbpath;
      79                 :         54 :     tmpfile += ".tmp";
      80                 :         54 :     ofstream out(tmpfile.c_str());
      81         [ -  + ]:         54 :     if (!out.is_open()) {
      82                 :          0 :         string msg = "Couldn't create file '";
      83                 :          0 :         msg += tmpfile;
      84                 :          0 :         msg += "' (";
      85                 :          0 :         msg += strerror(errno);
      86                 :          0 :         msg += ')';
      87                 :          0 :         throw msg;
      88                 :            :     }
      89                 :            : 
      90                 :            :     // Open NUMBER_OF_SUB_DBS databases and index files to the alternately so a
      91                 :            :     // multi-db combining them contains the documents in the expected order.
      92 [ +  + ][ #  # ]:        162 :     Xapian::WritableDatabase dbs[NUMBER_OF_SUB_DBS];
                 [ #  # ]
      93         [ +  + ]:        162 :     for (size_t n = 0; n < NUMBER_OF_SUB_DBS; ++n) {
      94                 :        108 :         string subdbdir = dbname;
      95                 :        108 :         subdbdir += "___";
      96                 :        108 :         subdbdir += str(n);
      97                 :            : #if defined XAPIAN_HAS_BRASS_BACKEND
      98         [ +  + ]:        108 :         if (subtype == "brass") {
      99                 :         36 :             dbs[n] = Xapian::Brass::open(dbdir + "/" + subdbdir, Xapian::DB_CREATE_OR_OVERWRITE);
     100                 :         36 :             out << "brass " << subdbdir << '\n';
     101                 :            :         }
     102                 :            : #endif
     103                 :            : #if defined XAPIAN_HAS_CHERT_BACKEND
     104         [ +  + ]:        108 :         if (subtype == "chert") {
     105                 :         36 :             dbs[n] = Xapian::Chert::open(dbdir + "/" + subdbdir, Xapian::DB_CREATE_OR_OVERWRITE);
     106                 :         36 :             out << "chert " << subdbdir << '\n';
     107                 :            :         }
     108                 :            : #endif
     109                 :            : #ifdef XAPIAN_HAS_FLINT_BACKEND
     110         [ +  + ]:        108 :         if (subtype == "flint") {
     111                 :         36 :             dbs[n] = Xapian::Flint::open(dbdir + "/" + subdbdir, Xapian::DB_CREATE_OR_OVERWRITE);
     112                 :         36 :             out << "flint " << subdbdir << '\n';
     113                 :            :         }
     114                 :            : #endif
     115                 :            :         
     116                 :            :     }
     117                 :         54 :     out.close();
     118                 :            : 
     119                 :         54 :     size_t c = 0;
     120                 :         54 :     FileIndexer f(get_datadir(), files);
     121         [ +  + ]:       5532 :     while (f) {
     122                 :       5478 :         dbs[c].add_document(f.next());
     123                 :       5478 :         c = (c + 1) % NUMBER_OF_SUB_DBS;
     124                 :            :     }
     125                 :            : 
     126                 :         54 :     rename(tmpfile.c_str(), dbpath.c_str());
     127                 :            : 
     128 [ #  # ][ +  + ]:        583 :     return dbpath;
     129                 :            : }
     130                 :            : 
     131                 :            : string
     132                 :        475 : BackendManagerMulti::do_get_database_path(const vector<string> & files)
     133                 :            : {
     134                 :        475 :     return createdb_multi(files);
     135                 :            : }
     136                 :            : 
     137                 :            : Xapian::WritableDatabase
     138                 :          0 : BackendManagerMulti::get_writable_database(const string &, const string &)
     139                 :            : {
     140                 :          0 :     throw Xapian::UnimplementedError("Multi-databases don't support writing");
     141                 :            : }

Generated by: LCOV version 1.8