diff --git a/Makefile b/Makefile index fc0ecb3..450c7d7 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,9 @@ SOURCE=\ endian_utils.cc \ error_set.cc \ hex_dump.cc \ + human_readable_format.cc \ metadata.cc \ + metadata_dump.cc \ metadata_disk_structures.cc \ space_map_disk.cc \ transaction_manager.cc diff --git a/block.tcc b/block.tcc index b5b66f1..19eb18f 100644 --- a/block.tcc +++ b/block.tcc @@ -57,7 +57,8 @@ block_manager::block_manager(std::string const &path, block_address n superblock_count_(0), ordinary_count_(0) { - fd_ = ::open(path.c_str(), O_RDWR | O_CREAT, 0666); + //fd_ = ::open(path.c_str(), O_RDWR | O_CREAT, 0666); + fd_ = ::open(path.c_str(), O_RDONLY, 0666); if (fd_ < 0) throw std::runtime_error("couldn't open file"); } diff --git a/btree.h b/btree.h index 722cb25..40f1c60 100644 --- a/btree.h +++ b/btree.h @@ -332,12 +332,14 @@ namespace persistent_data { // The bool return values indicate whether the walk // should be continued into sub trees of the node (true == continue). - virtual bool visit_internal(unsigned level, boost::optional key, + virtual bool visit_internal(unsigned level, bool sub_root, boost::optional key, internal_node const &n) = 0; - virtual bool visit_internal_leaf(unsigned level, boost::optional key, + virtual bool visit_internal_leaf(unsigned level, bool sub_root, boost::optional key, internal_node const &n) = 0; - virtual bool visit_leaf(unsigned level, boost::optional key, + virtual bool visit_leaf(unsigned level, bool sub_root, boost::optional key, leaf_node const &n) = 0; + + virtual void visit_complete() {} }; // Walks the tree in depth first order @@ -366,7 +368,7 @@ namespace persistent_data { int *index); void walk_tree(typename visitor::ptr visitor, - unsigned level, boost::optional key, + unsigned level, bool root, boost::optional key, block_address b) const; typename persistent_data::transaction_manager::ptr tm_; diff --git a/btree.tcc b/btree.tcc index 97d1978..fed0d1a 100644 --- a/btree.tcc +++ b/btree.tcc @@ -599,14 +599,16 @@ template void btree::visit(typename visitor::ptr visitor) const { - walk_tree(visitor, 0, boost::optional(), root_); + walk_tree(visitor, 0, true, boost::optional(), root_); + visitor->visit_complete(); } template void btree:: walk_tree(typename visitor::ptr visitor, - unsigned level, boost::optional key, + unsigned level, bool sub_root, + boost::optional key, block_address b) const { using namespace btree_detail; @@ -614,18 +616,18 @@ walk_tree(typename visitor::ptr visitor, read_ref blk = tm_->read_lock(b); internal_node o = to_node(blk); if (o.get_type() == INTERNAL) { - if (visitor->visit_internal(level, key, o)) + if (visitor->visit_internal(level, sub_root, key, o)) for (unsigned i = 0; i < o.get_nr_entries(); i++) - walk_tree(visitor, level, o.key_at(i), o.value_at(i)); + walk_tree(visitor, level, false, o.key_at(i), o.value_at(i)); } else if (level < Levels - 1) { - if (visitor->visit_internal_leaf(level, key, o)) + if (visitor->visit_internal_leaf(level, sub_root, key, o)) for (unsigned i = 0; i < o.get_nr_entries(); i++) - walk_tree(visitor, level + 1, boost::optional(), o.value_at(i)); + walk_tree(visitor, level + 1, true, boost::optional(o.key_at(i)), o.value_at(i)); } else { leaf_node ov = to_node(blk); - visitor->visit_leaf(level, key, ov); + visitor->visit_leaf(level, sub_root, key, ov); } } diff --git a/btree_checker.h b/btree_checker.h index 4e238df..3c0f028 100644 --- a/btree_checker.h +++ b/btree_checker.h @@ -75,6 +75,7 @@ namespace persistent_data { } bool visit_internal(unsigned level, + bool sub_root, optional key, btree_detail::node_ref const &n) { if (already_visited(n)) @@ -94,6 +95,7 @@ namespace persistent_data { } bool visit_internal_leaf(unsigned level, + bool sub_root, optional key, btree_detail::node_ref const &n) { if (already_visited(n)) @@ -115,6 +117,7 @@ namespace persistent_data { } bool visit_leaf(unsigned level, + bool sub_root, optional key, btree_detail::node_ref const &n) { if (already_visited(n)) diff --git a/emitter.h b/emitter.h new file mode 100644 index 0000000..f8aee5f --- /dev/null +++ b/emitter.h @@ -0,0 +1,53 @@ +#ifndef EMITTER_H +#define EMITTER_H + +#include +#include +#include + +//---------------------------------------------------------------- + +namespace thin_provisioning { + + //------------------------------------------------ + // Here's a little grammar for how this all hangs together: + // + // superblock :=