[caching] hint support
This commit is contained in:
parent
2e58332e49
commit
17f7c982f2
@ -36,6 +36,7 @@ all: $(PROGRAMS)
|
|||||||
SOURCE=\
|
SOURCE=\
|
||||||
base/error_state.cc \
|
base/error_state.cc \
|
||||||
\
|
\
|
||||||
|
caching/hint_array.cc \
|
||||||
caching/superblock.cc \
|
caching/superblock.cc \
|
||||||
caching/mapping_array.cc \
|
caching/mapping_array.cc \
|
||||||
caching/metadata.cc \
|
caching/metadata.cc \
|
||||||
@ -236,6 +237,7 @@ CACHE_CHECK_SOURCE=\
|
|||||||
persistent-data/space-maps/recursive.cc \
|
persistent-data/space-maps/recursive.cc \
|
||||||
persistent-data/space-maps/careful_alloc.cc \
|
persistent-data/space-maps/careful_alloc.cc \
|
||||||
persistent-data/transaction_manager.cc \
|
persistent-data/transaction_manager.cc \
|
||||||
|
caching/hint_array.cc \
|
||||||
caching/superblock.cc \
|
caching/superblock.cc \
|
||||||
caching/mapping_array.cc \
|
caching/mapping_array.cc \
|
||||||
caching/metadata.cc \
|
caching/metadata.cc \
|
||||||
|
147
caching/hint_array.cc
Normal file
147
caching/hint_array.cc
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#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 <uint32_t WIDTH>
|
||||||
|
shared_ptr<array_base> mk_array(transaction_manager::ptr tm) {
|
||||||
|
typedef hint_traits<WIDTH> traits;
|
||||||
|
typedef array<traits> ha;
|
||||||
|
|
||||||
|
shared_ptr<array_base> r = typename ha::ptr(new ha(tm, typename traits::ref_counter()));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<array_base> mk_array(transaction_manager::ptr tm, uint32_t width) {
|
||||||
|
switch (width) {
|
||||||
|
#define xx(n) case n: return mk_array<n>(tm)
|
||||||
|
|
||||||
|
all_widths
|
||||||
|
#undef xx
|
||||||
|
}
|
||||||
|
|
||||||
|
// never get here
|
||||||
|
return shared_ptr<array_base>();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
template <uint32_t WIDTH>
|
||||||
|
shared_ptr<array_base> mk_array(transaction_manager::ptr tm, block_address root, unsigned nr_entries) {
|
||||||
|
typedef hint_traits<WIDTH> traits;
|
||||||
|
typedef array<traits> ha;
|
||||||
|
|
||||||
|
shared_ptr<array_base> r = typename ha::ptr(new ha(tm, typename traits::ref_counter(), root, nr_entries));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<array_base> 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<n>(tm, root, nr_entries)
|
||||||
|
all_widths
|
||||||
|
#undef xx
|
||||||
|
}
|
||||||
|
|
||||||
|
// never get here
|
||||||
|
return shared_ptr<array_base>();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
template <uint32_t WIDTH>
|
||||||
|
void get_hint(shared_ptr<array_base> base, unsigned index, vector<unsigned char> &data) {
|
||||||
|
typedef hint_traits<WIDTH> traits;
|
||||||
|
typedef array<traits> ha;
|
||||||
|
|
||||||
|
shared_ptr<ha> a = dynamic_pointer_cast<ha>(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<array_base> base, unsigned index, vector<unsigned char> &data) {
|
||||||
|
switch (width) {
|
||||||
|
#define xx(n) case n: return get_hint<n>(base, index, data)
|
||||||
|
all_widths
|
||||||
|
#undef xx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
template <uint32_t WIDTH>
|
||||||
|
void set_hint(shared_ptr<array_base> base, unsigned index, vector<unsigned char> const &data) {
|
||||||
|
typedef hint_traits<WIDTH> traits;
|
||||||
|
typedef array<traits> ha;
|
||||||
|
|
||||||
|
shared_ptr<ha> a = dynamic_pointer_cast<ha>(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<array_base> base,
|
||||||
|
unsigned index, vector<unsigned char> const &data) {
|
||||||
|
switch (width) {
|
||||||
|
#define xx(n) case n: return set_hint<n>(base, index, data)
|
||||||
|
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<unsigned char> &data) const
|
||||||
|
{
|
||||||
|
get_hint_(width_, impl_, index, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hint_array::set_hint(unsigned index, vector<unsigned char> const &data)
|
||||||
|
{
|
||||||
|
set_hint_(width_, impl_, index, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
@ -13,22 +13,44 @@ namespace caching {
|
|||||||
struct hint_traits {
|
struct hint_traits {
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef byte disk_type[WIDTH];
|
typedef byte disk_type[WIDTH];
|
||||||
typedef byte value_type[WIDTH];
|
typedef vector<byte> value_type;
|
||||||
typedef no_op_ref_counter<value_type> ref_counter;
|
typedef no_op_ref_counter<value_type> ref_counter;
|
||||||
|
|
||||||
|
// FIXME: slow copying for now
|
||||||
static void unpack(disk_type const &disk, value_type &value) {
|
static void unpack(disk_type const &disk, value_type &value) {
|
||||||
::memcpy(value, disk, sizeof(value));
|
for (unsigned byte = 0; byte < WIDTH; byte++)
|
||||||
|
value[byte] = disk[byte];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pack(value_type const &value, disk_type &disk) {
|
static void pack(value_type const &value, disk_type &disk) {
|
||||||
::memcpy(disk, value, sizeof(disk));
|
for (unsigned byte = 0; byte < WIDTH; byte++)
|
||||||
|
disk[byte] = value[byte];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: data visitor stuff
|
// FIXME: data visitor stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef persistent_data::array<mapping_array_detail::hint_traits> hint_array;
|
class hint_array {
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<hint_array> ptr;
|
||||||
|
typedef typename persistent_data::transaction_manager::ptr tm_ptr;
|
||||||
|
|
||||||
|
hint_array(tm_ptr tm, unsigned width);
|
||||||
|
hint_array(tm_ptr tm, unsigned width, block_address root, unsigned nr_entries);
|
||||||
|
|
||||||
|
unsigned get_nr_entries() const;
|
||||||
|
|
||||||
|
void grow(unsigned new_nr_entries, void const *v);
|
||||||
|
|
||||||
|
block_address get_root() const;
|
||||||
|
void get_hint(unsigned index, vector<unsigned char> &data) const;
|
||||||
|
void set_hint(unsigned index, vector<unsigned char> const &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned width_;
|
||||||
|
boost::shared_ptr<persistent_data::array_base> impl_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
@ -53,6 +53,7 @@ metadata::commit()
|
|||||||
{
|
{
|
||||||
commit_space_map();
|
commit_space_map();
|
||||||
commit_mappings();
|
commit_mappings();
|
||||||
|
commit_hints();
|
||||||
commit_superblock();
|
commit_superblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +114,12 @@ metadata::commit_mappings()
|
|||||||
sb_.mapping_root = mappings_->get_root();
|
sb_.mapping_root = mappings_->get_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
metadata::commit_hints()
|
||||||
|
{
|
||||||
|
sb_.hint_root = hints_->get_root();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
metadata::commit_superblock()
|
metadata::commit_superblock()
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace caching {
|
|||||||
superblock_detail::superblock sb_;
|
superblock_detail::superblock sb_;
|
||||||
checked_space_map::ptr metadata_sm_;
|
checked_space_map::ptr metadata_sm_;
|
||||||
mapping_array::ptr mappings_;
|
mapping_array::ptr mappings_;
|
||||||
//hint_array::ptr hints_;
|
hint_array::ptr hints_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init_superblock();
|
void init_superblock();
|
||||||
@ -44,6 +44,7 @@ namespace caching {
|
|||||||
|
|
||||||
void commit_space_map();
|
void commit_space_map();
|
||||||
void commit_mappings();
|
void commit_mappings();
|
||||||
|
void commit_hints();
|
||||||
void commit_superblock();
|
void commit_superblock();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -67,8 +67,15 @@ namespace persistent_data {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class array_base {
|
||||||
|
public:
|
||||||
|
virtual ~array_base() {}
|
||||||
|
virtual void set_root(block_address root) = 0;
|
||||||
|
virtual block_address get_root() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ValueTraits>
|
template <typename ValueTraits>
|
||||||
class array {
|
class array : public array_base {
|
||||||
public:
|
public:
|
||||||
class block_ref_counter : public ref_counter<uint64_t> {
|
class block_ref_counter : public ref_counter<uint64_t> {
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user