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 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 222 write_block(B, flw.n, pw,
revision + 1);
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 251 write_block(B, flw.n, pw,
revision);
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));
uint4 walk(const GlassTable *B, uint4 block_size, bool inclusive)
void write_block(const GlassTable *B, uint4 n, uint8_t *p, uint4 rev)
XAPIAN_REVISION_TYPE rev
Revision number of a database.
void commit(const GlassTable *B, uint4 block_size)
Class managing a Btree table in a Glass database.
GlassFreeListChecker(const GlassFreeListChecker &)
void mark_block_unused(const GlassTable *B, uint4 block_size, uint4 n)
int revision()
Report the revision of the library which the program is linked with.
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.
void aligned_write4(unsigned char *ptr, T value)
Hierarchy of classes which Xapian can throw as exceptions.
functions for reading and writing different width words
void SET_LEVEL(uint8_t *b, int x)
uint4 get_first_unused_block() const
int GET_LEVEL(const uint8_t *b)
uint32_t aligned_read4(const unsigned char *ptr)
string str(int value)
Convert int to std::string.
uint4 count_set_bits(uint4 *p_first_bad_blk) const
Count how many bits are still set.
void read_block(const GlassTable *B, uint4 n, uint8_t *p)
DatabaseCorruptError indicates database corruption was detected.
void read_block(uint4 n, uint8_t *p) const
read_block(n, p) reads block n of the DB file to address p.
const int LEVEL_FREELIST
Freelist blocks have their level set to LEVEL_FREELIST.
Various assertion macros.
const uint4 UNUSED
Invalid freelist block value, so we can detect overreading bugs, etc.
void SET_REVISION(uint8_t *b, uint4 rev)
uint4 get_block(const GlassTable *B, uint4 block_size, uint4 *blk_to_free=NULL)
const unsigned C_BASE
The first offset to use for storing free block info.