20 #ifndef _TPIE_BTREE_SERIALIZED_STORE_H_
21 #define _TPIE_BTREE_SERIALIZED_STORE_H_
24 #include <tpie/btree/base.h>
47 class serialized_store {
60 typedef size_t size_type;
62 typedef uint64_t off_t;
76 struct internal_content {
83 static constexpr
size_t block_size() {
return bs_?bs_:24*1024;}
84 static constexpr
size_t min_internal_size() {
return 1;}
85 static constexpr
size_t max_internal_size() {
return a_ ? a_ : (block_size() -
sizeof(off_t) -
sizeof(
size_t)) /
sizeof(internal_content) ; }
86 static constexpr
size_t min_leaf_size() {
return 1;}
87 static constexpr
size_t max_leaf_size() {
return b_ ? b_ : (block_size() -
sizeof(off_t) -
sizeof(
size_t)) /
sizeof(T);}
92 internal_content values[max_internal_size()];
95 friend void serialize(S & s,
const internal & i) {
98 serialize(s, i.values, i.values + i.count);
101 template <
typename D>
113 T values[max_leaf_size()];
115 template <
typename S>
116 friend void serialize(S & s,
const leaf & i) {
119 serialize(s, i.values, i.values + i.count);
122 template <
typename D>
132 static constexpr uint64_t good_magic = 0x8bbd51bfe5e3d477, current_version = 0;
138 off_t metadata_offset;
142 typedef std::shared_ptr<internal> internal_type;
143 typedef std::shared_ptr<leaf> leaf_type;
148 explicit serialized_store(
const std::string & path,
bool write_only=
false):
149 m_height(0), m_size(0), metadata_offset(0), metadata_size(0), path(path) {
150 f.reset(
new std::fstream());
153 f->open(path, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
155 throw invalid_file_exception(
"Open failed");
156 memset(&h, 0,
sizeof(h));
157 f->write(reinterpret_cast<char *>(&h),
sizeof(h));
159 f->open(path, std::ios_base::in | std::ios_base::binary);
161 throw invalid_file_exception(
"Open failed");
162 f->read(reinterpret_cast<char *>(&h),
sizeof(h));
164 throw invalid_file_exception(
"Unable to read header");
166 if (h.magic != header::good_magic)
167 throw invalid_file_exception(
"Bad magic");
169 if (h.version != header::current_version)
170 throw invalid_file_exception(
"Bad version");
174 metadata_offset = h.metadata_offset;
175 metadata_size = h.metadata_size;
177 root_leaf = std::make_shared<leaf>();
178 root_leaf->my_offset = h.root;
181 }
else if (m_height > 1) {
182 root_internal = std::make_shared<internal>();
183 root_internal->my_offset = h.root;
191 void move(internal_type src,
size_t src_i,
192 internal_type dst,
size_t dst_i) {
193 dst->values[dst_i] = src->values[src_i];
196 void move(leaf_type src,
size_t src_i,
197 leaf_type dst,
size_t dst_i) {
198 dst->values[dst_i] = src->values[src_i];
201 void set(leaf_type dst,
size_t dst_i, T c) {
202 assert(dst == current_leaf);
203 dst->values[dst_i] = c;
206 void set(internal_type node,
size_t i, internal_type c) {
207 assert(node == current_internal);
208 node->values[i].offset = c->my_offset;
211 void set(internal_type node,
size_t i, leaf_type c) {
212 assert(node == current_internal);
213 node->values[i].offset = c->my_offset;
216 const T &
get(leaf_type l,
size_t i)
const {
220 size_t count(internal_type node)
const {
224 size_t count(leaf_type node)
const {
228 void set_count(internal_type node,
size_t i) {
232 void set_count(leaf_type node,
size_t i) {
236 leaf_type create_leaf() {
237 assert(!current_internal && !current_leaf);
238 current_leaf = std::make_shared<leaf>();
239 current_leaf->my_offset = (stream_size_type)f->tellp();
242 leaf_type create(leaf_type) {
return create_leaf();}
243 internal_type create_internal() {
244 assert(!current_internal && !current_leaf);
245 current_internal = std::make_shared<internal>();
246 current_internal->my_offset = (stream_size_type)f->tellp();
247 return current_internal;
249 internal_type create(internal_type) {
return create_internal();}
251 void set_root(internal_type node) {root_internal = node;}
252 void set_root(leaf_type node) {root_leaf = node;}
254 internal_type get_root_internal()
const {
255 return root_internal;
258 leaf_type get_root_leaf()
const {
262 internal_type get_child_internal(internal_type node,
size_t i)
const {
263 internal_type child = std::make_shared<internal>();
264 assert(i < node->count);
265 child->my_offset = node->values[i].offset;
266 f->seekg(child->my_offset);
271 leaf_type get_child_leaf(internal_type node,
size_t i)
const {
272 leaf_type child = std::make_shared<leaf>();
273 assert(i < node->count);
274 child->my_offset = node->values[i].offset;
275 f->seekg(child->my_offset);
280 size_t index(off_t my_offset, internal_type node)
const {
281 for (
size_t i=0; i < node->count; ++i)
282 if (node->values[i].offset == my_offset)
return i;
287 size_t index(leaf_type l, internal_type node)
const {
288 return index(l->my_offset, node);
291 size_t index(internal_type i, internal_type node)
const {
292 return index(i->my_offset, node);
295 void set_augment(leaf_type l, internal_type p,
augment_type ag) {
296 size_t idx = index(l->my_offset, p);
297 p->values[idx].augment = ag;
300 void set_augment(internal_type i, internal_type p,
augment_type ag) {
301 size_t idx = index(i->my_offset, p);
302 p->values[idx].augment = ag;
305 const augment_type & augment(internal_type p,
size_t i)
const {
306 return p->values[i].augment;
309 size_t height()
const throw() {
313 void set_height(
size_t height)
throw() {
317 size_t size()
const throw() {
321 void set_size(
size_t size)
throw() {
326 if (current_internal) {
327 assert(!current_leaf);
328 assert((stream_size_type)f->tellp() == current_internal->my_offset);
330 current_internal.reset();
333 assert((stream_size_type)f->tellp() == current_leaf->my_offset);
335 current_leaf.reset();
339 void finalize_build() {
341 assert(!current_internal && !current_leaf);
344 h.magic = header::good_magic;
345 h.version = header::current_version;
348 h.root = root_internal->my_offset;
349 }
else if (root_leaf) {
350 h.root = root_leaf->my_offset;
356 h.metadata_offset = metadata_offset;
357 h.metadata_size = metadata_size;
359 f->write(reinterpret_cast<char *>(&h),
sizeof(h));
362 f->open(path, std::ios_base::in | std::ios_base::binary);
364 throw invalid_file_exception(
"Open failed");
367 void set_metadata(
const std::string & data) {
368 assert(!current_internal && !current_leaf);
369 assert(f->is_open());
370 metadata_offset = (stream_size_type)f->tellp();
371 metadata_size = data.size();
372 f->write(data.c_str(), data.size());
375 std::string get_metadata() {
376 assert(f->is_open());
377 if (metadata_offset == 0 || metadata_size == 0)
379 std::string data(metadata_size,
'\0');
380 f->read(&data[0], metadata_size);
386 off_t metadata_offset, metadata_size;
389 std::unique_ptr<std::fstream> f;
390 internal_type current_internal, root_internal;
391 leaf_type current_leaf, root_leaf;
394 friend class ::tpie::btree_node;
397 friend class ::tpie::btree_iterator;
399 template <
typename,
typename>
400 friend class bbits::tree;
402 template <
typename,
typename>
403 friend class bbits::tree_state;
405 template<
typename,
typename>
406 friend class bbits::builder;
408 template <
typename,
bool>
409 friend struct bbits::block_size_getter;
Defines the tp_assert macro.
Binary serialization and unserialization.
This file contains a few deprecated definitions for legacy code.
void unserialize(S &src, foo &v)
Sample tpie::unserialize prototype.
A augment_type
Type of augmentation stored.
T value_type
Type of value of items stored.
void serialize(D &dst, const foo &v)
Sample tpie::serialize prototype.
#define tp_assert(condition, message)