34 using namespace Glass;
39 #ifdef GLASS_FREELIST_SIZE
40 # define FREELIST_END_ \
41 (8 + (GLASS_FREELIST_SIZE < 3 ? 3 : GLASS_FREELIST_SIZE) * 4)
42 # define FREELIST_END (FREELIST_END_ < 2048 ? FREELIST_END_ : 2048)
44 # define FREELIST_END block_size
61 B->read_block(n, ptr);
73 B->write_block(n, ptr, flw_appending);
81 return first_unused_block++;
89 p =
new uint8_t[block_size];
90 read_block(
B, fl.n,
p);
107 uint4 old_fl_blk = fl.n;
115 read_block(
B, fl.n,
p);
123 *blk_to_free = old_fl_blk;
125 mark_block_unused(
B, block_size, old_fl_blk);
128 return get_block(
B, block_size);
143 p =
new uint8_t[block_size];
144 read_block(
B, fl.n,
p);
167 read_block(
B, fl.n,
p);
175 return walk(
B, block_size, inclusive);
189 pw =
new uint8_t[block_size];
191 read_block(
B, flw.n, pw);
192 flw_appending =
true;
196 uint4 n = get_block(
B, block_size, &blk_to_free);
202 flw_appending = (n == first_unused_block - 1);
207 uint4 n = get_block(
B, block_size, &blk_to_free);
209 #ifdef GLASS_FREELIST_SIZE
215 if (
p && flw.n == fl.n) {
217 memcpy(
p, pw, block_size);
222 flw_appending = (n == first_unused_block - 1);
230 mark_block_unused(
B, block_size, blk_to_free);
236 if (pw && flw.c != 0) {
238 #ifdef GLASS_FREELIST_SIZE
244 if (
p && flw.n == fl.n) {
246 memcpy(
p, pw, block_size);
249 flw_appending =
true;
256 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
259 bitmap_size = (first_unused + BITS_PER_ELT - 1) / BITS_PER_ELT;
261 std::fill_n(bitmap, bitmap_size - 1, ALL_BITS);
264 uint4 remainder = first_unused & (BITS_PER_ELT - 1);
266 bitmap[bitmap_size - 1] = (
static_cast<elt_type>(1) << remainder) - 1;
268 bitmap[bitmap_size - 1] = ALL_BITS;
274 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
276 for (
uint4 i = 0; i < bitmap_size; ++i) {
280 if (p_first_bad_blk) {
281 uint4 first_bad_blk = i * BITS_PER_ELT;
283 #if HAVE_DECL___BUILTIN_CTZ
284 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned)) {
285 first_bad_blk += __builtin_ctz(elt);
287 #if HAVE_DECL___BUILTIN_CTZL
288 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned long)) {
289 first_bad_blk += __builtin_ctzl(elt);
291 #if HAVE_DECL___BUILTIN_CTZLL
292 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned long long)) {
293 first_bad_blk += __builtin_ctzll(elt);
296 for (
elt_type mask = 1; (elt & mask) == 0; mask <<= 1) {
300 *p_first_bad_blk = first_bad_blk;
301 p_first_bad_blk =
nullptr;
GlassFreeListChecker(const GlassFreeListChecker &)
uint4 count_set_bits(uint4 *p_first_bad_blk) const
Count how many bits are still set.
void write_block(const GlassTable *B, uint4 n, uint8_t *p, uint4 rev)
uint4 get_first_unused_block() const
void mark_block_unused(const GlassTable *B, uint4 block_size, uint4 n)
uint4 walk(const GlassTable *B, uint4 block_size, bool inclusive)
void commit(const GlassTable *B, uint4 block_size)
void read_block(const GlassTable *B, uint4 n, uint8_t *p)
uint4 get_block(const GlassTable *B, uint4 block_size, uint4 *blk_to_free=NULL)
Class managing a Btree table in a Glass database.
DatabaseCorruptError indicates database corruption was detected.
Hierarchy of classes which Xapian can throw as exceptions.
const uint4 UNUSED
Invalid freelist block value, so we can detect overreading bugs, etc.
const unsigned C_BASE
The first offset to use for storing free block info.
const int LEVEL_FREELIST
Freelist blocks have their level set to LEVEL_FREELIST.
void SET_LEVEL(uint8_t *b, int x)
int GET_LEVEL(const uint8_t *b)
void SET_REVISION(uint8_t *b, uint4 rev)
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.
Various assertion macros.
Count the number of set bits in an integer type.
static void add_popcount(A &accumulator, V value)
Add the number of set bits in value to accumulator.
functions for reading and writing different width words
void aligned_write4(unsigned char *ptr, T value)
uint32_t aligned_read4(const unsigned char *ptr)