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) {
199 const char * chunk =
reinterpret_cast<const char *
>(
p + cd);
200 tag->append(chunk, l);
208 const char * chunk =
reinterpret_cast<const char *
>(
p + cd);
241 int I = new_size - 3;
248 std::string::size_type key_len = key_.length();
253 std::string msg(
"Key too long: length was ");
255 msg +=
" bytes, maximum length of a key is "
261 std::memmove(
p +
I2 +
K1, key_.data(), key_len);
265 void set_tag(
int cd,
const char *start,
int len,
bool compressed,
int i,
int m) {
266 std::memmove(
p + cd, start, len);
282 static void setD(uint8_t * q,
int c,
int x) {
310 static int getD(
const uint8_t * q,
int c) {
368 int truncate_size,
uint4 n) {
369 int i = truncate_size;
395 static void setD(uint8_t * q,
int c,
int x) {
466 GlassTable(
const char * tablename_,
const std::string & path_,
467 bool readonly_,
bool lazy =
false);
469 GlassTable(
const char * tablename_,
int fd, off_t offset_,
470 bool readonly_,
bool lazy =
false);
484 void close(
bool permanent =
false);
566 bool get_exact_entry(
const std::string & key, std::string & tag)
const;
579 bool key_exists(
const std::string &key)
const;
591 bool keep_compressed)
const;
609 void add(
const std::string& key,
610 const std::string& tag,
611 bool already_compressed =
false);
628 bool del(
const std::string &key);
741 bool appending =
false)
const;
759 void form_key(
const std::string & key)
const;
933 template<
typename ITEM1,
typename ITEM2>
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);
945 int diff = std::memcmp(p1, p2, k_smaller);
948 diff = key1_len - key2_len;
951 diff = a.component_of() - b.component_of();
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) {
974 int len = key1_len +
X2;
975 return std::memcmp(p1, p2, len);
978 int k_smaller = (key2_len < key1_len ? key2_len : key1_len);
981 int diff = std::memcmp(p1, p2, k_smaller);
984 diff = key1_len - key2_len;
bool decompress_chunk(const char *p, int len, std::string &buf)
Returns true if this was the final chunk.
A cursor pointing to a position in a Btree table, for reading several entries in order,...
uint8_t * p
Current freelist block.
Class managing a Btree table in a Glass database.
bool readahead_key(const string &key) const
void block_to_cursor(Glass::Cursor *C_, int j, uint4 n) const
void add(const std::string &key, const std::string &tag, bool already_compressed=false)
Add a key/tag pair to the table, replacing any existing pair with the same key.
bool Btree_modified
Set to true the first time the B-tree is modified.
uint4 changed_n
the last block to be changed by an addition
void alter()
Btree::alter(); is called when the B-tree is to be altered.
bool next_for_sequential(Glass::Cursor *C_, int dummy) const
~GlassTable()
Close the Btree.
void compact(uint8_t *p)
compact(p) compact the block at p by shuffling all the items up to the end.
GlassFreeList free_list
List of free blocks.
int seq_count
count of the number of successive instances of purely sequential addition, starting at SEQ_START_POIN...
void create_and_open(int flags_, const RootInfo &root_info)
Create a new empty btree structure on disk and open it at the initial revision.
uint8_t * buffer
buffer of size block_size for reforming blocks
CompressionStream comp_stream
bool next(Glass::Cursor *C_, int j) const
void basic_open(const RootInfo *root_info, glass_revision_number_t rev)
glass_tablesize_t item_count
keeps a count of the number of items in the B-tree.
void delete_branch_item(int j)
GlassTable::delete_branch_item(j, repeatedly) is (almost) the converse of add_branch_item.
bool faked_root_block
true if the root block is faked (not written to disk).
void commit(glass_revision_number_t revision, RootInfo *root_info)
Commit any outstanding changes to the table.
int changed_c
directory offset corresponding to last block to be changed by an addition
bool next_default(Glass::Cursor *C_, int j) const
uint4 root
the root block of the B-tree
bool del(const std::string &key)
Delete an entry from the table.
uint4 last_readahead
Last block readahead_key() preread.
void split_root(uint4 split_n)
Btree needs to gain a new level to insert more items: so split root block and construct a new one.
uint8_t * split_p
Buffer used when splitting a block.
int add_kt(bool found)
add_kt(found) adds the item (key-tag pair) at B->kt into the B-tree, using cursor C.
void do_open_to_read(const RootInfo *root_info, glass_revision_number_t rev)
Perform the opening operation to read.
int level
number of levels, counting from 0
bool exists() const
Determine whether the btree exists on disk.
GlassTable & operator=(const GlassTable &)
Assignment not allowed.
void set_overwritten() const
void enter_key_above_branch(int j, Glass::BItem newitem)
enter_key_above_branch(j, newkey) is called after a branch block split.
bool is_open() const
Return true if this table is open.
void flush_db()
Flush any outstanding changes to the DB file of the table.
bool prev_default(Glass::Cursor *C_, int j) const
bool empty() const
Return true if there are no entries in the table.
const char * tablename
The name of the table (used when writing changesets).
bool writable
Set to true when the database is opened to write.
void open(int flags_, const RootInfo &root_info, glass_revision_number_t rev)
Open the btree.
GlassTable(const GlassTable &)
Copying not allowed.
void enter_key_above_leaf(Glass::LeafItem previtem, Glass::LeafItem newitem)
enter_key_above_leaf(previtem, newitem) is called after a leaf block split.
bool find(Glass::Cursor *) const
find(C_) searches for the key of B->kt in the B-tree.
bool prev(Glass::Cursor *C_, int j) const
bool read_tag(Glass::Cursor *C_, std::string *tag, bool keep_compressed) const
Read the tag value for the key pointed to by cursor C_.
bool key_exists(const std::string &key) const
Check if a key exists in the Btree.
bool is_modified() const
Determine whether the object contains uncommitted modifications.
void write_block(uint4 n, const uint8_t *p, bool appending=false) const
write_block(n, p, appending) writes block n in the DB file from address p.
int mid_point(uint8_t *p) const
mid_point(p) finds the directory entry in c that determines the approximate mid point of the data in ...
void add_leaf_item(Glass::LeafItem kt)
GlassTable::add_leaf_item(kt_) adds item kt_ to the leaf block.
void set_changes(GlassChanges *changes)
Set the GlassChanges object to write changed blocks to.
void read_block(uint4 n, uint8_t *p) const
read_block(n, p) reads block n of the DB file to address p.
unsigned int block_size
block size of the B tree in bytes
GlassCursor * cursor_get() const
Get a cursor for reading from the table.
bool cursor_created_since_last_modification
Flag for tracking when cursors need to rebuild.
void set_full_compaction(bool parity)
size_t max_item_size
maximum size of an item (key-tag pair)
unsigned long cursor_version
Version count for tracking when cursors need to rebuild.
void form_key(const std::string &key) const
glass_tablesize_t get_entry_count() const
Return a count of the number of entries in the table.
GlassChanges * changes_obj
The GlassChanges object to write block changes to.
void add_item_to_branch(uint8_t *p, Glass::BItem kt, int c)
add_item_to_branch(p, kt_, c) adds item kt_ to the branch block at p.
std::string name
The path name of the B tree.
bool lazy
If true, don't create the table until it's needed.
void add_branch_item(Glass::BItem kt, int j)
GlassTable::add_item(kt_, j) adds item kt_ to the block at cursor level C[j].
bool full_compaction
set to true when full compaction is to be achieved
static uint4 block_given_by(const uint8_t *p, int c)
block_given_by(p, c) finds the item at block address p, directory offset c, and returns its tag value...
static int find_in_branch(const uint8_t *p, Glass::LeafItem item, int c)
void close(bool permanent=false)
Close the Btree.
void delete_leaf_item(bool repeatedly)
GlassTable::delete_leaf_item(repeatedly) is (almost) the converse of add_leaf_item.
Glass::Cursor C[GLASS_BTREE_CURSOR_LEVELS]
int handle
File descriptor of the table.
void cancel(const RootInfo &root_info, glass_revision_number_t rev)
Cancel any outstanding changes.
Glass::LeafItem_wr kt
buffer of size block_size for making up key-tag items
bool is_writable() const
Return true if this table is writable.
bool prev_for_sequential(Glass::Cursor *C_, int dummy) const
void add_item_to_leaf(uint8_t *p, Glass::LeafItem kt, int c)
add_item_to_leaf(p, kt_, c) adds item kt_ to the leaf block at p.
void do_open_to_write(const RootInfo *root_info, glass_revision_number_t rev=0)
Perform the opening operation to write.
static void throw_database_closed()
Throw an exception indicating that the database is closed.
uint4 compress_min
Minimum size tag to try compressing (0 for no compression).
bool get_exact_entry(const std::string &key, std::string &tag) const
Read an entry from the table, if and only if it is exactly that being asked for.
bool sequential
true iff the data has been written in a single write in sequential order.
int flags
Flags like DB_NO_SYNC and DB_DANGEROUS.
off_t offset
offset to start of table in file.
static int find_in_leaf(const uint8_t *p, Glass::LeafItem item, int c, bool &exact)
find_in_leaf(p, key, c, exact) searches for the key in the leaf block at p.
glass_revision_number_t revision_number
revision number of the opened B-tree.
glass_revision_number_t get_open_revision_number() const
Get the revision number at which this table is currently open.
void set_max_item_size(size_t block_capacity)
Set the maximum item size given the block capacity.
uint4 block_given_by() const
Get this item's tag as a block number (this block should not be at level 0).
static int getX(const uint8_t *q, int c)
static int getD(const uint8_t *q, int c)
int size() const
SIZE in diagram above.
void set_component_of(int i)
void set_truncated_key_and_block(Key newkey, int new_comp, int truncate_size, uint4 n)
BItem_wr(uint8_t *p_, int c)
static void setX(uint8_t *q, int c, int x)
void set_key_and_block(Key newkey, uint4 n)
void form_null_key(uint4 n)
Form an item with a null key and with block number n in the tag.
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).
static void setD(uint8_t *q, int c, int x)
BItem(const uint8_t *p_, int c)
char operator[](size_t i) const
const uint8_t * get_address() const
const uint8_t * data() const
void read(std::string *key) const
int size() const
SIZE in diagram above.
bool first_component() const
bool last_component() const
LeafItem_base(T p_, int c)
void append_chunk(std::string *tag) const
static int getD(const uint8_t *q, int c)
bool get_compressed() const
bool decompress_chunk(CompressionStream &comp_stream, string &tag) const
static int getX(const uint8_t *q, int c)
void form_key(const std::string &key_)
LeafItem_wr(uint8_t *p_, int c)
static void setX(uint8_t *q, int c, int x)
void set_tag(int cd, const char *start, int len, bool compressed, int i, int m)
void set_size(int new_size)
void set_component_of(int i)
static void setD(uint8_t *q, int c, int x)
LeafItem(const uint8_t *p_)
LeafItem(const uint8_t *p_, int c)
DatabaseError indicates some sort of database related error.
InvalidArgumentError indicates an invalid parameter value was passed to the API.
class wrapper around zlib
Constants in the Xapian namespace.
Hierarchy of classes which Xapian can throw as exceptions.
Interface to Btree cursors.
Definitions, types, etc for use inside glass.
#define GLASS_BTREE_CURSOR_LEVELS
Allow for this many levels in the B-tree.
unsigned long long glass_tablesize_t
How many entries there are in a table.
uint4 glass_revision_number_t
The revision number of a glass database.
#define GLASS_TABLE_EXTENSION
Glass table extension.
#define GLASS_BTREE_MAX_KEY_LEN
The largest possible value of a key_len.
Wrappers for low-level POSIX I/O routines.
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
int DIR_END(const uint8_t *b)
const int LEVEL_FREELIST
Freelist blocks have their level set to LEVEL_FREELIST.
void SET_DIR_END(uint8_t *b, int x)
int compare(ITEM1 a, ITEM2 b)
Compare two items by their keys.
int TOTAL_FREE(const uint8_t *b)
void SET_LEVEL(uint8_t *b, int x)
int GET_LEVEL(const uint8_t *b)
void SET_REVISION(uint8_t *b, uint4 rev)
const size_t MAX_ITEM_SIZE
int MAX_FREE(const uint8_t *b)
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.
const int BYTES_PER_BLOCK_NUMBER
uint4 REVISION(const uint8_t *b)
void SET_TOTAL_FREE(uint8_t *b, int x)
const int I_COMPRESSED_BIT
void SET_MAX_FREE(uint8_t *b, int x)
string str(int value)
Convert int to std::string.
int revision()
Report the revision of the library which the program is linked with.
XAPIAN_REVISION_TYPE rev
Revision number of a database.
const int DB_NO_SYNC
Don't attempt to ensure changes have hit disk.
Define the XAPIAN_NORETURN macro.
Various assertion macros.
#define AssertRel(A, REL, B)
Convert types to std::string.
Various handy helpers which std::string really should provide.
#define STRINGIZE(X)
The STRINGIZE macro converts its parameter into a string constant.
functions for reading and writing different width words
void aligned_write4(unsigned char *ptr, T value)
uint32_t unaligned_read4(const unsigned char *ptr)
void unaligned_write2(unsigned char *ptr, T value)
uint16_t unaligned_read2(const unsigned char *ptr)
void unaligned_write4(unsigned char *ptr, T value)
uint32_t aligned_read4(const unsigned char *ptr)