1 /** @file glass_freelist.h
2 * @brief Glass freelist
4 /* Copyright 2014 Olly Betts
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 #ifndef XAPIAN_INCLUDED_GLASS_FREELIST_H
23 #define XAPIAN_INCLUDED_GLASS_FREELIST_H
25 #include "glass_defs.h"
32 /// Block number of current freelist chunk.
35 /// Current offset in block.
38 GlassFLCursor() : n(0), c(0) { }
40 bool operator==(const GlassFLCursor
& o
) const {
41 return n
== o
.n
&& c
== o
.c
;
44 bool operator!=(const GlassFLCursor
& o
) const {
48 void swap(GlassFLCursor
&o
) {
53 void pack(std::string
& buf
) {
55 pack_uint(buf
, c
/ 4);
58 bool unpack(const char ** p
, const char * end
) {
59 bool r
= unpack_uint(p
, end
, &n
) && unpack_uint(p
, end
, &c
);
67 GlassFreeList(const GlassFreeList
&);
69 void operator=(const GlassFreeList
&);
71 void read_block(const GlassTable
* B
, uint4 n
, byte
* p
);
73 void write_block(const GlassTable
* B
, uint4 n
, byte
* p
, uint4 rev
);
78 uint4 first_unused_block
;
80 GlassFLCursor fl
, fl_end
, flw
;
85 /// Current freelist block.
88 /// Current freelist block we're writing.
94 first_unused_block
= 0;
95 flw_appending
= false;
101 first_unused_block
= 0;
102 flw_appending
= false;
105 ~GlassFreeList() { delete [] p
; delete [] pw
; }
107 bool empty() const { return fl
== fl_end
; }
109 uint4
get_block(const GlassTable
* B
, uint4 block_size
,
110 uint4
* blk_to_free
= NULL
);
112 uint4
walk(const GlassTable
*B
, uint4 block_size
, bool inclusive
);
114 void mark_block_unused(const GlassTable
* B
, uint4 block_size
, uint4 n
);
116 uint4
get_revision() const { return revision
; }
117 void set_revision(uint4 revision_
) { revision
= revision_
; }
119 uint4
get_first_unused_block() const { return first_unused_block
; }
121 // Used when compacting to a single file.
122 void set_first_unused_block(uint4 base
) { first_unused_block
= base
; }
124 void commit(const GlassTable
* B
, uint4 block_size
);
126 void pack(std::string
& buf
) {
127 pack_uint(buf
, revision
);
128 pack_uint(buf
, first_unused_block
);
133 bool unpack(const char ** pstart
, const char * end
) {
134 bool r
= unpack_uint(pstart
, end
, &revision
) &&
135 unpack_uint(pstart
, end
, &first_unused_block
) &&
136 fl
.unpack(pstart
, end
) &&
137 flw
.unpack(pstart
, end
);
140 flw_appending
= false;
145 bool unpack(const std::string
& s
) {
146 const char * ptr
= s
.data();
147 const char * end
= ptr
+ s
.size();
148 return unpack(&ptr
, end
) && ptr
== end
;
152 class GlassFreeListChecker
{
153 // FIXME: uint_fast32_t is probably a good choice.
154 typedef unsigned long elt_type
;
161 GlassFreeListChecker(const GlassFreeListChecker
&);
162 GlassFreeListChecker
& operator=(const GlassFreeListChecker
&);
165 explicit GlassFreeListChecker(const GlassFreeList
& fl
);
167 ~GlassFreeListChecker() {
171 bool mark_used(uint4 n
) {
172 const unsigned BITS_PER_ELT
= sizeof(elt_type
) * 8;
173 elt_type mask
= static_cast<elt_type
>(1) << (n
& (BITS_PER_ELT
- 1));
175 if (rare(n
>= bitmap_size
)) return false;
176 if ((bitmap
[n
] & mask
) == 0) return false;
181 /// Count how many bits are still set.
182 uint4
count_set_bits(uint4
* p_first_bad_blk
) const;
185 #endif // XAPIAN_INCLUDED_GLASS_FREELIST_H