34 using namespace Honey;
39 #ifdef HONEY_FREELIST_SIZE
40 # define FREELIST_END_ \
41 (8 + (HONEY_FREELIST_SIZE < 3 ? 3 : HONEY_FREELIST_SIZE) * 4)
42 # define FREELIST_END (FREELIST_END_ < 2048 ? FREELIST_END_ : 2048)
44 # define FREELIST_END block_size
62 (void)
B; (void)n; (void)ptr;
64 B->read_block(n, ptr);
75 (void)
B; (void)n; (void)ptr; (void)
rev;
80 B->write_block(n, ptr, flw_appending);
89 return first_unused_block++;
97 p =
new uint8_t[block_size];
98 read_block(
B, fl.n,
p);
109 str(fl.n) +
", " +
str(fl.c) +
118 uint4 old_fl_blk = fl.n;
126 read_block(
B, fl.n,
p);
134 *blk_to_free = old_fl_blk;
136 mark_block_unused(
B, block_size, old_fl_blk);
139 return get_block(
B, block_size);
154 p =
new uint8_t[block_size];
155 read_block(
B, fl.n,
p);
157 Assert(fl.n == fl_end.n ||
179 read_block(
B, fl.n,
p);
187 return walk(
B, block_size, inclusive);
203 pw =
new uint8_t[block_size];
205 read_block(
B, flw.n, pw);
206 flw_appending =
true;
210 uint4 n = get_block(
B, block_size, &blk_to_free);
216 flw_appending = (n == first_unused_block - 1);
221 uint4 n = get_block(
B, block_size, &blk_to_free);
223 #ifdef HONEY_FREELIST_SIZE
229 if (
p && flw.n == fl.n) {
231 memcpy(
p, pw, block_size);
232 Assert(fl.n == fl_end.n ||
237 flw_appending = (n == first_unused_block - 1);
245 mark_block_unused(
B, block_size, blk_to_free);
251 if (pw && flw.c != 0) {
253 #ifdef HONEY_FREELIST_SIZE
259 if (
p && flw.n == fl.n) {
261 memcpy(
p, pw, block_size);
262 Assert(fl.n == fl_end.n ||
265 flw_appending =
true;
272 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
275 bitmap_size = (first_unused + BITS_PER_ELT - 1) / BITS_PER_ELT;
277 std::fill_n(bitmap, bitmap_size - 1, ALL_BITS);
280 uint4 remainder = first_unused & (BITS_PER_ELT - 1);
282 bitmap[bitmap_size - 1] = (
static_cast<elt_type>(1) << remainder) - 1;
284 bitmap[bitmap_size - 1] = ALL_BITS;
290 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
292 for (
uint4 i = 0; i < bitmap_size; ++i) {
296 if (p_first_bad_blk) {
297 uint4 first_bad_blk = i * BITS_PER_ELT;
299 #if HAVE_DECL___BUILTIN_CTZ
300 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned)) {
301 first_bad_blk += __builtin_ctz(elt);
303 #if HAVE_DECL___BUILTIN_CTZL
304 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned long)) {
305 first_bad_blk += __builtin_ctzl(elt);
307 #if HAVE_DECL___BUILTIN_CTZLL
308 }
else if constexpr(
sizeof(
elt_type) ==
sizeof(
unsigned long long)) {
309 first_bad_blk += __builtin_ctzll(elt);
312 for (
elt_type mask = 1; (elt & mask) == 0; mask <<= 1) {
316 *p_first_bad_blk = first_bad_blk;
317 p_first_bad_blk =
nullptr;
uint4 count_set_bits(uint4 *p_first_bad_blk) const
Count how many bits are still set.
HoneyFreeListChecker(const HoneyFreeListChecker &)
void write_block(const HoneyTable *B, uint4 n, uint8_t *p, uint4 rev)
void mark_block_unused(const HoneyTable *B, uint4 block_size, uint4 n)
uint4 get_first_unused_block() const
uint4 walk(const HoneyTable *B, uint4 block_size, bool inclusive)
void commit(const HoneyTable *B, uint4 block_size)
void read_block(const HoneyTable *B, uint4 n, uint8_t *p)
uint4 get_block(const HoneyTable *B, uint4 block_size, uint4 *blk_to_free=NULL)
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)