24 #ifndef OM_HGUARD_GLASS_TABLE_H 25 #define OM_HGUARD_GLASS_TABLE_H 57 #define GLASS_BTREE_MAX_KEY_LEN 255 111 inline int GET_LEVEL(
const uint8_t * b) {
return b[4]; }
143 explicit Key(
const uint8_t * p_) : p(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());
164 static int getD(
const uint8_t * q,
int c) {
179 return (getI() & ITEM_SIZE_MASK) + 3;
185 if (first_component())
return 1;
186 return getX(p, get_key_len() + I2 + K1);
191 int cd = get_key_len() + I2 +
K1;
192 if (!first_component()) cd +=
X2;
195 const char * chunk =
reinterpret_cast<const char *
>(p + cd);
196 tag->append(chunk, l);
200 int cd = get_key_len() + I2 +
K1;
201 if (!first_component()) cd +=
X2;
204 const char * chunk =
reinterpret_cast<const char *
>(p + cd);
233 setX(
p, get_key_len() + I2 + K1, i);
237 int I = new_size - 3;
244 std::string::size_type key_len = key_.length();
249 std::string msg(
"Key too long: length was ");
251 msg +=
" bytes, maximum length of a key is " 256 set_key_len(key_len);
257 std::memmove(
p + I2 + K1, key_.data(), key_len);
261 void set_tag(
int cd,
const char *start,
int len,
bool compressed,
int i,
int m) {
262 std::memmove(
p + cd, start, len);
278 static void setD(uint8_t * q,
int c,
int x) {
306 static int getD(
const uint8_t * q,
int c) {
322 Key key()
const {
return Key(p + BYTES_PER_BLOCK_NUMBER); }
330 return getX(p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1);
353 setX(
p, get_key_len() + BYTES_PER_BLOCK_NUMBER + K1, i);
356 int len = newkey.
length() + K1 +
X2;
358 std::memcpy(
p + BYTES_PER_BLOCK_NUMBER, newkey.
get_address(), len);
360 set_block_given_by(n);
364 int truncate_size,
uint4 n) {
365 int i = truncate_size;
370 std::memcpy(
p + BYTES_PER_BLOCK_NUMBER + K1, newkey.
get_address() +
K1, i);
372 setX(
p, BYTES_PER_BLOCK_NUMBER + K1 + i, new_comp);
374 set_block_given_by(n);
386 set_block_given_by(n);
391 static void setD(uint8_t * q,
int c,
int x) {
436 void basic_open(
const RootInfo * root_info,
440 void do_open_to_read(
const RootInfo * root_info,
444 void do_open_to_write(
const RootInfo * root_info,
462 GlassTable(
const char * tablename_,
const std::string & path_,
463 bool readonly_,
bool lazy =
false);
465 GlassTable(
const char * tablename_,
int fd, off_t offset_,
466 bool readonly_,
bool lazy =
false);
480 void close(
bool permanent =
false);
482 bool readahead_key(
const string &key)
const;
562 bool get_exact_entry(
const std::string & key, std::string & tag)
const;
575 bool key_exists(
const std::string &key)
const;
587 bool keep_compressed)
const;
605 void add(
const std::string& key,
606 const std::string& tag,
607 bool already_compressed =
false);
624 bool del(
const std::string &key);
651 void create_and_open(
int flags_,
const RootInfo & root_info);
653 void set_full_compaction(
bool parity);
664 return revision_number;
682 return (item_count == 0);
710 (block_size -
DIR_START - block_capacity *
D2) / block_capacity;
722 changes_obj = changes;
737 bool appending =
false)
const;
738 XAPIAN_NORETURN(
void set_overwritten()
const);
741 void compact(uint8_t *p);
744 void enter_key_above_branch(
int j,
Glass::BItem newitem);
745 int mid_point(uint8_t *p)
const;
747 void add_item_to_branch(uint8_t *p,
Glass::BItem kt,
int c);
750 void delete_leaf_item(
bool repeatedly);
751 void delete_branch_item(
int j);
752 int add_kt(
bool found);
754 void split_root(
uint4 split_n);
755 void form_key(
const std::string & key)
const;
855 if (sequential && !single_file())
856 return prev_for_sequential(C_, j);
857 return prev_default(C_, j);
861 if (sequential)
return next_for_sequential(C_, j);
862 return next_default(C_, j);
871 bool next_for_sequential(
Glass::Cursor *C_,
int dummy)
const;
873 static int find_in_leaf(
const uint8_t * p,
875 static int find_in_branch(
const uint8_t * p,
877 static int find_in_branch(
const uint8_t * p,
Glass::BItem item,
int c);
882 static uint4 block_given_by(
const uint8_t * p,
int c);
929 template<
typename ITEM1,
typename ITEM2>
934 const uint8_t* p1 = key1.
data();
935 const uint8_t* p2 = key2.
data();
936 int key1_len = key1.
length();
937 int key2_len = key2.
length();
938 int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
941 int diff = std::memcmp(p1, p2, k_smaller);
944 diff = key1_len - key2_len;
947 diff = a.component_of() - b.component_of();
963 const uint8_t* p1 = key1.
data();
964 const uint8_t* p2 = key2.
data();
965 int key1_len = key1.
length();
966 int key2_len = key2.
length();
967 if (key1_len == key2_len) {
970 int len = key1_len +
X2;
971 return std::memcmp(p1, p2, len);
974 int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
977 int diff = std::memcmp(p1, p2, k_smaller);
980 diff = key1_len - key2_len;
LeafItem(const uint8_t *p_)
Define the XAPIAN_NORETURN macro.
static void setD(uint8_t *q, int c, int x)
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.
off_t offset
offset to start of table in file.
Glass::LeafItem_wr kt
buffer of size block_size for making up key-tag items
XAPIAN_REVISION_TYPE rev
Revision number of a database.
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...
void commit(const GlassTable *B, uint4 block_size)
#define AssertRel(A, REL, B)
void unaligned_write4(unsigned char *ptr, T value)
#define GLASS_BTREE_MAX_KEY_LEN
The largest possible value of a key_len.
bool first_component() const
int TOTAL_FREE(const uint8_t *b)
bool empty() const
Return true if there are no entries in the table.
int changed_c
directory offset corresponding to last block to be changed by an addition
uint16_t unaligned_read2(const unsigned char *ptr)
Class managing a Btree table in a Glass database.
uint4 REVISION(const uint8_t *b)
static int getX(const uint8_t *q, int c)
uint4 glass_revision_number_t
The revision number of a glass database.
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
uint8_t * split_p
Buffer used when splitting a block.
unsigned long cursor_version
Version count for tracking when cursors need to rebuild.
void set_block_given_by(uint4 n)
Set this item's tag to point to block n (this block should not be at level 0).
Constants in the Xapian namespace.
bool writable
Set to true when the database is opened to write.
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
#define STRINGIZE(X)
The STRINGIZE macro converts its parameter into a string constant.
void set_truncated_key_and_block(Key newkey, int new_comp, int truncate_size, uint4 n)
Definitions, types, etc for use inside glass.
Convert types to std::string.
int handle
File descriptor of the table.
void set_key_and_block(Key newkey, uint4 n)
int revision()
Report the revision of the library which the program is linked with.
static void throw_database_closed()
bool lazy
If true, don't create the table until it's needed.
void set_component_of(int i)
BItem(const uint8_t *p_, int c)
void SET_MAX_FREE(uint8_t *b, int x)
const size_t MAX_ITEM_SIZE
int flags
Flags like DB_NO_SYNC and DB_DANGEROUS.
static int getX(const uint8_t *q, int c)
bool full_compaction
set to true when full compaction is to be achieved
unsigned long long glass_tablesize_t
How many entries there are in a table.
static int getD(const uint8_t *q, int c)
int size() const
SIZE in diagram above.
#define GLASS_TABLE_EXTENSION
Glass table extension.
uint4 changed_n
the last block to be changed by an addition
bool next(Glass::Cursor *C_, int j) const
void aligned_write4(unsigned char *ptr, T value)
void set_size(int new_size)
int MAX_FREE(const uint8_t *b)
int compare(ITEM1 a, ITEM2 b)
Compare two items by their keys.
Hierarchy of classes which Xapian can throw as exceptions.
BItem_wr(uint8_t *p_, int c)
class wrapper around zlib
void operator=(const GlassFreeList &)
InvalidArgumentError indicates an invalid parameter value was passed to the API.
void read(std::string *key) const
const char * tablename
The name of the table (used when writing changesets).
glass_tablesize_t item_count
keeps a count of the number of items in the B-tree.
functions for reading and writing different width words
int GET_LEVEL(const uint8_t *b)
static void setX(uint8_t *q, int c, int x)
bool is_modified() const
Determine whether the object contains uncommitted modifications.
const uint8_t * get_address() const
bool decompress_chunk(CompressionStream &comp_stream, string &tag) const
GlassChanges * changes_obj
The GlassChanges object to write block changes to.
uint4 last_readahead
Last block readahead_key() preread.
void form_key(const std::string &key_)
bool decompress_chunk(const char *p, int len, std::string &buf)
Returns true if this was the final chunk.
uint32_t aligned_read4(const unsigned char *ptr)
string str(int value)
Convert int to std::string.
LeafItem(const uint8_t *p_, int c)
void SET_LEVEL(uint8_t *b, int x)
bool get_compressed() const
void set_tag(int cd, const char *start, int len, bool compressed, int i, int m)
void read_block(const GlassTable *B, uint4 n, uint8_t *p)
static int getD(const uint8_t *q, int c)
bool last_component() const
CompressionStream comp_stream
char operator[](size_t i) const
int DIR_END(const uint8_t *b)
LeafItem_base(T p_, int c)
void set_component_of(int i)
void set_max_item_size(size_t block_capacity)
Set the maximum item size given the block capacity.
int seq_count
count of the number of successive instances of purely sequential addition, starting at SEQ_START_POIN...
bool is_open() const
Return true if this table is open.
LeafItem_wr(uint8_t *p_, int c)
A cursor pointing to a position in a Btree table, for reading several entries in order, or finding approximate matches.
const int DB_NO_SYNC
Don't attempt to ensure changes have hit disk.
void set_changes(GlassChanges *changes)
Set the GlassChanges object to write changed blocks to.
#define GLASS_BTREE_CURSOR_LEVELS
Allow for this many levels in the B-tree.
int size() const
SIZE in diagram above.
std::string name
The path name of the B tree.
static void setD(uint8_t *q, int c, int x)
bool Btree_modified
Set to true the first time the B-tree is modified.
unsigned int block_size
block size of the B tree in bytes
const uint8_t * data() const
const int LEVEL_FREELIST
Freelist blocks have their level set to LEVEL_FREELIST.
void unaligned_write2(unsigned char *ptr, T value)
uint8_t * buffer
buffer of size block_size for reforming blocks
glass_tablesize_t get_entry_count() const
Return a count of the number of entries in the table.
void append_chunk(std::string *tag) const
Interface to Btree cursors.
static void setX(uint8_t *q, int c, int x)
bool faked_root_block
true if the root block is faked (not written to disk).
size_t max_item_size
maximum size of an item (key-tag pair)
bool prev(Glass::Cursor *C_, int j) const
Wrappers for low-level POSIX I/O routines.
void SET_DIR_END(uint8_t *b, int x)
Various handy helpers which std::string really should provide.
void SET_REVISION(uint8_t *b, uint4 rev)
GlassFreeList free_list
List of free blocks.
uint4 compress_min
Minimum size tag to try compressing (0 for no compression).
const int BYTES_PER_BLOCK_NUMBER
Various assertion macros.
glass_revision_number_t revision_number
revision number of the opened B-tree.
DatabaseError indicates some sort of database related error.
const int I_COMPRESSED_BIT
uint4 root
the root block of the B-tree
void form_null_key(uint4 n)
Form an item with a null key and with block number n in the tag.
int level
number of levels, counting from 0
bool sequential
true iff the data has been written in a single write in sequential order.
void SET_TOTAL_FREE(uint8_t *b, int x)
bool cursor_created_since_last_modification
Flag for tracking when cursors need to rebuild.
bool is_writable() const
Return true if this table is writable.
uint4 block_given_by() const
Get this item's tag as a block number (this block should not be at level 0).
uint32_t unaligned_read4(const unsigned char *ptr)