33 #if !HAVE_DECL___BUILTIN_POPCOUNT
36 # if HAVE_DECL___POPCNT || HAVE_DECL___POPCNT64
42 using namespace Glass;
47 #ifdef GLASS_FREELIST_SIZE
48 # define FREELIST_END_ \
49 (8 + (GLASS_FREELIST_SIZE < 3 ? 3 : GLASS_FREELIST_SIZE) * 4)
50 # define FREELIST_END (FREELIST_END_ < 2048 ? FREELIST_END_ : 2048)
52 # define FREELIST_END block_size
69 B->read_block(n, ptr);
81 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);
115 uint4 old_fl_blk = fl.n;
123 read_block(
B, fl.n, p);
131 *blk_to_free = old_fl_blk;
133 mark_block_unused(
B, block_size, old_fl_blk);
136 return get_block(
B, block_size);
151 p =
new uint8_t[block_size];
152 read_block(
B, fl.n, p);
175 read_block(
B, fl.n, p);
183 return walk(
B, block_size, inclusive);
197 pw =
new uint8_t[block_size];
199 read_block(
B, flw.n, pw);
200 flw_appending =
true;
204 uint4 n = get_block(
B, block_size, &blk_to_free);
210 flw_appending = (n == first_unused_block - 1);
215 uint4 n = get_block(
B, block_size, &blk_to_free);
217 #ifdef GLASS_FREELIST_SIZE
223 if (p && flw.n == fl.n) {
225 memcpy(p, pw, block_size);
230 flw_appending = (n == first_unused_block - 1);
238 mark_block_unused(
B, block_size, blk_to_free);
244 if (pw && flw.c != 0) {
246 #ifdef GLASS_FREELIST_SIZE
252 if (p && flw.n == fl.n) {
254 memcpy(p, pw, block_size);
257 flw_appending =
true;
264 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
267 bitmap_size = (first_unused + BITS_PER_ELT - 1) / BITS_PER_ELT;
269 std::fill_n(bitmap, bitmap_size - 1, ALL_BITS);
272 uint4 remainder = first_unused & (BITS_PER_ELT - 1);
274 bitmap[bitmap_size - 1] = (
static_cast<elt_type>(1) << remainder) - 1;
276 bitmap[bitmap_size - 1] = ALL_BITS;
282 const unsigned BITS_PER_ELT =
sizeof(
elt_type) * 8;
284 for (
uint4 i = 0; i < bitmap_size; ++i) {
288 if (p_first_bad_blk) {
289 uint4 first_bad_blk = i * BITS_PER_ELT;
291 #if HAVE_DECL___BUILTIN_CTZ
292 }
else if (
sizeof(
elt_type) ==
sizeof(unsigned)) {
293 first_bad_blk += __builtin_ctz(elt);
295 #if HAVE_DECL___BUILTIN_CTZL
296 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned long)) {
297 first_bad_blk += __builtin_ctzl(elt);
299 #if HAVE_DECL___BUILTIN_CTZLL
300 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned long long)) {
301 first_bad_blk += __builtin_ctzll(elt);
304 for (
elt_type mask = 1; (elt & mask) == 0; mask <<= 1) {
308 *p_first_bad_blk = first_bad_blk;
309 p_first_bad_blk =
nullptr;
314 #if HAVE_DECL___BUILTIN_POPCOUNT
315 }
else if (
sizeof(
elt_type) ==
sizeof(unsigned)) {
316 c += __builtin_popcount(elt);
317 #elif HAVE_DECL___POPCNT
318 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned)) {
319 c +=
static_cast<uint4>(__popcnt(elt));
321 #if HAVE_DECL___BUILTIN_POPCOUNTL
322 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned long)) {
323 c += __builtin_popcountl(elt);
325 #if HAVE_DECL___BUILTIN_POPCOUNTLL
326 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned long long)) {
327 c += __builtin_popcountll(elt);
328 #elif HAVE_DECL___POPCNT64
329 }
else if (
sizeof(
elt_type) ==
sizeof(
unsigned long long)) {
330 c +=
static_cast<uint4>(__popcnt64(elt));
void SET_LEVEL(uint8_t *b, int x)
int GET_LEVEL(const uint8_t *b)
void SET_REVISION(uint8_t *b, uint4 rev)
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.
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.
functions for reading and writing different width words
void aligned_write4(unsigned char *ptr, T value)
uint32_t aligned_read4(const unsigned char *ptr)