35 #include <sys/types.h> 52 #ifdef XAPIAN_HAS_GLASS_BACKEND 56 #ifdef XAPIAN_HAS_CHERT_BACKEND 68 const vector<pair<Xapian::docid, Xapian::docid>>&
used_ranges;
76 return used_ranges[a].first < used_ranges[b].first;
102 internal->block_size = block_size;
108 internal->flags = (
internal->flags & mask) | flags;
114 internal->destdir_compat = destdir;
120 internal->srcdirs_compat.push_back(srcdir);
143 size_t num_tags,
const std::string
tags[])
155 const string &dbpath2,
int backend2)
159 const string &dbpath2,
int backend2)
162 db.
internal[0]->get_backend_info(&dbpath1);
163 string msg =
"All databases must be the same type ('";
182 LOGCALL_VOID(API,
"Database::compact_", output_ptr | fd | flags | block_size | compactor);
186 enum { STUB_NO, STUB_FILE, STUB_DIR } compact_to_stub = STUB_NO;
190 destdir = *output_ptr;
194 compact_to_stub = STUB_FILE;
197 compact_to_stub = STUB_DIR;
206 for (
const auto& it :
internal) {
208 int type = it->get_backend_info(&srcdir);
211 if (!compact_to_stub && !destdir.empty() && srcdir == destdir)
229 vector<Xapian::docid> offset;
230 vector<pair<Xapian::docid, Xapian::docid> > used_ranges;
231 vector<Xapian::Database::Internal *> internals;
232 offset.reserve(
internal.size());
233 used_ranges.reserve(
internal.size());
234 internals.reserve(
internal.size());
236 for (
const auto& i :
internal) {
238 internals.push_back(db);
248 if (renumber && first) {
254 tot_off -= (first - 1);
257 #ifdef XAPIAN_ASSERTIONS 274 offset.push_back(tot_off);
277 else if (last_docid < db->get_lastdocid())
279 used_ranges.push_back(make_pair(first, last));
283 last_docid = tot_off;
285 if (!renumber &&
internal.size() > 1) {
290 vector<size_t> order;
291 order.reserve(
internal.size());
292 for (
size_t i = 0; i <
internal.size(); ++i)
299 vector<Xapian::Database::Internal *> internals_;
300 internals_.reserve(
internal.size());
301 vector<pair<Xapian::docid, Xapian::docid>> used_ranges_;
302 used_ranges_.reserve(
internal.size());
305 for (
size_t j = 0; j != order.size(); ++j) {
308 internals_.push_back(internals[n]);
309 used_ranges_.push_back(used_ranges[n]);
311 const pair<Xapian::docid, Xapian::docid> p = used_ranges[n];
313 if (p.first == 0 && p.second == 0)
316 if (p.first <= last_end) {
318 string msg =
"when merging databases, --no-renumber is only currently supported if the databases have disjoint ranges of used document ids: ";
319 internals_[j - 1]->get_backend_info(&tmp);
321 msg +=
" has range ";
322 msg +=
str(last_start);
324 msg +=
str(last_end);
326 internals_[j]->get_backend_info(&tmp);
328 msg +=
" has range ";
331 msg +=
str(p.second);
334 last_start = p.first;
338 swap(internals, internals_);
339 swap(used_ranges, used_ranges_);
343 if (compact_to_stub) {
345 if (compact_to_stub == STUB_DIR) {
346 stub_file +=
"/XAPIANDB";
351 size_t sfx = destdir.size();
352 time_t
now = time(NULL);
355 destdir +=
str(now++);
356 if (mkdir(destdir.c_str(), 0755) == 0)
358 if (errno != EEXIST) {
359 string msg = destdir;
360 msg +=
": mkdir failed";
366 if (mkdir(destdir.c_str(), 0755) < 0) {
370 int mkdir_errno = errno;
371 if (mkdir_errno != EEXIST || !
dir_exists(destdir)) {
372 string msg = destdir;
373 msg +=
": cannot create directory";
379 #if defined XAPIAN_HAS_CHERT_BACKEND || defined XAPIAN_HAS_GLASS_BACKEND 388 #ifdef XAPIAN_HAS_CHERT_BACKEND 390 block_size, compaction, flags, last_docid);
402 #ifdef XAPIAN_HAS_GLASS_BACKEND 406 block_size, compaction, flags, last_docid);
410 block_size, compaction, flags, last_docid);
419 if (compact_to_stub) {
420 string new_stub_file = destdir;
421 new_stub_file +=
"/new_stub.tmp";
423 ofstream new_stub(new_stub_file.c_str());
424 size_t slash = destdir.find_last_of(
DIR_SEPS);
425 new_stub <<
"auto " << destdir.substr(slash + 1) <<
'\n';
428 string msg =
"Cannot rename '";
429 msg += new_stub_file;
The Xapian namespace contains public interfaces for the Xapian library.
static void compact(Xapian::Compactor *compactor, const char *destdir, const std::vector< Xapian::Database::Internal *> &sources, const std::vector< Xapian::docid > &offset, size_t block_size, Xapian::Compactor::compaction_level compaction, unsigned flags, Xapian::docid last_docid)
Define the XAPIAN_NORETURN macro.
const char * backend_name(int code)
This class is used to access a database, or a group of databases.
virtual Xapian::docid get_docid() const =0
Return the current docid.
Allow oversize items to save more space (not recommended if you ever plan to update the compacted dat...
#define AssertRel(A, REL, B)
InvalidOperationError indicates the API was used in an invalid way.
Base class for databases.
Constants in the Xapian namespace.
static void backend_mismatch(const Xapian::Database &db, int backend1, const string &dbpath2, int backend2)
static void compact(Xapian::Compactor *compactor, const char *destdir, int fd, const std::vector< Xapian::Database::Internal *> &sources, const std::vector< Xapian::docid > &offset, size_t block_size, Xapian::Compactor::compaction_level compaction, unsigned flags, Xapian::docid last_docid)
void set_destdir(const std::string &destdir)
Set where to write the output.
virtual Internal * skip_to(Xapian::docid did, double w_min)=0
Skip forward to the specified docid.
Don't split items unnecessarily.
Compact a database, or merge and compact several.
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Convert types to std::string.
Abstract base class for leaf postlists.
Utility functions for testing files.
virtual LeafPostList * open_post_list(const string &tname) const =0
Open a posting list.
std::vector< Xapian::Internal::intrusive_ptr< Internal > > internal
const int DBCOMPACT_NO_RENUMBER
Use the same document ids in the output as in the input(s).
Abstract base class for leaf postlists.
include <sys/stat.h> with portability enhancements
void compact()
Perform the actual compaction/merging operation.
virtual void set_status(const std::string &table, const std::string &status)
Update progress.
CmpByFirstUsed(const vector< pair< Xapian::docid, Xapian::docid >> &ur)
Hierarchy of classes which Xapian can throw as exceptions.
The ChertVersion class manages the "iamchert" file.
InvalidArgumentError indicates an invalid parameter value was passed to the API.
virtual Xapian::docid get_lastdocid() const =0
Return the last used document id of this (sub) database.
Indicates an attempt to use a feature which is unavailable.
virtual std::string resolve_duplicate_metadata(const std::string &key, size_t num_tags, const std::string tags[])
Resolve multiple user metadata entries with the same key.
Compact a database, or merge and compact several.
API for working with Xapian databases.
string str(int value)
Convert int to std::string.
bool io_tmp_rename(const std::string &tmp_file, const std::string &real_file)
Rename a temporary file to its final position.
C++ class definition for glass database.
vector< string > srcdirs_compat
void compact_(const std::string *output_ptr, int fd, unsigned flags, int block_size, Xapian::Compactor *compactor) const
Internal helper behind public compact() methods.
Base class for objects managed by intrusive_ptr.
Split items whenever it saves space (the default).
void compact(const std::string &output, unsigned flags=0, int block_size=0)
Produce a compact version of this database.
bool dir_exists(const char *path)
Test if a directory exists.
void add_database(const Database &database)
Add an existing database (or group of databases) to those accessed by this object.
C++ class definition for chert database.
void set_flags_(unsigned flags, unsigned mask=0)
void create()
Create the version file.
Xapian::Internal::intrusive_ptr< Internal > internal
bool operator()(size_t a, size_t b) const
virtual Internal * next(double w_min)=0
Advance the current position to the next document in the postlist.
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
const vector< pair< Xapian::docid, Xapian::docid > > & used_ranges
double now()
Return the current time.
compaction_level
Compaction level.
Wrappers for low-level POSIX I/O routines.
Various handy helpers which std::string really should provide.
virtual Xapian::doccount get_doccount() const =0
Return the number of docs in this (sub) database.
<unistd.h>, but with compat.
virtual bool at_end() const =0
Return true if the current position is past the last entry in this list.
Various assertion macros.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
DatabaseError indicates some sort of database related error.
virtual void get_used_docid_range(Xapian::docid &first, Xapian::docid &last) const
Find lowest and highest docids actually in use.
const int DBCOMPACT_SINGLE_FILE
Produce a single-file database.
bool file_exists(const char *path)
Test if a file exists.
void add_source(const std::string &srcdir)
Add a source database.
File and path manipulation routines.
include <fcntl.h>, but working around broken platforms.
void set_block_size(size_t block_size)
Set the block size to use for tables in the output database.