diff --git a/caching/hint_array.cc b/caching/hint_array.cc index d67f11d..0b95e48 100644 --- a/caching/hint_array.cc +++ b/caching/hint_array.cc @@ -2,6 +2,7 @@ using namespace boost; using namespace caching; +using namespace caching::hint_array_damage; using namespace persistent_data; //---------------------------------------------------------------- @@ -64,6 +65,18 @@ namespace { //-------------------------------- + template + shared_ptr + downcast_array(shared_ptr base) { + shared_ptr a = dynamic_pointer_cast(base); + if (!a) + throw runtime_error("internal error: couldn't cast hint array"); + + return a; + } + + //-------------------------------- + template shared_ptr mk_array(transaction_manager::ptr tm, block_address root, unsigned nr_entries) { typedef hint_traits traits; @@ -94,10 +107,7 @@ namespace { typedef hint_traits traits; typedef array ha; - shared_ptr a = dynamic_pointer_cast(base); - if (!a) - throw runtime_error("internal error: couldn't cast hint array"); - + shared_ptr a = downcast_array(base); data = a->get(index); } @@ -116,10 +126,7 @@ namespace { typedef hint_traits traits; typedef array ha; - shared_ptr a = dynamic_pointer_cast(base); - if (!a) - throw runtime_error("internal error: couldn't cast hint array"); - + shared_ptr a = downcast_array(base); a->set(index, data); } @@ -139,9 +146,7 @@ namespace { typedef hint_traits traits; typedef array ha; - shared_ptr a = dynamic_pointer_cast(base); - if (!a) - throw runtime_error("internal error: couldn't cast hint array"); + shared_ptr a = downcast_array(base); a->grow(new_nr_entries, value); } @@ -154,6 +159,62 @@ namespace { #undef xx } } + + //-------------------------------- + + template + struct no_op_visitor { + virtual void visit(uint32_t index, ValueType const &v) { + } + }; + + class ll_damage_visitor { + public: + ll_damage_visitor(damage_visitor &v) + : v_(v) { + } + + virtual void visit(array_detail::damage const &d) { + v_.visit(missing_hints(d.desc_, d.lost_keys_)); + } + + private: + damage_visitor &v_; + }; + + template + void check_hints(shared_ptr base, damage_visitor &visitor) { + typedef hint_traits traits; + typedef array ha; + + shared_ptr a = downcast_array(base); + no_op_visitor nv; + ll_damage_visitor ll(visitor); + a->visit_values(nv, ll); + } + + void check_hints_(uint32_t width, shared_ptr base, + damage_visitor &visitor) { + switch (width) { +#define xx(n) case n: check_hints(base, visitor); break + all_widths +#undef xx + } + } +} + +//---------------------------------------------------------------- + +missing_hints::missing_hints(std::string const desc, run const &keys) + : damage(desc), + keys_(keys) +{ +} + +void +missing_hints::visit(damage_visitor &v) const +{ + v.visit(*this); } //---------------------------------------------------------------- @@ -195,4 +256,10 @@ hint_array::grow(unsigned new_nr_entries, vector const &value) grow_(width_, impl_, new_nr_entries, value); } +void +hint_array::check_hint_array(hint_array_damage::damage_visitor &visitor) +{ + check_hints_(width_, impl_, visitor); +} + //---------------------------------------------------------------- diff --git a/caching/hint_array.h b/caching/hint_array.h index 4dfc8d4..e8483ac 100644 --- a/caching/hint_array.h +++ b/caching/hint_array.h @@ -8,9 +8,43 @@ //---------------------------------------------------------------- namespace caching { - namespace hint_array_detail { + namespace hint_array_damage { + class damage_visitor; - // FIXME: data visitor stuff + class damage { + public: + damage(std::string const &desc) + : desc_(desc) { + } + + virtual ~damage() {} + virtual void visit(damage_visitor &v) const = 0; + + std::string get_desc() const { + return desc_; + } + + private: + std::string desc_; + }; + + struct missing_hints : public damage { + missing_hints(std::string const desc, run const &keys); + virtual void visit(damage_visitor &v) const; + + run keys_; + }; + + class damage_visitor { + public: + virtual ~damage_visitor() {} + + virtual void visit(damage const &d) { + d.visit(*this); + } + + virtual void visit(missing_hints const &d) = 0; + }; } class hint_array { @@ -23,6 +57,7 @@ namespace caching { unsigned get_nr_entries() const; + void grow(unsigned new_nr_entries, void const *v); block_address get_root() const; @@ -30,6 +65,7 @@ namespace caching { void set_hint(unsigned index, vector const &data); void grow(unsigned new_nr_entries, vector const &value); + void check_hint_array(hint_array_damage::damage_visitor &visitor); private: unsigned width_;