1 /** @file chert_metadata.cc
2 * @brief Access to metadata for a chert database.
3 */
4 /* Copyright (C) 2004,2005,2006,2007,2008,2011 Olly Betts
5 * Copyright (C) 2008 Lemur Consulting Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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 #include "chert_metadata.h"
24
25 #include "backends/database.h"
26 #include "debuglog.h"
27 #include "omassert.h"
28 #include "stringutils.h"
29
30 using namespace std;
31 using Xapian::Internal::intrusive_ptr;
32
ChertMetadataTermList(intrusive_ptr<const Xapian::Database::Internal> database_,ChertCursor * cursor_,const string & prefix_)33 ChertMetadataTermList::ChertMetadataTermList(
34 intrusive_ptr<const Xapian::Database::Internal> database_,
35 ChertCursor * cursor_,
36 const string &prefix_)
37 : database(database_), cursor(cursor_), prefix(string("\x00\xc0", 2) + prefix_)
38 {
39 LOGCALL_CTOR(DB, "ChertMetadataTermList", database_ | cursor_ | prefix_);
40 Assert(cursor);
41 // Seek to the first key before the first metadata key.
42 cursor->find_entry_lt(prefix);
43 }
44
~ChertMetadataTermList()45 ChertMetadataTermList::~ChertMetadataTermList()
46 {
47 LOGCALL_DTOR(DB, "ChertMetadataTermList");
48 delete cursor;
49 }
50
51 string
get_termname() const52 ChertMetadataTermList::get_termname() const
53 {
54 LOGCALL(DB, string, "ChertMetadataTermList::get_termname", NO_ARGS);
55 Assert(!at_end());
56 Assert(!cursor->current_key.empty());
57 Assert(startswith(cursor->current_key, prefix));
58 RETURN(cursor->current_key.substr(2));
59 }
60
61 Xapian::doccount
get_termfreq() const62 ChertMetadataTermList::get_termfreq() const
63 {
64 throw Xapian::InvalidOperationError("ChertMetadataTermList::get_termfreq() not meaningful");
65 }
66
67 TermList *
next()68 ChertMetadataTermList::next()
69 {
70 LOGCALL(DB, TermList *, "ChertMetadataTermList::next", NO_ARGS);
71 Assert(!at_end());
72
73 cursor->next();
74 if (!cursor->after_end() && !startswith(cursor->current_key, prefix)) {
75 // We've reached the end of the prefixed terms.
76 cursor->to_end();
77 }
78
79 RETURN(NULL);
80 }
81
82 TermList *
skip_to(const string & key)83 ChertMetadataTermList::skip_to(const string &key)
84 {
85 LOGCALL(DB, TermList *, "ChertMetadataTermList::skip_to", key);
86 Assert(!at_end());
87
88 if (!cursor->find_entry_ge(string("\x00\xc0", 2) + key)) {
89 // The exact term we asked for isn't there, so check if the next
90 // term after it also has the right prefix.
91 if (!cursor->after_end() && !startswith(cursor->current_key, prefix)) {
92 // We've reached the end of the prefixed terms.
93 cursor->to_end();
94 }
95 }
96 RETURN(NULL);
97 }
98
99 bool
at_end() const100 ChertMetadataTermList::at_end() const
101 {
102 LOGCALL(DB, bool, "ChertMetadataTermList::at_end", NO_ARGS);
103 RETURN(cursor->after_end());
104 }
105