xapian-core  2.0.0
honey_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_HONEY_FREELIST_H
22 #define XAPIAN_INCLUDED_HONEY_FREELIST_H
23 
24 #include "honey_defs.h"
25 #include "pack.h"
26 
27 class HoneyTable;
28 
30  public:
32  uint4 n = 0;
33 
35  unsigned c = 0;
36 
38 
39  bool operator==(const HoneyFLCursor& o) const {
40  return n == o.n && c == o.c;
41  }
42 
43  bool operator!=(const HoneyFLCursor& o) const {
44  return !(*this == o);
45  }
46 
47  void swap(HoneyFLCursor& 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 HoneyFreeList&);
69 
70  void read_block(const HoneyTable* B, uint4 n, uint8_t* p);
71 
72  void write_block(const HoneyTable* B, uint4 n, uint8_t* p, uint4 rev);
73 
74  protected:
76 
78 
80 
81  bool flw_appending = false;
82 
83  private:
85  uint8_t* p = nullptr;
86 
88  uint8_t* pw = nullptr;
89 
90  public:
92 
93  void reset() {
94  revision = 0;
96  flw_appending = false;
97  }
98 
99  ~HoneyFreeList() { delete [] p; delete [] pw; }
100 
101  bool empty() const { return fl == fl_end; }
102 
103  uint4 get_block(const HoneyTable* B, uint4 block_size,
104  uint4* blk_to_free = NULL);
105 
106  uint4 walk(const HoneyTable* B, uint4 block_size, bool inclusive);
107 
108  void mark_block_unused(const HoneyTable* B, uint4 block_size, uint4 n);
109 
110  uint4 get_revision() const { return revision; }
111  void set_revision(uint4 revision_) { revision = revision_; }
112 
114 
115  // Used when compacting to a single file.
117 
118  void commit(const HoneyTable* B, uint4 block_size);
119 
120  void pack(std::string& buf) {
121  pack_uint(buf, revision);
123  fl.pack(buf);
124  flw.pack(buf);
125  }
126 
127  bool unpack(const char** pstart, const char* end) {
128  bool r = unpack_uint(pstart, end, &revision) &&
129  unpack_uint(pstart, end, &first_unused_block) &&
130  fl.unpack(pstart, end) &&
131  flw.unpack(pstart, end);
132  if (r) {
133  fl_end = flw;
134  flw_appending = false;
135  }
136  return r;
137  }
138 
139  bool unpack(const std::string& s) {
140  const char* ptr = s.data();
141  const char* end = ptr + s.size();
142  return unpack(&ptr, end) && ptr == end;
143  }
144 };
145 
147  // FIXME: uint_fast32_t is probably a good choice.
148  typedef unsigned long elt_type;
149 
151 
153 
154  // Prevent copying
157 
158  public:
159  explicit HoneyFreeListChecker(const HoneyFreeList& fl);
160 
162  delete [] bitmap;
163  }
164 
165  bool mark_used(uint4 n) {
166  const unsigned BITS_PER_ELT = sizeof(elt_type) * 8;
167  elt_type mask = static_cast<elt_type>(1) << (n & (BITS_PER_ELT - 1));
168  n /= BITS_PER_ELT;
169  if (rare(n >= bitmap_size)) return false;
170  if ((bitmap[n] & mask) == 0) return false;
171  bitmap[n] &= ~mask;
172  return true;
173  }
174 
176  uint4 count_set_bits(uint4 * p_first_bad_blk) const;
177 };
178 
179 #endif // XAPIAN_INCLUDED_HONEY_FREELIST_H
Definition: unittest.cc:660
unsigned c
Current offset in block.
void pack(std::string &buf)
void swap(HoneyFLCursor &o)
uint4 n
Block number of current freelist chunk.
bool operator!=(const HoneyFLCursor &o) const
bool unpack(const char **p, const char *end)
bool operator==(const HoneyFLCursor &o) const
HoneyFreeListChecker & operator=(const HoneyFreeListChecker &)
uint4 count_set_bits(uint4 *p_first_bad_blk) const
Count how many bits are still set.
unsigned long elt_type
bool mark_used(uint4 n)
HoneyFreeListChecker(const HoneyFreeListChecker &)
void pack(std::string &buf)
bool empty() const
HoneyFLCursor fl
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)
void set_revision(uint4 revision_)
uint4 get_first_unused_block() const
uint8_t * p
Current freelist block.
HoneyFreeList(const HoneyFreeList &)
uint4 get_revision() const
void operator=(const HoneyFreeList &)
bool unpack(const char **pstart, const char *end)
uint4 walk(const HoneyTable *B, uint4 block_size, bool inclusive)
void set_first_unused_block(uint4 base)
bool unpack(const std::string &s)
HoneyFLCursor flw
void commit(const HoneyTable *B, uint4 block_size)
uint8_t * pw
Current freelist block we're writing.
uint4 first_unused_block
void read_block(const HoneyTable *B, uint4 n, uint8_t *p)
HoneyFLCursor fl_end
uint4 get_block(const HoneyTable *B, uint4 block_size, uint4 *blk_to_free=NULL)
#define usual(COND)
Definition: config.h:608
#define rare(COND)
Definition: config.h:607
PositionList * p
Definitions, types, etc for use inside honey.
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