tests/harness/backendmanager_multi.cc

Go to the documentation of this file.
00001 
00004 /* Copyright (C) 2007 Olly Betts
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include "backendmanager_multi.h"
00024 
00025 #include "index_utils.h"
00026 #include "utils.h"
00027 
00028 #include <cstdio>
00029 #include <cstring>
00030 #include "safeerrno.h"
00031 
00032 using namespace std;
00033 
00034 BackendManagerMulti::~BackendManagerMulti() { }
00035 
00036 const char *
00037 BackendManagerMulti::get_dbtype() const
00038 {
00039     return "multi";
00040 }
00041 
00042 #define NUMBER_OF_SUB_DBS 2
00043 
00044 string
00045 BackendManagerMulti::createdb_multi(const vector<string> & files)
00046 {
00047     create_dir_if_needed(".multi");
00048 
00049     string dbpath = ".multi/db";
00050     vector<string>::const_iterator i;
00051     for (i = files.begin(); i != files.end(); ++i) {
00052         dbpath += "__";
00053         dbpath += *i;
00054     }
00055 
00056     if (file_exists(dbpath)) return dbpath;
00057 
00058     string tmpfile = dbpath;
00059     tmpfile += ".tmp";
00060     ofstream out(tmpfile.c_str());
00061     if (!out.is_open()) {
00062         string msg = "Couldn't create file '";
00063         msg += tmpfile;
00064         msg += "' (";
00065         msg += strerror(errno);
00066         msg += ')';
00067         throw msg;
00068     }
00069 
00070     // Open NUMBER_OF_SUB_DBS databases and index files to the alternately so a
00071     // multi-db combining them contains the documents in the expected order.
00072     Xapian::WritableDatabase dbs[NUMBER_OF_SUB_DBS];
00073     for (size_t n = 0; n < NUMBER_OF_SUB_DBS; ++n) {
00074         string subdbdir = dbpath;
00075         subdbdir += "___";
00076         subdbdir += om_tostring(n);
00077 #ifdef XAPIAN_HAS_FLINT_BACKEND
00078         dbs[n] = Xapian::Flint::open(subdbdir, Xapian::DB_CREATE_OR_OVERWRITE);
00079         out << "flint " << subdbdir << '\n';
00080 #else
00081         dbs[n] = Xapian::Quartz::open(subdbdir, Xapian::DB_CREATE_OR_OVERWRITE);
00082         out << "quartz " << subdbdir << '\n';
00083 #endif
00084     }
00085     out.close();
00086 
00087     size_t c = 0;
00088     FileIndexer f(get_datadir(), files);
00089     while (f) {
00090         dbs[c].add_document(f.next());
00091         c = (c + 1) % NUMBER_OF_SUB_DBS;
00092     }
00093 
00094     rename(tmpfile.c_str(), dbpath.c_str());
00095 
00096     return dbpath;
00097 }
00098 
00099 Xapian::Database
00100 BackendManagerMulti::get_database(const vector<string> & files)
00101 {
00102     return Xapian::Auto::open_stub(createdb_multi(files));
00103 }
00104 
00105 Xapian::Database
00106 BackendManagerMulti::get_database(const string & file)
00107 {
00108     return BackendManagerMulti::get_database(vector<string>(1, file));
00109 }
00110 
00111 Xapian::WritableDatabase
00112 BackendManagerMulti::get_writable_database(const string &, const string &)
00113 {
00114     throw Xapian::UnimplementedError("Multi-databases don't support writing");
00115 }

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.