xapian-core  2.0.0
glass_freelist.h
Go to the documentation of this file.
1 
4 /* Copyright 2014 Olly Betts
5  *
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.
10  *
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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see
18  * <https://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef XAPIAN_INCLUDED_GLASS_FREELIST_H
22 #define XAPIAN_INCLUDED_GLASS_FREELIST_H
23 
24 #include "glass_defs.h"
25 #include "pack.h"
26 
27 class GlassTable;
28 
30  public:
33 
35  unsigned c;
36 
37  GlassFLCursor() : n(0), c(0) { }
38 
39  bool operator==(const GlassFLCursor & o) const {
40  return n == o.n && c == o.c;
41  }
42 
43  bool operator!=(const GlassFLCursor & o) const {
44  return !(*this == o);
45  }
46 
47  void swap(GlassFLCursor &o) {
48  std::swap(n, o.n);
49  std::swap(c, o.c);
50  }
51 
52  void pack(std::string & buf) {
53  pack_uint(buf, n);
54  pack_uint(buf, c / 4);
55  }
56 
57  bool unpack(const char ** p, const char * end) {
58  bool r = unpack_uint(p, end, &n) && unpack_uint(p, end, &c);
59  if (usual(r))
60  c *= 4;
61  return r;
62  }
63 };
64 
67 
68  void operator=(const GlassFreeList &);
69 
70  void read_block(const GlassTable * B, uint4 n, uint8_t * p);
71 
72  void write_block(const GlassTable * B, uint4 n, uint8_t * p, uint4 rev);
73 
74  protected:
76 
78 
80 
82 
83  private:
85  uint8_t * p;
86 
88  uint8_t * pw;
89 
90  public:
92  revision = 0;
94  flw_appending = false;
95  p = pw = NULL;
96  }
97 
98  void reset() {
99  revision = 0;
100  first_unused_block = 0;
101  flw_appending = false;
102  }
103 
104  ~GlassFreeList() { delete [] p; delete [] pw; }
105 
106  bool empty() const { return fl == fl_end; }
107 
108  uint4 get_block(const GlassTable * B, uint4 block_size,
109  uint4 * blk_to_free = NULL);
110 
111  uint4 walk(const GlassTable *B, uint4 block_size, bool inclusive);
112 
113  void mark_block_unused(const GlassTable * B, uint4 block_size, uint4 n);
114 
115  uint4 get_revision() const { return revision; }
116  void set_revision(uint4 revision_) { revision = revision_; }
117 
119 
120  // Used when compacting to a single file.
122 
123  void commit(const GlassTable * B, uint4 block_size);
124 
125  void pack(std::string & buf) {
126  pack_uint(buf, revision);
128  fl.pack(buf);
129  flw.pack(buf);
130  }
131 
132  bool unpack(const char ** pstart, const char * end) {
133  bool r = unpack_uint(pstart, end, &revision) &&
134  unpack_uint(pstart, end, &first_unused_block) &&
135  fl.unpack(pstart, end) &&
136  flw.unpack(pstart, end);
137  if (r) {
138  fl_end = flw;
139  flw_appending = false;
140  }
141  return r;
142  }
143 
144  bool unpack(const std::string & s) {
145  const char * ptr = s.data();
146  const char * end = ptr + s.size();
147  return unpack(&ptr, end) && ptr == end;
148  }
149 };
150 
152  // FIXME: uint_fast32_t is probably a good choice.
153  typedef unsigned long elt_type;
154 
156 
158 
159  // Prevent copying
162 
163  public:
164  explicit GlassFreeListChecker(const GlassFreeList & fl);
165 
167  delete [] bitmap;
168  }
169 
170  bool mark_used(uint4 n) {
171  const unsigned BITS_PER_ELT = sizeof(elt_type) * 8;
172  elt_type mask = static_cast<elt_type>(1) << (n & (BITS_PER_ELT - 1));
173  n /= BITS_PER_ELT;
174  if (rare(n >= bitmap_size)) return false;
175  if ((bitmap[n] & mask) == 0) return false;
176  bitmap[n] &= ~mask;
177  return true;
178  }
179 
181  uint4 count_set_bits(uint4 * p_first_bad_blk) const;
182 };
183 
184 #endif // XAPIAN_INCLUDED_GLASS_FREELIST_H
Definition: unittest.cc:660
bool unpack(const char **p, const char *end)
void pack(std::string &buf)
uint4 n
Block number of current freelist chunk.
bool operator!=(const GlassFLCursor &o) const
void swap(GlassFLCursor &o)
unsigned c
Current offset in block.
bool operator==(const GlassFLCursor &o) const
unsigned long elt_type
GlassFreeListChecker(const GlassFreeListChecker &)
GlassFreeListChecker & operator=(const GlassFreeListChecker &)
bool mark_used(uint4 n)
uint4 count_set_bits(uint4 *p_first_bad_blk) const
Count how many bits are still set.
void set_first_unused_block(uint4 base)
void operator=(const GlassFreeList &)
void pack(std::string &buf)
GlassFLCursor flw
void write_block(const GlassTable *B, uint4 n, uint8_t *p, uint4 rev)
GlassFreeList(const GlassFreeList &)
uint8_t * pw
Current freelist block we're writing.
uint4 get_first_unused_block() const
uint4 first_unused_block
bool unpack(const std::string &s)
GlassFLCursor fl
void mark_block_unused(const GlassTable *B, uint4 block_size, uint4 n)
uint4 walk(const GlassTable *B, uint4 block_size, bool inclusive)
void set_revision(uint4 revision_)
GlassFLCursor fl_end
void commit(const GlassTable *B, uint4 block_size)
bool empty() const
void read_block(const GlassTable *B, uint4 n, uint8_t *p)
uint8_t * p
Current freelist block.
bool unpack(const char **pstart, const char *end)
uint4 get_block(const GlassTable *B, uint4 block_size, uint4 *blk_to_free=NULL)
uint4 get_revision() const
Class managing a Btree table in a Glass database.
Definition: glass_table.h:432
#define usual(COND)
Definition: config.h:608
#define rare(COND)
Definition: config.h:607
PositionList * p
Definitions, types, etc for use inside glass.
uint32_t uint4
Definition: internaltypes.h:31
XAPIAN_REVISION_TYPE rev
Revision number of a database.
Definition: types.h:108
Pack types into strings and unpack them again.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
Definition: pack.h:346
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
Definition: pack.h:315