xapian-core  2.0.0
glass_cursor.h
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2002-2024 Olly Betts
6  *
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.
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, see
19  * <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef XAPIAN_INCLUDED_GLASS_CURSOR_H
23 #define XAPIAN_INCLUDED_GLASS_CURSOR_H
24 
25 #include "glass_defs.h"
26 
27 #include "alignment_cast.h"
28 #include "omassert.h"
29 
30 #include <algorithm>
31 #include <cstring>
32 #include <string>
33 #include <string_view>
34 
35 using std::string;
36 
37 #define BLK_UNUSED uint4(-1)
38 
39 namespace Glass {
40 
41 class Cursor {
42  // Prevent copying
43  Cursor(const Cursor &);
44  Cursor & operator=(const Cursor &);
45 
47  char * data;
48 
49  public:
51  Cursor() : data(0), c(-1), rewrite(false) { }
52 
53  ~Cursor() { destroy(); }
54 
55  uint8_t * init(unsigned block_size) {
56  if (data && refs() > 1) {
57  --refs();
58  data = NULL;
59  }
60  if (!data)
61  data = new char[block_size + 8];
62  refs() = 1;
64  rewrite = false;
65  c = -1;
66  return reinterpret_cast<uint8_t*>(data + 8);
67  }
68 
69  const uint8_t * clone(const Cursor & o) {
70  if (data != o.data) {
71  destroy();
72  data = o.data;
73  ++refs();
74  }
75  return reinterpret_cast<uint8_t*>(data + 8);
76  }
77 
78  void swap(Cursor & o) {
79  std::swap(data, o.data);
80  std::swap(c, o.c);
81  std::swap(rewrite, o.rewrite);
82  }
83 
84  void destroy() {
85  if (data) {
86  if (--refs() == 0)
87  delete [] data;
88  data = NULL;
89  rewrite = false;
90  }
91  }
92 
93  uint4 & refs() const {
94  Assert(data);
95  return *alignment_cast<uint4*>(data);
96  }
97 
102  uint4 get_n() const {
103  Assert(data);
104  return *alignment_cast<uint4*>(data + 4);
105  }
106 
107  void set_n(uint4 n) {
108  Assert(data);
109  // Assert(refs() == 1);
110  *alignment_cast<uint4*>(data + 4) = n;
111  }
112 
117  const uint8_t * get_p() const {
118  if (rare(!data)) return NULL;
119  return reinterpret_cast<uint8_t*>(data + 8);
120  }
121 
122  uint8_t * get_modifiable_p(unsigned block_size) {
123  if (rare(!data)) return NULL;
124  if (refs() > 1) {
125  char * new_data = new char[block_size + 8];
126  std::memcpy(new_data, data, block_size + 8);
127  --refs();
128  data = new_data;
129  refs() = 1;
130  }
131  return reinterpret_cast<uint8_t*>(data + 8);
132  }
133 
135  int c;
136 
138  bool rewrite;
139 };
140 
141 }
142 
143 class GlassTable;
144 
148 class GlassCursor {
151 
154 
159  void rebuild();
160 
161  protected:
168 
172 
173  private:
176 
177  protected:
179  const GlassTable * B;
180 
181  private:
184 
185  unsigned long version;
186 
188  int level;
189 
208  void get_key(string * key) const;
209 
210  public:
222  explicit GlassCursor(const GlassTable *B,
223  const Glass::Cursor * C_ = NULL);
224 
230  GlassCursor * clone() const {
231  return new GlassCursor(B, C);
232  }
233 
235  ~GlassCursor();
236 
239  string current_key;
240 
244  string current_tag;
245 
250  void rewind() {
251  (void)find_entry_ge({});
252  }
253 
266  bool read_tag(bool keep_compressed = false);
267 
282  bool next();
283 
306  bool find_entry(const string &key);
307 
316  bool find_exact(const string &key);
317 
319  void find_entry_lt(const string &key);
320 
326  bool find_entry_ge(std::string_view key);
327 
330  void to_end() { is_after_end = true; }
331 
337  bool after_end() const { return is_after_end; }
338 
340  const GlassTable * get_table() const { return B; }
341 };
342 
344  public:
358  explicit MutableGlassCursor(GlassTable *B_) : GlassCursor(B_) { }
359 
365  bool del();
366 };
367 
368 #ifdef DISABLE_GPL_LIBXAPIAN
369 # error GPL source we cannot relicense included in libxapian
370 #endif
371 
372 #endif /* XAPIAN_INCLUDED_GLASS_CURSOR_H */
Cast a pointer we know is suitably aligned.
Definition: unittest.cc:660
A cursor pointing to a position in a Btree table, for reading several entries in order,...
Definition: glass_cursor.h:148
const GlassTable * get_table() const
Return a pointer to the GlassTable we're a cursor for.
Definition: glass_cursor.h:340
GlassCursor & operator=(const GlassCursor &)
Assignment not allowed.
const GlassTable * B
The Btree table.
Definition: glass_cursor.h:179
void get_key(string *key) const
Get the key.
GlassCursor * clone() const
Clone a cursor.
Definition: glass_cursor.h:230
@ UNREAD_ON_LAST_CHUNK
Definition: glass_cursor.h:175
string current_key
Current key pointed to by cursor.
Definition: glass_cursor.h:239
bool find_exact(const string &key)
Position the cursor exactly on a key.
bool after_end() const
Determine whether cursor is off the end of table.
Definition: glass_cursor.h:337
bool find_entry(const string &key)
Position the cursor on the highest entry with key <= key.
void to_end()
Set the cursor to be off the end of the table.
Definition: glass_cursor.h:330
bool read_tag(bool keep_compressed=false)
Read the tag from the table and store it in current_tag.
int level
The value of level in the Btree structure.
Definition: glass_cursor.h:188
void rebuild()
Rebuild the cursor.
Definition: glass_cursor.cc:71
bool next()
Advance to the next key.
void rewind()
Position cursor on the dummy empty key.
Definition: glass_cursor.h:250
unsigned long version
Definition: glass_cursor.h:185
bool find_entry_ge(std::string_view key)
Position the cursor on the lowest entry with key >= key.
string current_tag
Current tag pointed to by cursor.
Definition: glass_cursor.h:244
~GlassCursor()
Destroy the GlassCursor.
Definition: glass_cursor.cc:99
void find_entry_lt(const string &key)
Position the cursor on the highest entry with key < key.
enum GlassCursor::@6 tag_status
Status of the current_tag member.
bool is_after_end
Whether the cursor is off the end of the table.
Definition: glass_cursor.h:171
bool is_positioned
Whether the cursor is positioned at a valid entry.
Definition: glass_cursor.h:167
Glass::Cursor * C
Pointer to an array of Cursors.
Definition: glass_cursor.h:183
GlassCursor(const GlassCursor &)
Copying not allowed.
Class managing a Btree table in a Glass database.
Definition: glass_table.h:432
Cursor & operator=(const Cursor &)
uint8_t * init(unsigned block_size)
Definition: glass_cursor.h:55
uint8_t * get_modifiable_p(unsigned block_size)
Definition: glass_cursor.h:122
bool rewrite
true if the block is not the same as on disk, and so needs rewriting
Definition: glass_cursor.h:138
void destroy()
Definition: glass_cursor.h:84
int c
offset in the block's directory
Definition: glass_cursor.h:135
void swap(Cursor &o)
Definition: glass_cursor.h:78
uint4 get_n() const
Get the block number.
Definition: glass_cursor.h:102
uint4 & refs() const
Definition: glass_cursor.h:93
char * data
Pointer to reference counted data.
Definition: glass_cursor.h:47
const uint8_t * clone(const Cursor &o)
Definition: glass_cursor.h:69
const uint8_t * get_p() const
Get pointer to block.
Definition: glass_cursor.h:117
void set_n(uint4 n)
Definition: glass_cursor.h:107
Cursor()
Constructor.
Definition: glass_cursor.h:51
Cursor(const Cursor &)
MutableGlassCursor(GlassTable *B_)
Create a mutable cursor attached to a Btree.
Definition: glass_cursor.h:358
bool del()
Delete the current key/tag pair, leaving the cursor on the next entry.
#define rare(COND)
Definition: config.h:607
#define BLK_UNUSED
Definition: glass_cursor.h:37
Definitions, types, etc for use inside glass.
#define false
Definition: header.h:9
uint32_t uint4
Definition: internaltypes.h:31
Various assertion macros.
#define Assert(COND)
Definition: omassert.h:122