Fix warning from older GCC
[xapian.git] / xapian-core / backends / databaseinternal.h
blob56abe91378a9de38298a8e3c5034ba470ca46a83
1 /** @file databaseinternal.h
2 * @brief Virtual base class for Database internals
3 */
4 /* Copyright 2004,2006,2007,2008,2009,2011,2014,2015,2016,2017 Olly Betts
5 * Copyright 2007,2008 Lemur Consulting Ltd
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.
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.
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
22 #ifndef XAPIAN_INCLUDED_DATABASEINTERNAL_H
23 #define XAPIAN_INCLUDED_DATABASEINTERNAL_H
25 #include "internaltypes.h"
27 #include <xapian/database.h>
28 #include <xapian/document.h>
29 #include <xapian/intrusive_ptr.h>
30 #include <xapian/positioniterator.h>
31 #include <xapian/postingiterator.h>
32 #include <xapian/termiterator.h>
33 #include <xapian/types.h>
34 #include <xapian/valueiterator.h>
36 #include <string>
38 typedef Xapian::TermIterator::Internal TermList;
39 typedef Xapian::PositionIterator::Internal PositionList;
40 typedef Xapian::PostingIterator::Internal PostList;
41 typedef Xapian::ValueIterator::Internal ValueList;
43 class LeafPostList;
45 namespace Xapian {
47 class Query;
48 struct ReplicationInfo;
50 /// Virtual base class for Database internals
51 class Database::Internal : public Xapian::Internal::intrusive_base {
52 friend class Database;
54 /// Don't allow assignment.
55 Internal& operator=(const Internal&) = delete;
57 /// Don't allow copying.
58 Internal(const Internal&) = delete;
60 /// The "action required" helper for the dtor_called() helper.
61 void dtor_called_();
63 protected:
64 /// Transaction state enum.
65 enum transaction_state {
66 TRANSACTION_READONLY = -2, // Not a writable database shard.
67 TRANSACTION_UNIMPLEMENTED = -1, // Used by InMemory.
68 TRANSACTION_NONE = 0,
69 TRANSACTION_UNFLUSHED = 1,
70 TRANSACTION_FLUSHED = 2
73 /** Only constructable as a base class for derived classes.
75 * @param transaction_support One of:
76 * * TRANSACTION_READONLY - read-only shard
77 * * TRANSACTION_UNIMPLEMENTED - writable but no transaction support
78 * * TRANSACTION_NONE - writable with transaction support
80 Internal(transaction_state transaction_support)
81 : state(transaction_support) {}
83 /// Current transaction state.
84 transaction_state state;
86 /// Test if this shard is read-only.
87 bool is_read_only() const {
88 return state == TRANSACTION_READONLY;
91 /// Test if a transaction is currently active.
92 bool transaction_active() const { return state > 0; }
94 /** Helper to process uncommitted changes when a writable db is destroyed.
96 * The destructor of a derived writable database class needs to call this
97 * method - we can't call it from our own destructor because we need to
98 * be able to call methods in the derived class, but that's no longer
99 * valid by the time our destructor runs, as that happens after the
100 * destructor of the derived class has run.
102 * If a transaction is active, it is cancelled. Otherwise we attempt to
103 * commit uncommitted changes, but because it is not safe to throw
104 * exceptions from destructors, this method will catch and discard any
105 * exceptions.
107 void dtor_called() {
108 // Inline the check to exclude no-op cases (read-only and unimplemented).
109 if (state >= 0)
110 dtor_called_();
113 public:
114 /** We have virtual methods and want to be able to delete derived classes
115 * using a pointer to the base class, so we need a virtual destructor.
117 virtual ~Internal() {}
119 typedef size_t size_type;
121 virtual size_type size() const;
123 virtual void keep_alive();
125 virtual void readahead_for_query(const Query& query) const;
127 virtual doccount get_doccount() const = 0;
129 /** Return the last used document id of this (sub) database. */
130 virtual docid get_lastdocid() const = 0;
132 /** Return the total length of all documents in this database. */
133 virtual totallength get_total_length() const = 0;
135 virtual termcount get_doclength(docid did) const = 0;
137 /** Get the number of unique terms in document.
139 * @param did The document id of the document to return this value for.
141 virtual termcount get_unique_terms(docid did) const = 0;
143 /** Returns frequencies for a term.
145 * @param term The term to get frequencies for
146 * @param termfreq_ptr Point to return number of docs indexed by @a
147 * term (or NULL not to return)
148 * @param collfreq_ptr Point to return number of occurrences of @a
149 * term in the database (or NULL not to return)
151 virtual void get_freqs(const std::string& term,
152 doccount* termfreq_ptr,
153 termcount* collfreq_ptr) const = 0;
155 /** Return the frequency of a given value slot.
157 * This is the number of documents which have a (non-empty) value
158 * stored in the slot.
160 * @param slot The value slot to examine.
162 * @exception UnimplementedError The frequency of the value isn't
163 * available for this database type.
165 virtual doccount get_value_freq(valueno slot) const;
167 /** Get a lower bound on the values stored in the given value slot.
169 * If the lower bound isn't available for the given database type,
170 * this will return the lowest possible bound - the empty string.
172 * @param slot The value slot to examine.
174 virtual std::string get_value_lower_bound(valueno slot) const;
176 /** Get an upper bound on the values stored in the given value slot.
178 * @param slot The value slot to examine.
180 * @exception UnimplementedError The upper bound of the values isn't
181 * available for this database type.
183 virtual std::string get_value_upper_bound(valueno slot) const;
185 /// Get a lower bound on the length of a document in this DB.
186 virtual termcount get_doclength_lower_bound() const;
188 /// Get an upper bound on the length of a document in this DB.
189 virtual termcount get_doclength_upper_bound() const;
191 /// Get an upper bound on the wdf of term @a term.
192 virtual termcount get_wdf_upper_bound(const std::string& term) const;
194 virtual bool term_exists(const std::string& term) const = 0;
196 /** Check whether this database contains any positional information. */
197 virtual bool has_positions() const = 0;
199 virtual PostList* open_post_list(const std::string& term) const = 0;
201 virtual LeafPostList* open_leaf_post_list(const std::string& term) const = 0;
203 /** Open a value stream.
205 * This returns the value in a particular slot for each document.
207 * @param slot The value slot.
209 * @return Pointer to a new ValueList object which should be deleted by
210 * the caller once it is no longer needed.
212 virtual ValueList* open_value_list(valueno slot) const;
214 virtual TermList* open_term_list(docid did) const = 0;
216 /** Like open_term_list() but without MultiTermList wrapper.
218 * MultiDatabase::open_term_list() wraps the returns TermList in a
219 * MultiTermList, but we don't want that for query expansion.
221 virtual TermList* open_term_list_direct(docid did) const = 0;
223 virtual TermList* open_allterms(const std::string& prefix) const = 0;
225 virtual PositionList* open_position_list(docid did,
226 const std::string& term) const = 0;
228 /** Open a handle on a document.
230 * The returned handle provides access to document data and document
231 * values.
233 * @param did The document id to open.
235 * @param lazy If true, there's no need to check that this document
236 * actually exists (only a hint - the backend may still
237 * check). Used to avoid unnecessary work when we already
238 * know that the requested document exists.
240 * @return A new document object, owned by the caller.
242 virtual Document::Internal* open_document(docid did, bool lazy) const = 0;
244 /** Create a termlist tree from trigrams of @a word.
246 * You can assume word.size() > 1.
248 * If there are no trigrams, returns NULL.
250 virtual TermList* open_spelling_termlist(const std::string& word) const;
252 /** Return a termlist which returns the words which are spelling
253 * correction targets.
255 * If there are no spelling correction targets, returns NULL.
257 virtual TermList* open_spelling_wordlist() const;
259 /** Return the number of times @a word was added as a spelling. */
260 virtual doccount get_spelling_frequency(const std::string& word) const;
262 /** Add a word to the spelling dictionary.
264 * If the word is already present, its frequency is increased.
266 * @param word The word to add.
267 * @param freqinc How much to increase its frequency by.
269 virtual void add_spelling(const std::string& word,
270 termcount freqinc) const;
272 /** Remove a word from the spelling dictionary.
274 * The word's frequency is decreased, and if would become zero or less
275 * then the word is removed completely.
277 * @param word The word to remove.
278 * @param freqdec How much to decrease its frequency by.
280 * @return Any freqdec not "used up".
282 virtual termcount remove_spelling(const std::string& word,
283 termcount freqdec) const;
285 /** Open a termlist returning synonyms for a term.
287 * If @a term has no synonyms, returns NULL.
289 virtual TermList* open_synonym_termlist(const std::string& term) const;
291 /** Open a termlist returning each term which has synonyms.
293 * @param prefix If non-empty, only terms with this prefix are
294 * returned.
296 virtual TermList* open_synonym_keylist(const std::string& prefix) const;
298 /** Add a synonym for a term.
300 * If @a synonym is already a synonym for @a term, then no action is
301 * taken.
303 virtual void add_synonym(const std::string& term,
304 const std::string& synonym) const;
306 /** Remove a synonym for a term.
308 * If @a synonym isn't a synonym for @a term, then no action is taken.
310 virtual void remove_synonym(const std::string& term,
311 const std::string& synonym) const;
313 /** Clear all synonyms for a term.
315 * If @a term has no synonyms, no action is taken.
317 virtual void clear_synonyms(const std::string& term) const;
319 /** Get the metadata associated with a given key.
321 * See Database::get_metadata() for more information.
323 virtual std::string get_metadata(const std::string& key) const;
325 /** Open a termlist returning each metadata key.
327 * Only metadata keys which are associated with a non-empty value will
328 * be returned.
330 * @param prefix If non-empty, only keys with this prefix are returned.
332 virtual TermList* open_metadata_keylist(const std::string& prefix) const;
334 /** Set the metadata associated with a given key.
336 * See WritableDatabase::set_metadata() for more information.
338 virtual void set_metadata(const std::string& key, const std::string& value);
340 /** Reopen the database to the latest available revision.
342 * Database backends which don't support simultaneous update and
343 * reading probably don't need to do anything here.
345 virtual bool reopen();
347 /** Close the database */
348 virtual void close() = 0;
350 /** Commit pending modifications to the database. */
351 virtual void commit();
353 /** Cancel pending modifications to the database. */
354 virtual void cancel();
356 /** Begin transaction. */
357 virtual void begin_transaction(bool flushed);
359 /** End transaction.
361 * @param do_commit If true, commits the transaction; if false,
362 * cancels the transaction.
364 virtual void end_transaction(bool do_commit);
366 virtual docid add_document(const Document& document);
368 virtual void delete_document(docid did);
370 /** Delete any documents indexed by a term from the database. */
371 virtual void delete_document(const std::string& unique_term);
373 virtual void replace_document(docid did,
374 const Document& document);
376 /** Replace any documents matching a term. */
377 virtual docid replace_document(const std::string& unique_term,
378 const Document& document);
380 /** Request a document.
382 * This tells the database that we're going to want a particular
383 * document soon. It's just a hint which the backend may ignore,
384 * but for glass it issues a preread hint on the file with the
385 * document data in, and for the remote backend it might cause
386 * the document to be fetched asynchronously (this isn't currently
387 * implemented though).
389 * It can be called for multiple documents in turn, and a common usage
390 * pattern would be to iterate over an MSet and request the documents,
391 * then iterate over it again to actually get and display them.
393 * The default implementation is a no-op.
395 virtual void request_document(docid did) const;
397 /** Write a set of changesets to a file descriptor.
399 * This call may reopen the database, leaving it pointing to a more
400 * recent version of the database.
402 virtual void write_changesets_to_fd(int fd,
403 const std::string& start_revision,
404 bool need_whole_db,
405 ReplicationInfo* info);
407 /// Get a string describing the current revision of the database.
408 virtual std::string get_revision_info() const;
410 /** Get a UUID for the database.
412 * The UUID will persist for the lifetime of the database.
414 * Replicas (eg, made with the replication protocol, or by copying all
415 * the database files) will have the same UUID. However, copies (made
416 * with copydatabase, or xapian-compact) will have different UUIDs.
418 * If the backend does not support UUIDs the empty string is returned.
420 virtual std::string get_uuid() const;
422 /** Notify the database that document is no longer valid.
424 * This is used to invalidate references to a document kept by a
425 * database for doing lazy updates. If we moved to using a weak_ptr
426 * instead we wouldn't need a special method for this, but it would
427 * involve a fair bit of reorganising of other parts of the code.
429 virtual void invalidate_doc_object(Document::Internal* obj) const;
431 /** Get backend information about this database.
433 * @param path If non-NULL, and set the pointed to string to the file
434 * path of this database (or if to some string describing
435 * the database in a backend-specified format if "path"
436 * isn't a concept which make sense).
438 * @return A constant indicating the backend type.
440 virtual int get_backend_info(std::string* path) const = 0;
442 /** Find lowest and highest docids actually in use.
444 * Only used by compaction, so only needs to be implemented by
445 * backends which support compaction.
447 virtual void get_used_docid_range(docid& first,
448 docid& last) const;
450 /** Return true if the database is open for writing.
452 * If this is a WritableDatabase, always returns true.
454 * For a Database, test if there's a writer holding the lock (or if
455 * we can't test for a lock without taking it on the current platform,
456 * throw Xapian::UnimplementedError).
458 virtual bool locked() const;
460 /// Return a string describing this object.
461 virtual std::string get_description() const = 0;
466 #endif // XAPIAN_INCLUDED_DATABASEINTERNAL_H