#include "caching/hint_array.h" using namespace boost; using namespace caching; using namespace persistent_data; //---------------------------------------------------------------- namespace { using namespace caching::hint_array_detail; // We've got into a bit of a mess here. Templates are compile // time, and we don't know the hint width until run time. We're // going to have to provide specialisation for all legal widths and // use the appropriate one. #define all_widths \ xx(4); xx(8); xx(12); xx(16); xx(20); xx(24); xx(28); xx(32);\ xx(36); xx(40); xx(44); xx(48); xx(52); xx(56); xx(60); xx(64); \ xx(68); xx(72); xx(76); xx(80); xx(84); xx(88); xx(92); xx(96); \ xx(100); xx(104); xx(108); xx(112); xx(116); xx(120); xx(124); xx(128); template shared_ptr mk_array(transaction_manager::ptr tm) { typedef hint_traits traits; typedef array ha; shared_ptr r = typename ha::ptr(new ha(tm, typename traits::ref_counter())); return r; } shared_ptr mk_array(transaction_manager::ptr tm, uint32_t width) { switch (width) { #define xx(n) case n: return mk_array(tm) all_widths #undef xx } // never get here return shared_ptr(); } //-------------------------------- template shared_ptr mk_array(transaction_manager::ptr tm, block_address root, unsigned nr_entries) { typedef hint_traits traits; typedef array ha; shared_ptr r = typename ha::ptr(new ha(tm, typename traits::ref_counter(), root, nr_entries)); return r; } shared_ptr mk_array(transaction_manager::ptr tm, uint32_t width, block_address root, unsigned nr_entries) { switch (width) { #define xx(n) case n: return mk_array(tm, root, nr_entries) all_widths #undef xx } // never get here return shared_ptr(); } //-------------------------------- template void get_hint(shared_ptr base, unsigned index, vector &data) { 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"); data = a->get(index); } void get_hint_(uint32_t width, shared_ptr base, unsigned index, vector &data) { switch (width) { #define xx(n) case n: return get_hint(base, index, data) all_widths #undef xx } } //-------------------------------- template void set_hint(shared_ptr base, unsigned index, vector const &data) { 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"); a->set(index, data); } void set_hint_(uint32_t width, shared_ptr base, unsigned index, vector const &data) { switch (width) { #define xx(n) case n: return set_hint(base, index, data) all_widths #undef xx } } //-------------------------------- template void grow(shared_ptr base, unsigned new_nr_entries, vector const &value) { 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"); a->grow(new_nr_entries, value); } void grow_(uint32_t width, shared_ptr base, unsigned new_nr_entries, vector const &value) { switch (width) { #define xx(n) case n: return grow(base, new_nr_entries, value) all_widths #undef xx } } } //---------------------------------------------------------------- hint_array::hint_array(tm_ptr tm, unsigned width) : width_(width), impl_(mk_array(tm, width)) { } hint_array::hint_array(typename hint_array::tm_ptr tm, unsigned width, block_address root, unsigned nr_entries) : width_(width), impl_(mk_array(tm, width, root, nr_entries)) { } block_address hint_array::get_root() const { return impl_->get_root(); } void hint_array::get_hint(unsigned index, vector &data) const { get_hint_(width_, impl_, index, data); } void hint_array::set_hint(unsigned index, vector const &data) { set_hint_(width_, impl_, index, data); } void hint_array::grow(unsigned new_nr_entries, vector const &value) { grow_(width_, impl_, new_nr_entries, value); } //----------------------------------------------------------------