xapian-core  1.4.29
glass_table.h
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2002-2025 Olly Betts
6  * Copyright 2008 Lemur Consulting Ltd
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23 
24 #ifndef OM_HGUARD_GLASS_TABLE_H
25 #define OM_HGUARD_GLASS_TABLE_H
26 
27 #include <xapian/constants.h>
28 #include <xapian/error.h>
29 
30 #include "glass_freelist.h"
31 #include "glass_cursor.h"
32 #include "glass_defs.h"
33 
34 #include "io_utils.h"
35 #include "noreturn.h"
36 #include "omassert.h"
37 #include "str.h"
38 #include "stringutils.h"
39 #include "wordaccess.h"
40 
42 
43 #include <algorithm>
44 #include <string>
45 
46 namespace Glass {
47 
50 const size_t BLOCK_CAPACITY = 4;
51 
57 #define GLASS_BTREE_MAX_KEY_LEN 255
58 
59 // FIXME: This named constant probably isn't used everywhere it should be...
60 const int BYTES_PER_BLOCK_NUMBER = 4;
61 
62 /* The B-tree blocks have a number of internal lengths and offsets held in 1, 2
63  or 4 bytes. To make the coding a little clearer,
64  we use for
65  ------ ---
66  K1 the 1 byte length of key
67  I2 the 2 byte length of an item (key-tag pair)
68  D2 the 2 byte offset to the item from the directory
69  X2 the 2 byte component counter that ends each key
70 */
71 
72 const int K1 = 1;
73 const int I2 = 2;
74 const int D2 = 2;
75 const int X2 = 2;
76 
77 /* and when getting or setting them, we use these methods of the various
78  * *Item* classes: */
79 
80 // getD(p, c)
81 // setD(p, c, x)
82 // getI()
83 // setI(x)
84 // getX(p, c)
85 // setX(p, c, x)
86 
87 /* if you've been reading the comments from the top, the next four procedures
88  will not cause any headaches.
89 
90  Recall that a leaf item has this form:
91 
92  i k x
93  | | |
94  I K key X tag
95  ←K→
96  <---SIZE---->
97  <---I--->
98 
99  Except that X is omitted for the first component of a tag (there is a flag
100  bit in the upper bits of I which indicates these).
101 
102  item_of(p, c) returns i, the address of the item at block address p,
103  directory offset c,
104 
105  component_of(p, c) returns the number marked 'x' above,
106 
107  last_component(p, c) returns true if this is a final component.
108 */
109 
110 inline uint4 REVISION(const uint8_t * b) { return aligned_read4(b); }
111 inline int GET_LEVEL(const uint8_t * b) { return b[4]; }
112 inline int MAX_FREE(const uint8_t * b) { return unaligned_read2(b + 5); }
113 inline int TOTAL_FREE(const uint8_t * b) { return unaligned_read2(b + 7); }
114 inline int DIR_END(const uint8_t * b) { return unaligned_read2(b + 9); }
115 const int DIR_START = 11;
116 
117 inline void SET_REVISION(uint8_t * b, uint4 rev) { aligned_write4(b, rev); }
118 inline void SET_LEVEL(uint8_t * b, int x) { AssertRel(x,<,256); b[4] = x; }
119 inline void SET_MAX_FREE(uint8_t * b, int x) { unaligned_write2(b + 5, x); }
120 inline void SET_TOTAL_FREE(uint8_t * b, int x) { unaligned_write2(b + 7, x); }
121 inline void SET_DIR_END(uint8_t * b, int x) { unaligned_write2(b + 9, x); }
122 
123 // The item size is stored in 2 bytes, but the top bit is used to store a flag for
124 // "is the tag data compressed" and the next two bits are used to flag if this is the
125 // first and/or last item for this tag.
126 const int I_COMPRESSED_BIT = 0x80;
127 const int I_LAST_BIT = 0x40;
128 const int I_FIRST_BIT = 0x20;
129 
130 const int I_MASK = (I_COMPRESSED_BIT|I_LAST_BIT|I_FIRST_BIT);
131 
132 const int ITEM_SIZE_MASK = (0xffff &~ (I_MASK << 8));
133 const size_t MAX_ITEM_SIZE = (ITEM_SIZE_MASK + 3);
134 
136 const int LEVEL_FREELIST = 254;
137 
138 class RootInfo;
139 
140 class Key {
141  const uint8_t *p;
142  public:
143  explicit Key(const uint8_t * p_) : p(p_) { }
144  const uint8_t * get_address() const { return p; }
145  const uint8_t * data() const { return p + K1; }
146  void read(std::string * key) const {
147  key->assign(reinterpret_cast<const char *>(p + K1), length());
148  }
149  int length() const {
150  return p[0];
151  }
152  char operator[](size_t i) const {
153  AssertRel(i,<,size_t(length()));
154  return p[i + K1];
155  }
156 };
157 
158 // LeafItem_wr wants to be "LeafItem with non-const p and more methods" - we can't
159 // achieve that nicely with inheritance, so we use a template base class.
160 template<class T> class LeafItem_base {
161  protected:
162  T p;
163  int get_key_len() const { return p[I2]; }
164  static int getD(const uint8_t * q, int c) {
165  AssertRel(c, >=, DIR_START);
166  AssertRel(c, <, 65535);
167  Assert((c & 1) == 1);
168  return unaligned_read2(q + c);
169  }
170  int getI() const { return unaligned_read2(p); }
171  static int getX(const uint8_t * q, int c) { return unaligned_read2(q + c); }
172  public:
173  /* LeafItem from block address and offset to item pointer */
174  LeafItem_base(T p_, int c) : p(p_ + getD(p_, c)) { }
175  explicit LeafItem_base(T p_) : p(p_) { }
176 
177  void init(T p_, int c) { p = p_ + getD(p_, c); }
178  void init(T p_) { p = p_; }
179 
180  T get_address() const { return p; }
182  int size() const {
183  return (getI() & ITEM_SIZE_MASK) + 3;
184  }
185  bool get_compressed() const { return *p & I_COMPRESSED_BIT; }
186  bool first_component() const { return *p & I_FIRST_BIT; }
187  bool last_component() const { return *p & I_LAST_BIT; }
188  int component_of() const {
189  if (first_component()) return 1;
190  return getX(p, get_key_len() + I2 + K1);
191  }
192  Key key() const { return Key(p + I2); }
193  void append_chunk(std::string * tag) const {
194  // Offset to the start of the tag data.
195  int cd = get_key_len() + I2 + K1;
196  if (!first_component()) cd += X2;
197  // Number of bytes to extract from current component.
198  int l = size() - cd;
199  const char * chunk = reinterpret_cast<const char *>(p + cd);
200  tag->append(chunk, l);
201  }
202  bool decompress_chunk(CompressionStream& comp_stream, string& tag) const {
203  // Offset to the start of the tag data.
204  int cd = get_key_len() + I2 + K1;
205  if (!first_component()) cd += X2;
206  // Number of bytes to extract from current component.
207  int l = size() - cd;
208  const char * chunk = reinterpret_cast<const char *>(p + cd);
209  return comp_stream.decompress_chunk(chunk, l, tag);
210  }
211 };
212 
213 class LeafItem : public LeafItem_base<const uint8_t *> {
214  public:
215  /* LeafItem from block address and offset to item pointer */
216  LeafItem(const uint8_t * p_, int c)
217  : LeafItem_base<const uint8_t *>(p_, c) { }
218  explicit LeafItem(const uint8_t * p_)
219  : LeafItem_base<const uint8_t *>(p_) { }
220 };
221 
222 class LeafItem_wr : public LeafItem_base<uint8_t *> {
223  void set_key_len(int x) {
224  AssertRel(x, >=, 0);
226  p[I2] = x;
227  }
228  void setI(int x) { unaligned_write2(p, x); }
229  static void setX(uint8_t * q, int c, int x) { unaligned_write2(q + c, x); }
230  public:
231  /* LeafItem_wr from block address and offset to item pointer */
232  LeafItem_wr(uint8_t * p_, int c) : LeafItem_base<uint8_t *>(p_, c) { }
233  explicit LeafItem_wr(uint8_t * p_) : LeafItem_base<uint8_t *>(p_) { }
234  void set_component_of(int i) {
235  AssertRel(i,>,1);
236  *p &=~ I_FIRST_BIT;
237  setX(p, get_key_len() + I2 + K1, i);
238  }
239  void set_size(int new_size) {
240  AssertRel(new_size,>=,3);
241  int I = new_size - 3;
242  // We should never be able to pass too large a size here, but don't
243  // corrupt the database if this somehow happens.
244  if (rare(I &~ ITEM_SIZE_MASK)) throw Xapian::DatabaseError("item too large!");
245  setI(I);
246  }
247  void form_key(const std::string & key_) {
248  std::string::size_type key_len = key_.length();
249  if (key_len > GLASS_BTREE_MAX_KEY_LEN) {
250  // We check term length when a term is added to a document but
251  // glass doubles zero bytes, so this can still happen for terms
252  // which contain one or more zero bytes.
253  std::string msg("Key too long: length was ");
254  msg += str(key_len);
255  msg += " bytes, maximum length of a key is "
257  throw Xapian::InvalidArgumentError(msg);
258  }
259 
260  set_key_len(key_len);
261  std::memmove(p + I2 + K1, key_.data(), key_len);
262  *p |= I_FIRST_BIT;
263  }
264  // FIXME passing cd here is icky
265  void set_tag(int cd, const char *start, int len, bool compressed, int i, int m) {
266  std::memmove(p + cd, start, len);
267  set_size(cd + len);
268  if (compressed) *p |= I_COMPRESSED_BIT;
269  if (i == m) *p |= I_LAST_BIT;
270  if (i == 1) {
271  *p |= I_FIRST_BIT;
272  } else {
273  set_component_of(i);
274  }
275  }
276  void fake_root_item() {
277  set_key_len(0); // null key length
278  set_size(I2 + K1); // length of the item
279  *p |= I_FIRST_BIT|I_LAST_BIT;
280  }
281  operator const LeafItem() const { return LeafItem(p); }
282  static void setD(uint8_t * q, int c, int x) {
283  AssertRel(c, >=, DIR_START);
284  AssertRel(c, <, 65535);
285  Assert((c & 1) == 1);
286  unaligned_write2(q + c, x);
287  }
288 };
289 
290 /* A branch item has this form:
291 
292  k x
293  | |
294  tag K key X
295  ←B→ ←K→
296  <--SIZE--->
297 
298  B = BYTES_PER_BLOCK_NUMBER
299 
300  We can't omit X here, as we've nowhere to store the first and last bit
301  flags which we have in leaf items.
302 */
303 
304 // BItem_wr wants to be "BItem with non-const p and more methods" - we can't
305 // achieve that nicely with inheritance, so we use a template base class.
306 template<class T> class BItem_base {
307  protected:
308  T p;
309  int get_key_len() const { return p[BYTES_PER_BLOCK_NUMBER]; }
310  static int getD(const uint8_t * q, int c) {
311  AssertRel(c, >=, DIR_START);
312  AssertRel(c, <, 65535);
313  Assert((c & 1) == 1);
314  return unaligned_read2(q + c);
315  }
316  static int getX(const uint8_t * q, int c) { return unaligned_read2(q + c); }
317  public:
318  /* BItem from block address and offset to item pointer */
319  BItem_base(T p_, int c) : p(p_ + getD(p_, c)) { }
320  explicit BItem_base(T p_) : p(p_) { }
321  T get_address() const { return p; }
323  int size() const {
324  return get_key_len() + K1 + X2 + BYTES_PER_BLOCK_NUMBER;
325  }
326  Key key() const { return Key(p + BYTES_PER_BLOCK_NUMBER); }
331  return unaligned_read4(p);
332  }
333  int component_of() const {
334  return getX(p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1);
335  }
336 };
337 
338 class BItem : public BItem_base<const uint8_t *> {
339  public:
340  /* BItem from block address and offset to item pointer */
341  BItem(const uint8_t * p_, int c) : BItem_base<const uint8_t *>(p_, c) { }
342  explicit BItem(const uint8_t * p_) : BItem_base<const uint8_t *>(p_) { }
343 };
344 
345 class BItem_wr : public BItem_base<uint8_t *> {
346  void set_key_len(int x) {
347  AssertRel(x, >=, 0);
350  }
351  static void setX(uint8_t * q, int c, int x) { unaligned_write2(q + c, x); }
352  public:
353  /* BItem_wr from block address and offset to item pointer */
354  BItem_wr(uint8_t * p_, int c) : BItem_base<uint8_t *>(p_, c) { }
355  explicit BItem_wr(uint8_t * p_) : BItem_base<uint8_t *>(p_) { }
356  void set_component_of(int i) {
357  setX(p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1, i);
358  }
359  void set_key_and_block(Key newkey, uint4 n) {
360  int len = newkey.length() + K1 + X2;
361  // Copy the key size, main part of the key and the count part.
362  std::memcpy(p + BYTES_PER_BLOCK_NUMBER, newkey.get_address(), len);
363  // Set tag contents to block number
364  set_block_given_by(n);
365  }
366  // Takes size as we may be truncating newkey.
367  void set_truncated_key_and_block(Key newkey, int new_comp,
368  int truncate_size, uint4 n) {
369  int i = truncate_size;
370  AssertRel(i,<=,newkey.length());
371  // Key size
372  set_key_len(i);
373  // Copy the main part of the key, possibly truncating.
374  std::memcpy(p + BYTES_PER_BLOCK_NUMBER + K1, newkey.get_address() + K1, i);
375  // Set the component count.
376  setX(p, BYTES_PER_BLOCK_NUMBER + K1 + i, new_comp);
377  // Set tag contents to block number
378  set_block_given_by(n);
379  }
380 
385  unaligned_write4(p, n);
386  }
390  set_block_given_by(n);
391  set_key_len(0); /* null key */
392  set_component_of(0);
393  }
394  operator const BItem() const { return BItem(p); }
395  static void setD(uint8_t * q, int c, int x) {
396  AssertRel(c, >=, DIR_START);
397  AssertRel(c, <, 65535);
398  Assert((c & 1) == 1);
399  unaligned_write2(q + c, x);
400  }
401 };
402 
403 }
404 
405 using Glass::RootInfo;
406 
407 class GlassChanges;
408 
429 class GlassTable {
430  friend class GlassCursor; /* Should probably fix this. */
431  friend class GlassFreeList;
432 
433  private:
435  GlassTable(const GlassTable &);
436 
438  GlassTable & operator=(const GlassTable &);
439 
440  void basic_open(const RootInfo * root_info,
442 
444  void do_open_to_read(const RootInfo * root_info,
446 
448  void do_open_to_write(const RootInfo * root_info,
450 
451  public:
466  GlassTable(const char * tablename_, const std::string & path_,
467  bool readonly_, bool lazy = false);
468 
469  GlassTable(const char * tablename_, int fd, off_t offset_,
470  bool readonly_, bool lazy = false);
471 
477  ~GlassTable();
478 
484  void close(bool permanent = false);
485 
486  bool readahead_key(const string &key) const;
487 
490  bool exists() const;
491 
503  void open(int flags_, const RootInfo & root_info,
505 
510  bool is_open() const { return handle >= 0; }
511 
513  bool is_writable() const { return writable; }
514 
520  void flush_db();
521 
537  void commit(glass_revision_number_t revision, RootInfo * root_info);
538 
539  bool sync() {
540  return (flags & Xapian::DB_NO_SYNC) ||
541  handle < 0 ||
542  io_sync(handle);
543  }
544 
550  void cancel(const RootInfo & root_info, glass_revision_number_t rev);
551 
566  bool get_exact_entry(const std::string & key, std::string & tag) const;
567 
579  bool key_exists(const std::string &key) const;
580 
589  bool read_tag(Glass::Cursor* C_,
590  std::string* tag,
591  bool keep_compressed) const;
592 
609  void add(const std::string& key,
610  const std::string& tag,
611  bool already_compressed = false);
612 
628  bool del(const std::string &key);
629 
630  int get_flags() const { return flags; }
631 
655  void create_and_open(int flags_, const RootInfo & root_info);
656 
657  void set_full_compaction(bool parity);
658 
668  return revision_number;
669  }
670 
681  return item_count;
682  }
683 
685  bool empty() const {
686  return (item_count == 0);
687  }
688 
694  GlassCursor * cursor_get() const;
695 
701  bool is_modified() const { return Btree_modified; }
702 
708  void set_max_item_size(size_t block_capacity) {
709  if (block_capacity > Glass::BLOCK_CAPACITY)
710  block_capacity = Glass::BLOCK_CAPACITY;
711  using Glass::DIR_START;
712  using Glass::D2;
713  max_item_size =
714  (block_size - DIR_START - block_capacity * D2) / block_capacity;
715  // Make sure we don't exceed the limit imposed by the format.
716  if (max_item_size > Glass::MAX_ITEM_SIZE)
717  max_item_size = Glass::MAX_ITEM_SIZE;
718  }
719 
725  void set_changes(GlassChanges * changes) {
726  changes_obj = changes;
727  }
728 
730  XAPIAN_NORETURN(static void throw_database_closed());
731 
732  string get_path() const {
733  return name + GLASS_TABLE_EXTENSION;
734  }
735 
736  protected:
737  bool find(Glass::Cursor *) const;
738  int delete_kt();
739  void read_block(uint4 n, uint8_t *p) const;
740  void write_block(uint4 n, const uint8_t *p,
741  bool appending = false) const;
742  XAPIAN_NORETURN(void set_overwritten() const);
743  void block_to_cursor(Glass::Cursor *C_, int j, uint4 n) const;
744  void alter();
745  void compact(uint8_t *p);
746  void enter_key_above_leaf(Glass::LeafItem previtem,
747  Glass::LeafItem newitem);
748  void enter_key_above_branch(int j, Glass::BItem newitem);
749  int mid_point(uint8_t *p) const;
750  void add_item_to_leaf(uint8_t *p, Glass::LeafItem kt, int c);
751  void add_item_to_branch(uint8_t *p, Glass::BItem kt, int c);
752  void add_leaf_item(Glass::LeafItem kt);
753  void add_branch_item(Glass::BItem kt, int j);
754  void delete_leaf_item(bool repeatedly);
755  void delete_branch_item(int j);
756  int add_kt(bool found);
757  void read_root();
758  void split_root(uint4 split_n);
759  void form_key(const std::string & key) const;
760 
762  const char * tablename;
763 
766 
769 
771  unsigned int block_size;
772 
774  int flags;
775 
781 
786 
794  int handle;
795 
797  int level;
798 
801 
804 
806  uint8_t * buffer;
807 
810 
815  std::string name;
816 
821 
824 
828 
831 
833  mutable bool Btree_modified;
834 
837 
839  bool writable;
840 
843 
845  unsigned long cursor_version;
846 
852 
853  bool single_file() const {
854  return name.empty();
855  }
856 
857  /* B-tree navigation functions */
858  bool prev(Glass::Cursor *C_, int j) const {
859  if (sequential && !single_file())
860  return prev_for_sequential(C_, j);
861  return prev_default(C_, j);
862  }
863 
864  bool next(Glass::Cursor *C_, int j) const {
865  if (sequential) return next_for_sequential(C_, j);
866  return next_default(C_, j);
867  }
868 
869  /* Default implementations. */
870  bool prev_default(Glass::Cursor *C_, int j) const;
871  bool next_default(Glass::Cursor *C_, int j) const;
872 
873  /* Implementations for sequential mode. */
874  bool prev_for_sequential(Glass::Cursor *C_, int dummy) const;
875  bool next_for_sequential(Glass::Cursor *C_, int dummy) const;
876 
877  static int find_in_leaf(const uint8_t * p,
878  Glass::LeafItem item, int c, bool& exact);
879  static int find_in_branch(const uint8_t * p,
880  Glass::LeafItem item, int c);
881  static int find_in_branch(const uint8_t * p, Glass::BItem item, int c);
882 
886  static uint4 block_given_by(const uint8_t * p, int c);
887 
889 
895  uint8_t * split_p;
896 
899 
901 
903  bool lazy;
904 
907 
909  off_t offset;
910 
911  /* Debugging methods */
912 // void report_block_full(int m, int n, const uint8_t * p);
913 };
914 
915 namespace Glass {
916 
933 template<typename ITEM1, typename ITEM2>
934 int compare(ITEM1 a, ITEM2 b)
935 {
936  Key key1 = a.key();
937  Key key2 = b.key();
938  const uint8_t* p1 = key1.data();
939  const uint8_t* p2 = key2.data();
940  int key1_len = key1.length();
941  int key2_len = key2.length();
942  int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
943 
944  // Compare the common part of the keys.
945  int diff = std::memcmp(p1, p2, k_smaller);
946  if (diff == 0) {
947  // If the common part matches, compare the lengths.
948  diff = key1_len - key2_len;
949  if (diff == 0) {
950  // If the strings match, compare component_of().
951  diff = a.component_of() - b.component_of();
952  }
953  }
954  return diff;
955 }
956 
962 inline int
964 {
965  Key key1 = a.key();
966  Key key2 = b.key();
967  const uint8_t* p1 = key1.data();
968  const uint8_t* p2 = key2.data();
969  int key1_len = key1.length();
970  int key2_len = key2.length();
971  if (key1_len == key2_len) {
972  // The keys are the same length, so we can compare the counts in the
973  // same operation since they're stored as 2 byte bigendian numbers.
974  int len = key1_len + X2;
975  return std::memcmp(p1, p2, len);
976  }
977 
978  int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
979 
980  // Compare the common part of the keys.
981  int diff = std::memcmp(p1, p2, k_smaller);
982  if (diff == 0) {
983  // If the common part matches, compare the lengths.
984  diff = key1_len - key2_len;
985  // We dealt with the "same length" case above so we never need to check
986  // component_of here.
987  }
988  return diff;
989 }
990 
991 }
992 
993 #endif /* OM_HGUARD_GLASS_TABLE_H */
int close(FD &fd)
Definition: fd.h:63
#define Assert(COND)
Definition: omassert.h:122
LeafItem(const uint8_t *p_)
Definition: glass_table.h:218
Define the XAPIAN_NORETURN macro.
static void setD(uint8_t *q, int c, int x)
Definition: glass_table.h:395
int component_of() const
Definition: glass_table.h:188
void write_block(const GlassTable *B, uint4 n, uint8_t *p, uint4 rev)
glass_revision_number_t get_open_revision_number() const
Get the revision number at which this table is currently open.
Definition: glass_table.h:667
off_t offset
offset to start of table in file.
Definition: glass_table.h:909
Glass::LeafItem_wr kt
buffer of size block_size for making up key-tag items
Definition: glass_table.h:803
void init(T p_, int c)
Definition: glass_table.h:177
XAPIAN_REVISION_TYPE rev
Revision number of a database.
Definition: types.h:133
const int I_LAST_BIT
Definition: glass_table.h:127
const size_t BLOCK_CAPACITY
Even for items of at maximum size, it must be possible to get this number of items in a block...
Definition: glass_table.h:50
void commit(const GlassTable *B, uint4 block_size)
#define AssertRel(A, REL, B)
Definition: omassert.h:123
void unaligned_write4(unsigned char *ptr, T value)
Definition: wordaccess.h:177
#define GLASS_BTREE_MAX_KEY_LEN
The largest possible value of a key_len.
Definition: glass_table.h:57
bool first_component() const
Definition: glass_table.h:186
int TOTAL_FREE(const uint8_t *b)
Definition: glass_table.h:113
void set_key_len(int x)
Definition: glass_table.h:223
const int I_MASK
Definition: glass_table.h:130
bool empty() const
Return true if there are no entries in the table.
Definition: glass_table.h:685
int changed_c
directory offset corresponding to last block to be changed by an addition
Definition: glass_table.h:827
int component_of() const
Definition: glass_table.h:333
uint16_t unaligned_read2(const unsigned char *ptr)
Definition: wordaccess.h:163
Class managing a Btree table in a Glass database.
Definition: glass_table.h:429
uint4 REVISION(const uint8_t *b)
Definition: glass_table.h:110
static int getX(const uint8_t *q, int c)
Definition: glass_table.h:316
uint4 glass_revision_number_t
The revision number of a glass database.
Definition: glass_defs.h:68
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
Definition: io_utils.h:73
uint8_t * split_p
Buffer used when splitting a block.
Definition: glass_table.h:895
unsigned long cursor_version
Version count for tracking when cursors need to rebuild.
Definition: glass_table.h:845
void set_block_given_by(uint4 n)
Set this item&#39;s tag to point to block n (this block should not be at level 0).
Definition: glass_table.h:384
Constants in the Xapian namespace.
bool writable
Set to true when the database is opened to write.
Definition: glass_table.h:839
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
Definition: dbfactory.h:104
#define STRINGIZE(X)
The STRINGIZE macro converts its parameter into a string constant.
Definition: stringutils.h:36
void set_truncated_key_and_block(Key newkey, int new_comp, int truncate_size, uint4 n)
Definition: glass_table.h:367
Definitions, types, etc for use inside glass.
Convert types to std::string.
int handle
File descriptor of the table.
Definition: glass_table.h:794
void set_key_and_block(Key newkey, uint4 n)
Definition: glass_table.h:359
int revision()
Report the revision of the library which the program is linked with.
Definition: xapian.h:142
BItem(const uint8_t *p_)
Definition: glass_table.h:342
static void throw_database_closed()
bool lazy
If true, don&#39;t create the table until it&#39;s needed.
Definition: glass_table.h:903
void set_component_of(int i)
Definition: glass_table.h:234
BItem(const uint8_t *p_, int c)
Definition: glass_table.h:341
string get_path() const
Definition: glass_table.h:732
void SET_MAX_FREE(uint8_t *b, int x)
Definition: glass_table.h:119
const size_t MAX_ITEM_SIZE
Definition: glass_table.h:133
#define rare(COND)
Definition: config.h:575
int flags
Flags like DB_NO_SYNC and DB_DANGEROUS.
Definition: glass_table.h:774
static int getX(const uint8_t *q, int c)
Definition: glass_table.h:171
bool full_compaction
set to true when full compaction is to be achieved
Definition: glass_table.h:836
unsigned long long glass_tablesize_t
How many entries there are in a table.
Definition: glass_defs.h:71
static int getD(const uint8_t *q, int c)
Definition: glass_table.h:310
int size() const
SIZE in diagram above.
Definition: glass_table.h:182
#define GLASS_TABLE_EXTENSION
Glass table extension.
Definition: glass_defs.h:27
uint4 changed_n
the last block to be changed by an addition
Definition: glass_table.h:823
bool next(Glass::Cursor *C_, int j) const
Definition: glass_table.h:864
int get_key_len() const
Definition: glass_table.h:163
void aligned_write4(unsigned char *ptr, T value)
Definition: wordaccess.h:170
void set_size(int new_size)
Definition: glass_table.h:239
int MAX_FREE(const uint8_t *b)
Definition: glass_table.h:112
int compare(ITEM1 a, ITEM2 b)
Compare two items by their keys.
Definition: glass_table.h:934
Hierarchy of classes which Xapian can throw as exceptions.
BItem_wr(uint8_t *p_, int c)
Definition: glass_table.h:354
class wrapper around zlib
const int K1
Definition: glass_table.h:72
const char * dummy[]
Definition: version_h.cc:7
void operator=(const GlassFreeList &)
InvalidArgumentError indicates an invalid parameter value was passed to the API.
Definition: error.h:241
void read(std::string *key) const
Definition: glass_table.h:146
LeafItem_wr(uint8_t *p_)
Definition: glass_table.h:233
const char * tablename
The name of the table (used when writing changesets).
Definition: glass_table.h:762
uint32_t uint4
Definition: internaltypes.h:32
glass_tablesize_t item_count
keeps a count of the number of items in the B-tree.
Definition: glass_table.h:768
bool sync()
Definition: glass_table.h:539
functions for reading and writing different width words
int GET_LEVEL(const uint8_t *b)
Definition: glass_table.h:111
static void setX(uint8_t *q, int c, int x)
Definition: glass_table.h:229
Glass freelist.
bool is_modified() const
Determine whether the object contains uncommitted modifications.
Definition: glass_table.h:701
const uint8_t * get_address() const
Definition: glass_table.h:144
bool decompress_chunk(CompressionStream &comp_stream, string &tag) const
Definition: glass_table.h:202
GlassChanges * changes_obj
The GlassChanges object to write block changes to.
Definition: glass_table.h:851
uint4 last_readahead
Last block readahead_key() preread.
Definition: glass_table.h:906
void form_key(const std::string &key_)
Definition: glass_table.h:247
int length() const
Definition: glass_table.h:149
bool single_file() const
Definition: glass_table.h:853
void setI(int x)
Definition: glass_table.h:228
bool decompress_chunk(const char *p, int len, std::string &buf)
Returns true if this was the final chunk.
BItem_wr(uint8_t *p_)
Definition: glass_table.h:355
uint32_t aligned_read4(const unsigned char *ptr)
Definition: wordaccess.h:145
int get_flags() const
Definition: glass_table.h:630
const int I_FIRST_BIT
Definition: glass_table.h:128
const int I2
Definition: glass_table.h:73
string str(int value)
Convert int to std::string.
Definition: str.cc:90
LeafItem(const uint8_t *p_, int c)
Definition: glass_table.h:216
void SET_LEVEL(uint8_t *b, int x)
Definition: glass_table.h:118
bool get_compressed() const
Definition: glass_table.h:185
const int D2
Definition: glass_table.h:74
void set_tag(int cd, const char *start, int len, bool compressed, int i, int m)
Definition: glass_table.h:265
const uint8_t * p
Definition: glass_table.h:141
void read_block(const GlassTable *B, uint4 n, uint8_t *p)
static int getD(const uint8_t *q, int c)
Definition: glass_table.h:164
bool last_component() const
Definition: glass_table.h:187
const int ITEM_SIZE_MASK
Definition: glass_table.h:132
CompressionStream comp_stream
Definition: glass_table.h:900
char operator[](size_t i) const
Definition: glass_table.h:152
int DIR_END(const uint8_t *b)
Definition: glass_table.h:114
LeafItem_base(T p_, int c)
Definition: glass_table.h:174
void set_component_of(int i)
Definition: glass_table.h:356
void set_max_item_size(size_t block_capacity)
Set the maximum item size given the block capacity.
Definition: glass_table.h:708
int seq_count
count of the number of successive instances of purely sequential addition, starting at SEQ_START_POIN...
Definition: glass_table.h:820
bool is_open() const
Return true if this table is open.
Definition: glass_table.h:510
LeafItem_wr(uint8_t *p_, int c)
Definition: glass_table.h:232
A cursor pointing to a position in a Btree table, for reading several entries in order, or finding approximate matches.
Definition: glass_cursor.h:147
const int DB_NO_SYNC
Don&#39;t attempt to ensure changes have hit disk.
Definition: constants.h:66
void set_changes(GlassChanges *changes)
Set the GlassChanges object to write changed blocks to.
Definition: glass_table.h:725
const int DIR_START
Definition: glass_table.h:115
#define GLASS_BTREE_CURSOR_LEVELS
Allow for this many levels in the B-tree.
Definition: glass_defs.h:43
int size() const
SIZE in diagram above.
Definition: glass_table.h:323
std::string name
The path name of the B tree.
Definition: glass_table.h:815
static void setD(uint8_t *q, int c, int x)
Definition: glass_table.h:282
bool Btree_modified
Set to true the first time the B-tree is modified.
Definition: glass_table.h:833
unsigned int block_size
block size of the B tree in bytes
Definition: glass_table.h:771
const uint8_t * data() const
Definition: glass_table.h:145
Key key() const
Definition: glass_table.h:326
const int LEVEL_FREELIST
Freelist blocks have their level set to LEVEL_FREELIST.
Definition: glass_table.h:136
void unaligned_write2(unsigned char *ptr, T value)
Definition: wordaccess.h:191
uint8_t * buffer
buffer of size block_size for reforming blocks
Definition: glass_table.h:806
glass_tablesize_t get_entry_count() const
Return a count of the number of entries in the table.
Definition: glass_table.h:680
void append_chunk(std::string *tag) const
Definition: glass_table.h:193
Interface to Btree cursors.
static void setX(uint8_t *q, int c, int x)
Definition: glass_table.h:351
bool faked_root_block
true if the root block is faked (not written to disk).
Definition: glass_table.h:780
size_t max_item_size
maximum size of an item (key-tag pair)
Definition: glass_table.h:830
bool prev(Glass::Cursor *C_, int j) const
Definition: glass_table.h:858
const int X2
Definition: glass_table.h:75
Wrappers for low-level POSIX I/O routines.
void set_key_len(int x)
Definition: glass_table.h:346
void SET_DIR_END(uint8_t *b, int x)
Definition: glass_table.h:121
Various handy helpers which std::string really should provide.
void SET_REVISION(uint8_t *b, uint4 rev)
Definition: glass_table.h:117
GlassFreeList free_list
List of free blocks.
Definition: glass_table.h:809
uint4 compress_min
Minimum size tag to try compressing (0 for no compression).
Definition: glass_table.h:898
Definition: header.h:151
BItem_base(T p_, int c)
Definition: glass_table.h:319
const int BYTES_PER_BLOCK_NUMBER
Definition: glass_table.h:60
T get_address() const
Definition: glass_table.h:321
Various assertion macros.
glass_revision_number_t revision_number
revision number of the opened B-tree.
Definition: glass_table.h:765
DatabaseError indicates some sort of database related error.
Definition: error.h:367
Key(const uint8_t *p_)
Definition: glass_table.h:143
const int I_COMPRESSED_BIT
Definition: glass_table.h:126
uint4 root
the root block of the B-tree
Definition: glass_table.h:800
void form_null_key(uint4 n)
Form an item with a null key and with block number n in the tag.
Definition: glass_table.h:389
int level
number of levels, counting from 0
Definition: glass_table.h:797
bool sequential
true iff the data has been written in a single write in sequential order.
Definition: glass_table.h:785
void SET_TOTAL_FREE(uint8_t *b, int x)
Definition: glass_table.h:120
bool cursor_created_since_last_modification
Flag for tracking when cursors need to rebuild.
Definition: glass_table.h:842
bool is_writable() const
Return true if this table is writable.
Definition: glass_table.h:513
uint4 block_given_by() const
Get this item&#39;s tag as a block number (this block should not be at level 0).
Definition: glass_table.h:330
#define C(X)
int get_key_len() const
Definition: glass_table.h:309
uint32_t unaligned_read4(const unsigned char *ptr)
Definition: wordaccess.h:151