xapian-core  1.4.19
glass_table.h
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2016 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  T get_address() const { return p; }
178  int size() const {
179  return (getI() & ITEM_SIZE_MASK) + 3;
180  }
181  bool get_compressed() const { return *p & I_COMPRESSED_BIT; }
182  bool first_component() const { return *p & I_FIRST_BIT; }
183  bool last_component() const { return *p & I_LAST_BIT; }
184  int component_of() const {
185  if (first_component()) return 1;
186  return getX(p, get_key_len() + I2 + K1);
187  }
188  Key key() const { return Key(p + I2); }
189  void append_chunk(std::string * tag) const {
190  // Offset to the start of the tag data.
191  int cd = get_key_len() + I2 + K1;
192  if (!first_component()) cd += X2;
193  // Number of bytes to extract from current component.
194  int l = size() - cd;
195  const char * chunk = reinterpret_cast<const char *>(p + cd);
196  tag->append(chunk, l);
197  }
198  bool decompress_chunk(CompressionStream& comp_stream, string& tag) const {
199  // Offset to the start of the tag data.
200  int cd = get_key_len() + I2 + K1;
201  if (!first_component()) cd += X2;
202  // Number of bytes to extract from current component.
203  int l = size() - cd;
204  const char * chunk = reinterpret_cast<const char *>(p + cd);
205  return comp_stream.decompress_chunk(chunk, l, tag);
206  }
207 };
208 
209 class LeafItem : public LeafItem_base<const uint8_t *> {
210  public:
211  /* LeafItem from block address and offset to item pointer */
212  LeafItem(const uint8_t * p_, int c)
213  : LeafItem_base<const uint8_t *>(p_, c) { }
214  explicit LeafItem(const uint8_t * p_)
215  : LeafItem_base<const uint8_t *>(p_) { }
216 };
217 
218 class LeafItem_wr : public LeafItem_base<uint8_t *> {
219  void set_key_len(int x) {
220  AssertRel(x, >=, 0);
222  p[I2] = x;
223  }
224  void setI(int x) { unaligned_write2(p, x); }
225  static void setX(uint8_t * q, int c, int x) { unaligned_write2(q + c, x); }
226  public:
227  /* LeafItem_wr from block address and offset to item pointer */
228  LeafItem_wr(uint8_t * p_, int c) : LeafItem_base<uint8_t *>(p_, c) { }
229  explicit LeafItem_wr(uint8_t * p_) : LeafItem_base<uint8_t *>(p_) { }
230  void set_component_of(int i) {
231  AssertRel(i,>,1);
232  *p &=~ I_FIRST_BIT;
233  setX(p, get_key_len() + I2 + K1, i);
234  }
235  void set_size(int new_size) {
236  AssertRel(new_size,>=,3);
237  int I = new_size - 3;
238  // We should never be able to pass too large a size here, but don't
239  // corrupt the database if this somehow happens.
240  if (rare(I &~ ITEM_SIZE_MASK)) throw Xapian::DatabaseError("item too large!");
241  setI(I);
242  }
243  void form_key(const std::string & key_) {
244  std::string::size_type key_len = key_.length();
245  if (key_len > GLASS_BTREE_MAX_KEY_LEN) {
246  // We check term length when a term is added to a document but
247  // glass doubles zero bytes, so this can still happen for terms
248  // which contain one or more zero bytes.
249  std::string msg("Key too long: length was ");
250  msg += str(key_len);
251  msg += " bytes, maximum length of a key is "
253  throw Xapian::InvalidArgumentError(msg);
254  }
255 
256  set_key_len(key_len);
257  std::memmove(p + I2 + K1, key_.data(), key_len);
258  *p |= I_FIRST_BIT;
259  }
260  // FIXME passing cd here is icky
261  void set_tag(int cd, const char *start, int len, bool compressed, int i, int m) {
262  std::memmove(p + cd, start, len);
263  set_size(cd + len);
264  if (compressed) *p |= I_COMPRESSED_BIT;
265  if (i == m) *p |= I_LAST_BIT;
266  if (i == 1) {
267  *p |= I_FIRST_BIT;
268  } else {
269  set_component_of(i);
270  }
271  }
272  void fake_root_item() {
273  set_key_len(0); // null key length
274  set_size(I2 + K1); // length of the item
275  *p |= I_FIRST_BIT|I_LAST_BIT;
276  }
277  operator const LeafItem() const { return LeafItem(p); }
278  static void setD(uint8_t * q, int c, int x) {
279  AssertRel(c, >=, DIR_START);
280  AssertRel(c, <, 65535);
281  Assert((c & 1) == 1);
282  unaligned_write2(q + c, x);
283  }
284 };
285 
286 /* A branch item has this form:
287 
288  k x
289  | |
290  tag K key X
291  ←B→ ←K→
292  <--SIZE--->
293 
294  B = BYTES_PER_BLOCK_NUMBER
295 
296  We can't omit X here, as we've nowhere to store the first and last bit
297  flags which we have in leaf items.
298 */
299 
300 // BItem_wr wants to be "BItem with non-const p and more methods" - we can't
301 // achieve that nicely with inheritance, so we use a template base class.
302 template<class T> class BItem_base {
303  protected:
304  T p;
305  int get_key_len() const { return p[BYTES_PER_BLOCK_NUMBER]; }
306  static int getD(const uint8_t * q, int c) {
307  AssertRel(c, >=, DIR_START);
308  AssertRel(c, <, 65535);
309  Assert((c & 1) == 1);
310  return unaligned_read2(q + c);
311  }
312  static int getX(const uint8_t * q, int c) { return unaligned_read2(q + c); }
313  public:
314  /* BItem from block address and offset to item pointer */
315  BItem_base(T p_, int c) : p(p_ + getD(p_, c)) { }
316  explicit BItem_base(T p_) : p(p_) { }
317  T get_address() const { return p; }
319  int size() const {
320  return get_key_len() + K1 + X2 + BYTES_PER_BLOCK_NUMBER;
321  }
322  Key key() const { return Key(p + BYTES_PER_BLOCK_NUMBER); }
327  return unaligned_read4(p);
328  }
329  int component_of() const {
330  return getX(p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1);
331  }
332 };
333 
334 class BItem : public BItem_base<const uint8_t *> {
335  public:
336  /* BItem from block address and offset to item pointer */
337  BItem(const uint8_t * p_, int c) : BItem_base<const uint8_t *>(p_, c) { }
338  explicit BItem(const uint8_t * p_) : BItem_base<const uint8_t *>(p_) { }
339 };
340 
341 class BItem_wr : public BItem_base<uint8_t *> {
342  void set_key_len(int x) {
343  AssertRel(x, >=, 0);
346  }
347  static void setX(uint8_t * q, int c, int x) { unaligned_write2(q + c, x); }
348  public:
349  /* BItem_wr from block address and offset to item pointer */
350  BItem_wr(uint8_t * p_, int c) : BItem_base<uint8_t *>(p_, c) { }
351  explicit BItem_wr(uint8_t * p_) : BItem_base<uint8_t *>(p_) { }
352  void set_component_of(int i) {
353  setX(p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1, i);
354  }
355  void set_key_and_block(Key newkey, uint4 n) {
356  int len = newkey.length() + K1 + X2;
357  // Copy the key size, main part of the key and the count part.
358  std::memcpy(p + BYTES_PER_BLOCK_NUMBER, newkey.get_address(), len);
359  // Set tag contents to block number
360  set_block_given_by(n);
361  }
362  // Takes size as we may be truncating newkey.
363  void set_truncated_key_and_block(Key newkey, int new_comp,
364  int truncate_size, uint4 n) {
365  int i = truncate_size;
366  AssertRel(i,<=,newkey.length());
367  // Key size
368  set_key_len(i);
369  // Copy the main part of the key, possibly truncating.
370  std::memcpy(p + BYTES_PER_BLOCK_NUMBER + K1, newkey.get_address() + K1, i);
371  // Set the component count.
372  setX(p, BYTES_PER_BLOCK_NUMBER + K1 + i, new_comp);
373  // Set tag contents to block number
374  set_block_given_by(n);
375  }
376 
381  unaligned_write4(p, n);
382  }
386  set_block_given_by(n);
387  set_key_len(0); /* null key */
388  set_component_of(0);
389  }
390  operator const BItem() const { return BItem(p); }
391  static void setD(uint8_t * q, int c, int x) {
392  AssertRel(c, >=, DIR_START);
393  AssertRel(c, <, 65535);
394  Assert((c & 1) == 1);
395  unaligned_write2(q + c, x);
396  }
397 };
398 
399 // Allow for BTREE_CURSOR_LEVELS levels in the B-tree.
400 // With 10, overflow is practically impossible
401 // FIXME: but we want it to be completely impossible...
402 const int BTREE_CURSOR_LEVELS = 10;
403 
404 }
405 
406 using Glass::RootInfo;
407 
408 class GlassChanges;
409 
430 class GlassTable {
431  friend class GlassCursor; /* Should probably fix this. */
432  friend class GlassFreeList;
433 
434  private:
436  GlassTable(const GlassTable &);
437 
439  GlassTable & operator=(const GlassTable &);
440 
441  void basic_open(const RootInfo * root_info,
443 
445  void do_open_to_read(const RootInfo * root_info,
447 
449  void do_open_to_write(const RootInfo * root_info,
451 
452  public:
467  GlassTable(const char * tablename_, const std::string & path_,
468  bool readonly_, bool lazy = false);
469 
470  GlassTable(const char * tablename_, int fd, off_t offset_,
471  bool readonly_, bool lazy = false);
472 
478  ~GlassTable();
479 
485  void close(bool permanent = false);
486 
487  bool readahead_key(const string &key) const;
488 
491  bool exists() const;
492 
504  void open(int flags_, const RootInfo & root_info,
506 
511  bool is_open() const { return handle >= 0; }
512 
514  bool is_writable() const { return writable; }
515 
521  void flush_db();
522 
538  void commit(glass_revision_number_t revision, RootInfo * root_info);
539 
540  bool sync() {
541  return (flags & Xapian::DB_NO_SYNC) ||
542  handle < 0 ||
543  io_sync(handle);
544  }
545 
551  void cancel(const RootInfo & root_info, glass_revision_number_t rev);
552 
567  bool get_exact_entry(const std::string & key, std::string & tag) const;
568 
580  bool key_exists(const std::string &key) const;
581 
590  bool read_tag(Glass::Cursor* C_,
591  std::string* tag,
592  bool keep_compressed) const;
593 
610  void add(const std::string& key,
611  std::string tag,
612  bool already_compressed = false);
613 
629  bool del(const std::string &key);
630 
631  int get_flags() const { return flags; }
632 
656  void create_and_open(int flags_, const RootInfo & root_info);
657 
658  void set_full_compaction(bool parity);
659 
669  return revision_number;
670  }
671 
682  return item_count;
683  }
684 
686  bool empty() const {
687  return (item_count == 0);
688  }
689 
695  GlassCursor * cursor_get() const;
696 
702  bool is_modified() const { return Btree_modified; }
703 
709  void set_max_item_size(size_t block_capacity) {
710  if (block_capacity > Glass::BLOCK_CAPACITY)
711  block_capacity = Glass::BLOCK_CAPACITY;
712  using Glass::DIR_START;
713  using Glass::D2;
714  max_item_size =
715  (block_size - DIR_START - block_capacity * D2) / block_capacity;
716  // Make sure we don't exceed the limit imposed by the format.
717  if (max_item_size > Glass::MAX_ITEM_SIZE)
718  max_item_size = Glass::MAX_ITEM_SIZE;
719  }
720 
726  void set_changes(GlassChanges * changes) {
727  changes_obj = changes;
728  }
729 
731  XAPIAN_NORETURN(static void throw_database_closed());
732 
733  string get_path() const {
734  return name + GLASS_TABLE_EXTENSION;
735  }
736 
737  protected:
738  bool find(Glass::Cursor *) const;
739  int delete_kt();
740  void read_block(uint4 n, uint8_t *p) const;
741  void write_block(uint4 n, const uint8_t *p,
742  bool appending = false) const;
743  XAPIAN_NORETURN(void set_overwritten() const);
744  void block_to_cursor(Glass::Cursor *C_, int j, uint4 n) const;
745  void alter();
746  void compact(uint8_t *p);
747  void enter_key_above_leaf(Glass::LeafItem previtem,
748  Glass::LeafItem newitem);
749  void enter_key_above_branch(int j, Glass::BItem newitem);
750  int mid_point(uint8_t *p) const;
751  void add_item_to_leaf(uint8_t *p, Glass::LeafItem kt, int c);
752  void add_item_to_branch(uint8_t *p, Glass::BItem kt, int c);
753  void add_leaf_item(Glass::LeafItem kt);
754  void add_branch_item(Glass::BItem kt, int j);
755  void delete_leaf_item(bool repeatedly);
756  void delete_branch_item(int j);
757  int add_kt(bool found);
758  void read_root();
759  void split_root(uint4 split_n);
760  void form_key(const std::string & key) const;
761 
763  const char * tablename;
764 
767 
770 
772  unsigned int block_size;
773 
775  int flags;
776 
782 
787 
795  int handle;
796 
798  int level;
799 
802 
805 
807  uint8_t * buffer;
808 
811 
816  std::string name;
817 
822 
825 
829 
832 
834  mutable bool Btree_modified;
835 
838 
840  bool writable;
841 
844 
846  unsigned long cursor_version;
847 
853 
854  bool single_file() const {
855  return name.empty();
856  }
857 
858  /* B-tree navigation functions */
859  bool prev(Glass::Cursor *C_, int j) const {
860  if (sequential && !single_file())
861  return prev_for_sequential(C_, j);
862  return prev_default(C_, j);
863  }
864 
865  bool next(Glass::Cursor *C_, int j) const {
866  if (sequential) return next_for_sequential(C_, j);
867  return next_default(C_, j);
868  }
869 
870  /* Default implementations. */
871  bool prev_default(Glass::Cursor *C_, int j) const;
872  bool next_default(Glass::Cursor *C_, int j) const;
873 
874  /* Implementations for sequential mode. */
875  bool prev_for_sequential(Glass::Cursor *C_, int dummy) const;
876  bool next_for_sequential(Glass::Cursor *C_, int dummy) const;
877 
878  static int find_in_leaf(const uint8_t * p,
879  Glass::LeafItem item, int c, bool& exact);
880  static int find_in_branch(const uint8_t * p,
881  Glass::LeafItem item, int c);
882  static int find_in_branch(const uint8_t * p, Glass::BItem item, int c);
883 
887  static uint4 block_given_by(const uint8_t * p, int c);
888 
890 
896  uint8_t * split_p;
897 
900 
902 
904  bool lazy;
905 
908 
910  off_t offset;
911 
912  /* Debugging methods */
913 // void report_block_full(int m, int n, const uint8_t * p);
914 };
915 
916 namespace Glass {
917 
934 template<typename ITEM1, typename ITEM2>
935 int compare(ITEM1 a, ITEM2 b)
936 {
937  Key key1 = a.key();
938  Key key2 = b.key();
939  const uint8_t* p1 = key1.data();
940  const uint8_t* p2 = key2.data();
941  int key1_len = key1.length();
942  int key2_len = key2.length();
943  int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
944 
945  // Compare the common part of the keys.
946  int diff = std::memcmp(p1, p2, k_smaller);
947  if (diff == 0) {
948  // If the common part matches, compare the lengths.
949  diff = key1_len - key2_len;
950  if (diff == 0) {
951  // If the strings match, compare component_of().
952  diff = a.component_of() - b.component_of();
953  }
954  }
955  return diff;
956 }
957 
963 inline int
965 {
966  Key key1 = a.key();
967  Key key2 = b.key();
968  const uint8_t* p1 = key1.data();
969  const uint8_t* p2 = key2.data();
970  int key1_len = key1.length();
971  int key2_len = key2.length();
972  if (key1_len == key2_len) {
973  // The keys are the same length, so we can compare the counts in the
974  // same operation since they're stored as 2 byte bigendian numbers.
975  int len = key1_len + X2;
976  return std::memcmp(p1, p2, len);
977  }
978 
979  int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
980 
981  // Compare the common part of the keys.
982  int diff = std::memcmp(p1, p2, k_smaller);
983  if (diff == 0) {
984  // If the common part matches, compare the lengths.
985  diff = key1_len - key2_len;
986  // We dealt with the "same length" case above so we never need to check
987  // component_of here.
988  }
989  return diff;
990 }
991 
992 }
993 
994 #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:214
Define the XAPIAN_NORETURN macro.
static void setD(uint8_t *q, int c, int x)
Definition: glass_table.h:391
int component_of() const
Definition: glass_table.h:184
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:668
off_t offset
offset to start of table in file.
Definition: glass_table.h:910
Glass::LeafItem_wr kt
buffer of size block_size for making up key-tag items
Definition: glass_table.h:804
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:182
int TOTAL_FREE(const uint8_t *b)
Definition: glass_table.h:113
void set_key_len(int x)
Definition: glass_table.h:219
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:686
int changed_c
directory offset corresponding to last block to be changed by an addition
Definition: glass_table.h:828
int component_of() const
Definition: glass_table.h:329
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:430
uint4 REVISION(const uint8_t *b)
Definition: glass_table.h:110
static int getX(const uint8_t *q, int c)
Definition: glass_table.h:312
uint4 glass_revision_number_t
The revision number of a glass database.
Definition: glass_defs.h:61
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:896
unsigned long cursor_version
Version count for tracking when cursors need to rebuild.
Definition: glass_table.h:846
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:380
Constants in the Xapian namespace.
bool writable
Set to true when the database is opened to write.
Definition: glass_table.h:840
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:363
Definitions, types, etc for use inside glass.
Convert types to std::string.
int handle
File descriptor of the table.
Definition: glass_table.h:795
void set_key_and_block(Key newkey, uint4 n)
Definition: glass_table.h:355
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:338
static void throw_database_closed()
bool lazy
If true, don&#39;t create the table until it&#39;s needed.
Definition: glass_table.h:904
void set_component_of(int i)
Definition: glass_table.h:230
BItem(const uint8_t *p_, int c)
Definition: glass_table.h:337
string get_path() const
Definition: glass_table.h:733
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:543
int flags
Flags like DB_NO_SYNC and DB_DANGEROUS.
Definition: glass_table.h:775
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:837
unsigned long long glass_tablesize_t
How many entries there are in a table.
Definition: glass_defs.h:64
static int getD(const uint8_t *q, int c)
Definition: glass_table.h:306
int size() const
SIZE in diagram above.
Definition: glass_table.h:178
#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:824
bool next(Glass::Cursor *C_, int j) const
Definition: glass_table.h:865
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:235
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:935
Hierarchy of classes which Xapian can throw as exceptions.
BItem_wr(uint8_t *p_, int c)
Definition: glass_table.h:350
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:229
const char * tablename
The name of the table (used when writing changesets).
Definition: glass_table.h:763
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:769
bool sync()
Definition: glass_table.h:540
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:225
Glass freelist.
bool is_modified() const
Determine whether the object contains uncommitted modifications.
Definition: glass_table.h:702
const uint8_t * get_address() const
Definition: glass_table.h:144
bool decompress_chunk(CompressionStream &comp_stream, string &tag) const
Definition: glass_table.h:198
GlassChanges * changes_obj
The GlassChanges object to write block changes to.
Definition: glass_table.h:852
uint4 last_readahead
Last block readahead_key() preread.
Definition: glass_table.h:907
void form_key(const std::string &key_)
Definition: glass_table.h:243
int length() const
Definition: glass_table.h:149
bool single_file() const
Definition: glass_table.h:854
void setI(int x)
Definition: glass_table.h:224
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:351
uint32_t aligned_read4(const unsigned char *ptr)
Definition: wordaccess.h:145
int get_flags() const
Definition: glass_table.h:631
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:212
void SET_LEVEL(uint8_t *b, int x)
Definition: glass_table.h:118
bool get_compressed() const
Definition: glass_table.h:181
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:261
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:183
const int ITEM_SIZE_MASK
Definition: glass_table.h:132
CompressionStream comp_stream
Definition: glass_table.h:901
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:352
void set_max_item_size(size_t block_capacity)
Set the maximum item size given the block capacity.
Definition: glass_table.h:709
int seq_count
count of the number of successive instances of purely sequential addition, starting at SEQ_START_POIN...
Definition: glass_table.h:821
bool is_open() const
Return true if this table is open.
Definition: glass_table.h:511
LeafItem_wr(uint8_t *p_, int c)
Definition: glass_table.h:228
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:726
const int DIR_START
Definition: glass_table.h:115
int size() const
SIZE in diagram above.
Definition: glass_table.h:319
std::string name
The path name of the B tree.
Definition: glass_table.h:816
static void setD(uint8_t *q, int c, int x)
Definition: glass_table.h:278
bool Btree_modified
Set to true the first time the B-tree is modified.
Definition: glass_table.h:834
unsigned int block_size
block size of the B tree in bytes
Definition: glass_table.h:772
const uint8_t * data() const
Definition: glass_table.h:145
Key key() const
Definition: glass_table.h:322
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:807
glass_tablesize_t get_entry_count() const
Return a count of the number of entries in the table.
Definition: glass_table.h:681
void append_chunk(std::string *tag) const
Definition: glass_table.h:189
Interface to Btree cursors.
static void setX(uint8_t *q, int c, int x)
Definition: glass_table.h:347
bool faked_root_block
true if the root block is faked (not written to disk).
Definition: glass_table.h:781
size_t max_item_size
maximum size of an item (key-tag pair)
Definition: glass_table.h:831
bool prev(Glass::Cursor *C_, int j) const
Definition: glass_table.h:859
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:342
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:810
uint4 compress_min
Minimum size tag to try compressing (0 for no compression).
Definition: glass_table.h:899
const int BTREE_CURSOR_LEVELS
Definition: glass_table.h:402
Definition: header.h:151
BItem_base(T p_, int c)
Definition: glass_table.h:315
const int BYTES_PER_BLOCK_NUMBER
Definition: glass_table.h:60
T get_address() const
Definition: glass_table.h:317
Various assertion macros.
glass_revision_number_t revision_number
revision number of the opened B-tree.
Definition: glass_table.h:766
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:801
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:385
int level
number of levels, counting from 0
Definition: glass_table.h:798
bool sequential
true iff the data has been written in a single write in sequential order.
Definition: glass_table.h:786
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:843
bool is_writable() const
Return true if this table is writable.
Definition: glass_table.h:514
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:326
#define C(X)
int get_key_len() const
Definition: glass_table.h:305
uint32_t unaligned_read4(const unsigned char *ptr)
Definition: wordaccess.h:151