File: chert_cursor.h

package info (click to toggle)
xapian-core 1.4.3-2%2Bdeb9u3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 21,412 kB
  • sloc: cpp: 113,868; ansic: 8,723; sh: 4,433; perl: 836; makefile: 566; tcl: 317; python: 40
file content (269 lines) | stat: -rw-r--r-- 7,911 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/** @file chert_cursor.h
 * @brief Interface to Btree cursors
 */
/* Copyright 1999,2000,2001 BrightStation PLC
 * Copyright 2002,2003,2004,2006,2007,2008,2010 Olly Betts
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#ifndef OM_HGUARD_CHERT_CURSOR_H
#define OM_HGUARD_CHERT_CURSOR_H

#include "chert_types.h"

#include <string>
using std::string;

#define BLK_UNUSED uint4(-1)

class Cursor {
    private:
	// Prevent copying
	Cursor(const Cursor &);
	Cursor & operator=(const Cursor &);

    public:
	/// Constructor, to initialise important elements.
	Cursor() : p(0), c(-1), n(BLK_UNUSED), rewrite(false)
	{}

	/// pointer to a block
	byte * p;
	/// offset in the block's directory
	int c;
	/** block number
	 *
	 * n is kept in tandem with p.  The unassigned state is when
	 * p == 0 and n == BLK_UNUSED.
	 *
	 * Setting n to BLK_UNUSED is necessary in at least some cases.
	 */

	uint4 n;
	/// true if the block is not the same as on disk, and so needs rewriting
	bool rewrite;
};

class ChertTable;

/** A cursor pointing to a position in a Btree table, for reading several
 *  entries in order, or finding approximate matches.
 */
class ChertCursor {
    private:
	/// Copying not allowed
	ChertCursor(const ChertCursor &);

	/// Assignment not allowed
	ChertCursor & operator=(const ChertCursor &);

	/** Rebuild the cursor.
	 *
	 *  Called when the table has changed.
	 */
	void rebuild();

    protected:
	/** Whether the cursor is positioned at a valid entry.
	 *
	 *  false initially, and after the cursor has dropped
	 *  off either end of the list of items
	 */
	bool is_positioned;

	/** Whether the cursor is off the end of the table.
	 */
	bool is_after_end;

    private:
	/** Status of the current_tag member. */
	enum { UNREAD, UNCOMPRESSED, COMPRESSED } tag_status;

    protected:
	/// The Btree table
	const ChertTable * B;

    private:
	/// Pointer to an array of Cursors
	Cursor * C;

	unsigned long version;

	/** The value of level in the Btree structure. */
	int level;

	/** Get the key.
	 *
	 *  The key of the item at the cursor is copied into key.
	 *
	 *  The cursor must be positioned before calling this method.
	 *
	 *  e.g.
	 *
	 *    ChertCursor BC(&btree);
	 *    string key;
	 *
	 *    // Now do something to each key in the Btree
	 *    BC.find_entry(string()); // must give result true
	 *
	 *    while (BC.next()) {
	 *        BC.get_key(&key);
	 *        do_something_to(key);
	 *    }
	 */
	void get_key(string * key) const;

    public:
	/** Create a cursor attached to a Btree.
	 *
	 *  Creates a cursor, which can be used to remember a position inside
	 *  the B-tree. The position is simply the item (key and tag) to which
	 *  the cursor points. A cursor is either positioned or unpositioned,
	 *  and is initially unpositioned.
	 *
	 *  NB: You must not try to use a ChertCursor after the Btree it is
	 *  attached to is destroyed.  It's safe to destroy the ChertCursor
	 *  after the Btree though, you just may not use the ChertCursor.
	 */
	explicit ChertCursor(const ChertTable *B);

	/** Destroy the ChertCursor */
	~ChertCursor();

	/** Current key pointed to by cursor.
	 */
	string current_key;

	/** Current tag pointed to by cursor.  You must call read_tag to
	 *  make this value available.
	 */
	string current_tag;

	/** Read the tag from the table and store it in current_tag.
	 *
	 *  Some cursor users don't need the tag, so for efficiency we
	 *  only read it when asked to.
	 *
	 *  @param keep_compressed  Don't uncompress the tag - e.g. useful
	 *			    if it's just being opaquely copied
	 *			    (default: false).
	 *
	 *  @return	true if current_tag holds compressed data (always
	 *		false if keep_compressed was false).
	 */
	bool read_tag(bool keep_compressed = false);

	/** Advance to the next key.
	 *
	 *  If cursor is unpositioned, the result is simply false.
	 *
	 *  If cursor is positioned, and points to the very last item in the
	 *  Btree the cursor is made unpositioned, and the result is false.
	 *  Otherwise the cursor is moved to the next item in the B-tree,
	 *  and the result is true.
	 *
	 *  Effectively, ChertCursor::next() loses the position of BC when it
	 *  drops off the end of the list of items. If this is awkward, one can
	 *  always arrange for a key to be present which has a rightmost
	 *  position in a set of keys,
	 */
	bool next();

	/** Move to the previous key.
	 *
	 *  This is like ChertCursor::next, but BC is taken to the previous
	 *  rather than next item.
	 */
	bool prev();

	/** Position the cursor on the highest entry with key <= @a key.
	 *
	 *  If the exact key is found in the table, the cursor will be
	 *  set to point to it, and the method will return true.
	 *
	 *  If the key is not found, the cursor will be set to point to
	 *  the key preceding that asked for, and the method will return
	 *  false.  If there is no key preceding that asked for, the cursor
	 *  will point to a null key.
	 *
	 *  Note:  Since the B-tree always contains a null key, which precedes
	 *  everything, a call to ChertCursor::find_entry always results in a
	 *  valid key being pointed to by the cursor.
	 *
	 *  Note: Calling this method with a null key, then calling next()
	 *  will leave the cursor pointing to the first key.
	 *
	 *  @param key    The key to look for in the table.
	 *
	 *  @return true if the exact key was found in the table, false
	 *          otherwise.
	 */
	bool find_entry(const string &key);

	/// Position the cursor on the highest entry with key < @a key.
	void find_entry_lt(const string &key) {
	    if (find_entry(key)) prev();
	}

	/** Position the cursor on the lowest entry with key >= @a key.
	 *
	 *  @return true if the exact key was found in the table, false
	 *          otherwise.
	 */
	bool find_entry_ge(const string &key);

	/** Set the cursor to be off the end of the table.
	 */
	void to_end() { is_after_end = true; }

	/** Determine whether cursor is off the end of table.
	 *
	 *  @return true if the cursor has been moved off the end of the
	 *          table, past the last entry in it, and false otherwise.
	 */
	bool after_end() const { return is_after_end; }

	/// Return a pointer to the ChertTable we're a cursor for.
	const ChertTable * get_table() const { return B; }
};

class MutableChertCursor : public ChertCursor {
  public:
    /** Create a mutable cursor attached to a Btree.
     *
     *  A mutable cursor allows the items to be deleted.
     *
     *  Creates a cursor, which can be used to remember a position inside
     *  the B-tree. The position is simply the item (key and tag) to which
     *  the cursor points. A cursor is either positioned or unpositioned,
     *  and is initially unpositioned.
     *
     *  NB: You must not try to use a MutableChertCursor after the Btree it is
     *  attached to is destroyed.  It's safe to destroy the MutableChertCursor
     *  after the Btree though, you just may not use the MutableChertCursor.
     */
    explicit MutableChertCursor(ChertTable *B_) : ChertCursor(B_) { }

    /** Delete the current key/tag pair, leaving the cursor on the next
     *  entry.
     *
     *  @return false if the cursor ends up unpositioned.
     */
    bool del();
};

#endif /* OM_HGUARD_CHERT_CURSOR_H */