block_manager and unit test
This commit is contained in:
parent
c090bb88b5
commit
8a7f0214d3
12
Makefile
12
Makefile
@ -1,7 +1,9 @@
|
|||||||
SOURCE=\
|
SOURCE=\
|
||||||
main.cc \
|
|
||||||
metadata.cc
|
metadata.cc
|
||||||
|
|
||||||
|
PROGRAM_SOURCE=\
|
||||||
|
block_t.cc
|
||||||
|
|
||||||
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
||||||
CPPFLAGS=-Wall -std=c++0x
|
CPPFLAGS=-Wall -std=c++0x
|
||||||
INCLUDES=
|
INCLUDES=
|
||||||
@ -17,7 +19,11 @@ LIBS=-lstdc++
|
|||||||
.cc.o:
|
.cc.o:
|
||||||
g++ -c $(CPPFLAGS) $(INCLUDES) -o $@ $<
|
g++ -c $(CPPFLAGS) $(INCLUDES) -o $@ $<
|
||||||
|
|
||||||
multisnap_display: $(OBJECTS)
|
multisnap_display: $(OBJECTS) main.o
|
||||||
g++ -o $@ $+ $(LIBS)
|
g++ -o $@ $+ $(LIBS)
|
||||||
|
|
||||||
include $(subst .cc,.d,$(SOURCE))
|
block_t: block_t.o
|
||||||
|
g++ -o $@ $+ $(LIBS)
|
||||||
|
|
||||||
|
include $(subst .cc,.d,$(SOURCE))
|
||||||
|
include $(subst .cc,.d,$(PROGRAM_SOURCE))
|
40
block.h
40
block.h
@ -20,7 +20,7 @@ namespace persistent_data {
|
|||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<block_manager> ptr;
|
typedef boost::shared_ptr<block_manager> ptr;
|
||||||
|
|
||||||
block_manager(std::string const &path);
|
block_manager(std::string const &path, block_address nr_blocks);
|
||||||
~block_manager();
|
~block_manager();
|
||||||
|
|
||||||
typedef unsigned char buffer[BlockSize];
|
typedef unsigned char buffer[BlockSize];
|
||||||
@ -28,48 +28,50 @@ namespace persistent_data {
|
|||||||
|
|
||||||
class block;
|
class block;
|
||||||
|
|
||||||
class block_validator {
|
class validator {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<block_validator> ptr;
|
typedef boost::shared_ptr<validator> ptr;
|
||||||
|
|
||||||
virtual ~block_validator() {}
|
virtual ~validator() {}
|
||||||
|
|
||||||
virtual void check(block const &b) const = 0;
|
virtual void check(block const &b) const = 0;
|
||||||
virtual void prepare(block &b) const = 0;
|
virtual void prepare(block &b) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct block {
|
struct block {
|
||||||
typedef boost::optional<typename block_validator::ptr> maybe_validator;
|
typedef boost::shared_ptr<block> ptr;
|
||||||
|
typedef boost::optional<typename validator::ptr> maybe_validator;
|
||||||
|
|
||||||
block(block_address location,
|
block(block_address location,
|
||||||
maybe_validator v = maybe_validator())
|
maybe_validator v = maybe_validator())
|
||||||
: location_(location),
|
: location_(location),
|
||||||
validator_(v) {
|
validator_(v),
|
||||||
|
initialised_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
block_address location_;
|
block_address location_;
|
||||||
buffer data_;
|
buffer data_;
|
||||||
maybe_validator validator_;
|
maybe_validator validator_;
|
||||||
|
bool initialised_;
|
||||||
};
|
};
|
||||||
typedef boost::shared_ptr<block> block_ptr;
|
|
||||||
|
|
||||||
class read_ref {
|
class read_ref {
|
||||||
public:
|
public:
|
||||||
read_ref(block_ptr b);
|
read_ref(typename block::ptr b);
|
||||||
virtual ~read_ref() {}
|
virtual ~read_ref() {}
|
||||||
|
|
||||||
block_address get_location() const;
|
block_address get_location() const;
|
||||||
const_buffer &data() const;
|
const_buffer &data() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
block_ptr block_;
|
typename block::ptr block_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inherited from read_ref, since you can read a block that's write
|
// Inherited from read_ref, since you can read a block that's write
|
||||||
// locked.
|
// locked.
|
||||||
class write_ref : public read_ref {
|
class write_ref : public read_ref {
|
||||||
public:
|
public:
|
||||||
write_ref(block_ptr b);
|
write_ref(typename block::ptr b);
|
||||||
|
|
||||||
using read_ref::data;
|
using read_ref::data;
|
||||||
buffer &data();
|
buffer &data();
|
||||||
@ -77,10 +79,10 @@ namespace persistent_data {
|
|||||||
|
|
||||||
// Locking methods
|
// Locking methods
|
||||||
read_ref
|
read_ref
|
||||||
read_lock(block_address location);
|
read_lock(block_address location) const;
|
||||||
|
|
||||||
boost::optional<read_ref>
|
boost::optional<read_ref>
|
||||||
read_try_lock(block_address location);
|
read_try_lock(block_address location) const;
|
||||||
|
|
||||||
write_ref
|
write_ref
|
||||||
write_lock(block_address location);
|
write_lock(block_address location);
|
||||||
@ -91,31 +93,33 @@ namespace persistent_data {
|
|||||||
// Validator variants
|
// Validator variants
|
||||||
read_ref
|
read_ref
|
||||||
read_lock(block_address location,
|
read_lock(block_address location,
|
||||||
typename block_validator::ptr const &v);
|
typename validator::ptr const &v) const;
|
||||||
|
|
||||||
boost::optional<read_ref>
|
boost::optional<read_ref>
|
||||||
read_try_lock(block_address location,
|
read_try_lock(block_address location,
|
||||||
typename block_validator::ptr const &v);
|
typename validator::ptr const &v) const;
|
||||||
|
|
||||||
write_ref
|
write_ref
|
||||||
write_lock(block_address location,
|
write_lock(block_address location,
|
||||||
typename block_validator::ptr const &v);
|
typename validator::ptr const &v);
|
||||||
|
|
||||||
write_ref
|
write_ref
|
||||||
write_lock_zero(block_address location,
|
write_lock_zero(block_address location,
|
||||||
typename block_validator::ptr const &v);
|
typename validator::ptr const &v);
|
||||||
|
|
||||||
// Use this to commit changes
|
// Use this to commit changes
|
||||||
void flush(write_ref super_block);
|
void flush(write_ref super_block);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void read_block(block &b);
|
void check(block_address b) const;
|
||||||
|
|
||||||
|
void read_block(block &b) const;
|
||||||
void write_block(block const &b);
|
void write_block(block const &b);
|
||||||
void zero_block(block &b);
|
void zero_block(block &b);
|
||||||
|
|
||||||
void write_and_release(block *b);
|
void write_and_release(block *b);
|
||||||
|
|
||||||
int fd_;
|
int fd_;
|
||||||
|
block_address nr_blocks_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
block.tcc
75
block.tcc
@ -16,7 +16,7 @@ using namespace std;
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
block_manager<BlockSize>::read_ref::read_ref(block_manager::block_ptr b)
|
block_manager<BlockSize>::read_ref::read_ref(typename block_manager::block::ptr b)
|
||||||
: block_(b)
|
: block_(b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ block_manager<BlockSize>::read_ref::data() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
block_manager<BlockSize>::write_ref::write_ref(block_manager::block_ptr b)
|
block_manager<BlockSize>::write_ref::write_ref(typename block_manager::block::ptr b)
|
||||||
: read_ref(b)
|
: read_ref(b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -51,9 +51,10 @@ block_manager<BlockSize>::write_ref::data()
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
block_manager<BlockSize>::block_manager(std::string const &path)
|
block_manager<BlockSize>::block_manager(std::string const &path, block_address nr_blocks)
|
||||||
|
: nr_blocks_(nr_blocks)
|
||||||
{
|
{
|
||||||
fd_ = ::open(path.c_str(), O_RDWR | O_EXCL);
|
fd_ = ::open(path.c_str(), O_RDWR | O_CREAT, 0666);
|
||||||
if (fd_ < 0)
|
if (fd_ < 0)
|
||||||
throw std::runtime_error("couldn't open file");
|
throw std::runtime_error("couldn't open file");
|
||||||
}
|
}
|
||||||
@ -66,16 +67,18 @@ block_manager<BlockSize>::~block_manager()
|
|||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
typename block_manager<BlockSize>::read_ref
|
typename block_manager<BlockSize>::read_ref
|
||||||
block_manager<BlockSize>::read_lock(block_address location)
|
block_manager<BlockSize>::read_lock(block_address location) const
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location));
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location));
|
||||||
read_block(*b);
|
read_block(*b);
|
||||||
return read_ref(b);
|
return read_ref(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
optional<typename block_manager<BlockSize>::read_ref>
|
optional<typename block_manager<BlockSize>::read_ref>
|
||||||
block_manager<BlockSize>::read_try_lock(block_address location)
|
block_manager<BlockSize>::read_try_lock(block_address location) const
|
||||||
{
|
{
|
||||||
return read_lock(location);
|
return read_lock(location);
|
||||||
}
|
}
|
||||||
@ -84,7 +87,9 @@ template <uint32_t BlockSize>
|
|||||||
typename block_manager<BlockSize>::write_ref
|
typename block_manager<BlockSize>::write_ref
|
||||||
block_manager<BlockSize>::write_lock(block_address location)
|
block_manager<BlockSize>::write_lock(block_address location)
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location), bind(&block_manager::write_and_release, this, _1));
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location), bind(&block_manager::write_and_release, this, _1));
|
||||||
read_block(*b);
|
read_block(*b);
|
||||||
return write_ref(b);
|
return write_ref(b);
|
||||||
}
|
}
|
||||||
@ -93,7 +98,9 @@ template <uint32_t BlockSize>
|
|||||||
typename block_manager<BlockSize>::write_ref
|
typename block_manager<BlockSize>::write_ref
|
||||||
block_manager<BlockSize>::write_lock_zero(block_address location)
|
block_manager<BlockSize>::write_lock_zero(block_address location)
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location), bind(&block_manager<BlockSize>::write_and_release, this, _1));
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location), bind(&block_manager<BlockSize>::write_and_release, this, _1));
|
||||||
zero_block(*b);
|
zero_block(*b);
|
||||||
return write_ref(b);
|
return write_ref(b);
|
||||||
}
|
}
|
||||||
@ -101,9 +108,11 @@ block_manager<BlockSize>::write_lock_zero(block_address location)
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
typename block_manager<BlockSize>::read_ref
|
typename block_manager<BlockSize>::read_ref
|
||||||
block_manager<BlockSize>::read_lock(block_address location,
|
block_manager<BlockSize>::read_lock(block_address location,
|
||||||
typename block_manager<BlockSize>::block_validator::ptr const &v)
|
typename block_manager<BlockSize>::validator::ptr const &v) const
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location, v));
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location, v));
|
||||||
read_block(*b);
|
read_block(*b);
|
||||||
return read_ref(b);
|
return read_ref(b);
|
||||||
}
|
}
|
||||||
@ -111,7 +120,7 @@ block_manager<BlockSize>::read_lock(block_address location,
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
optional<typename block_manager<BlockSize>::read_ref>
|
optional<typename block_manager<BlockSize>::read_ref>
|
||||||
block_manager<BlockSize>::read_try_lock(block_address location,
|
block_manager<BlockSize>::read_try_lock(block_address location,
|
||||||
typename block_manager<BlockSize>::block_validator::ptr const &v)
|
typename block_manager<BlockSize>::validator::ptr const &v) const
|
||||||
{
|
{
|
||||||
return read_lock(location, v);
|
return read_lock(location, v);
|
||||||
}
|
}
|
||||||
@ -119,9 +128,12 @@ block_manager<BlockSize>::read_try_lock(block_address location,
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
typename block_manager<BlockSize>::write_ref
|
typename block_manager<BlockSize>::write_ref
|
||||||
block_manager<BlockSize>::write_lock(block_address location,
|
block_manager<BlockSize>::write_lock(block_address location,
|
||||||
typename block_manager<BlockSize>::block_validator::ptr const &v)
|
typename block_manager<BlockSize>::validator::ptr const &v)
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location, v), write_and_release);
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location, v),
|
||||||
|
bind(&block_manager::write_and_release, this, _1));
|
||||||
read_block(*b);
|
read_block(*b);
|
||||||
return write_ref(b);
|
return write_ref(b);
|
||||||
}
|
}
|
||||||
@ -129,9 +141,12 @@ block_manager<BlockSize>::write_lock(block_address location,
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
typename block_manager<BlockSize>::write_ref
|
typename block_manager<BlockSize>::write_ref
|
||||||
block_manager<BlockSize>::write_lock_zero(block_address location,
|
block_manager<BlockSize>::write_lock_zero(block_address location,
|
||||||
typename block_manager<BlockSize>::block_validator::ptr const &v)
|
typename block_manager<BlockSize>::validator::ptr const &v)
|
||||||
{
|
{
|
||||||
block_ptr b(new block(location, v), write_and_release);
|
check(location);
|
||||||
|
|
||||||
|
typename block::ptr b(new block(location, v),
|
||||||
|
bind(&block_manager::write_and_release, this, _1));
|
||||||
zero_block(*b);
|
zero_block(*b);
|
||||||
return write_ref(b);
|
return write_ref(b);
|
||||||
}
|
}
|
||||||
@ -140,16 +155,16 @@ template <uint32_t BlockSize>
|
|||||||
void
|
void
|
||||||
block_manager<BlockSize>::flush(block_manager<BlockSize>::write_ref super_block)
|
block_manager<BlockSize>::flush(block_manager<BlockSize>::write_ref super_block)
|
||||||
{
|
{
|
||||||
|
// FIXME: the caller still holds the write_ref, so the superblock
|
||||||
|
// will get written twice
|
||||||
write_block(super_block);
|
write_block(super_block);
|
||||||
::fsync(fd_);
|
::fsync(fd_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
void
|
void
|
||||||
block_manager<BlockSize>::read_block(block &b)
|
block_manager<BlockSize>::read_block(block &b) const
|
||||||
{
|
{
|
||||||
std::cerr << "reading block: " << b.location_ << std::endl;
|
|
||||||
|
|
||||||
off_t r;
|
off_t r;
|
||||||
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
||||||
if (r == (off_t) -1)
|
if (r == (off_t) -1)
|
||||||
@ -168,15 +183,14 @@ block_manager<BlockSize>::read_block(block &b)
|
|||||||
|
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
throw std::runtime_error("read failed");
|
throw std::runtime_error("read failed");
|
||||||
|
|
||||||
|
b.initialised_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
void
|
void
|
||||||
block_manager<BlockSize>::write_block(block const &b)
|
block_manager<BlockSize>::write_block(block const &b)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::cerr << "writing block: " << b.location_ << std::endl;
|
|
||||||
|
|
||||||
off_t r;
|
off_t r;
|
||||||
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
||||||
if (r == (off_t) -1)
|
if (r == (off_t) -1)
|
||||||
@ -202,14 +216,29 @@ void
|
|||||||
block_manager<BlockSize>::zero_block(block &b)
|
block_manager<BlockSize>::zero_block(block &b)
|
||||||
{
|
{
|
||||||
memset(b.data_, 0, BlockSize);
|
memset(b.data_, 0, BlockSize);
|
||||||
|
b.initialised_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
void
|
void
|
||||||
block_manager<BlockSize>::write_and_release(block *b)
|
block_manager<BlockSize>::write_and_release(block *b)
|
||||||
{
|
{
|
||||||
write_block(*b);
|
if (b->initialised_) {
|
||||||
|
if (b->validator_)
|
||||||
|
(*b->validator_)->prepare(*b);
|
||||||
|
|
||||||
|
write_block(*b);
|
||||||
|
}
|
||||||
|
|
||||||
delete b;
|
delete b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
void
|
||||||
|
block_manager<BlockSize>::check(block_address b) const
|
||||||
|
{
|
||||||
|
if (b >= nr_blocks_)
|
||||||
|
throw std::runtime_error("block address out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
125
block_t.cc
Normal file
125
block_t.cc
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "block.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define BOOST_TEST_MODULE BlockManagerTests
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
void check_all_bytes(typename block_manager<BlockSize>::read_ref const &rr, int v) {
|
||||||
|
auto data = rr.data();
|
||||||
|
for (unsigned b = 0; b < BlockSize; b++)
|
||||||
|
BOOST_CHECK_EQUAL(data[b], v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
class zero_validator : public block_manager<BlockSize>::validator {
|
||||||
|
void check(block_manager<4096>::block const &blk) const {
|
||||||
|
for (unsigned b = 0; b < BlockSize; b++)
|
||||||
|
if (blk.data_[b] != 0)
|
||||||
|
throw runtime_error("validator check zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare(block_manager<4096>::block &blk) const {
|
||||||
|
for (unsigned b = 0; b < BlockSize; b++)
|
||||||
|
blk.data_[b] = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(bad_path)
|
||||||
|
{
|
||||||
|
BOOST_CHECK_THROW(block_manager<4096>("/bogus/bogus/bogus", 1234), runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(out_of_range_access)
|
||||||
|
{
|
||||||
|
block_manager<4096> bm("./test.data", 1024);
|
||||||
|
BOOST_CHECK_THROW(bm.read_lock(1024), runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(read_lock_all_blocks)
|
||||||
|
{
|
||||||
|
block_address const nr = 64;
|
||||||
|
block_manager<4096> bm("./test.data", nr);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nr; i++)
|
||||||
|
bm.read_lock(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(write_lock_all_blocks)
|
||||||
|
{
|
||||||
|
block_address const nr = 64;
|
||||||
|
block_manager<4096> bm("./test.data", nr);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nr; i++)
|
||||||
|
bm.write_lock(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(writes_persist)
|
||||||
|
{
|
||||||
|
block_address const nr = 64;
|
||||||
|
block_manager<4096> bm("./test.data", nr);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nr; i++) {
|
||||||
|
auto wr = bm.write_lock(i);
|
||||||
|
::memset(wr.data(), i, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nr; i++) {
|
||||||
|
auto rr = bm.read_lock(i);
|
||||||
|
check_all_bytes<4096>(rr, i % 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(write_lock_zero_zeroes)
|
||||||
|
{
|
||||||
|
block_address const nr = 64;
|
||||||
|
block_manager<4096> bm("./test.data", nr);
|
||||||
|
check_all_bytes<4096>(bm.write_lock_zero(23), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(different_block_sizes)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
block_manager<4096> bm("./test.data", 64);
|
||||||
|
auto rr = bm.read_lock(0);
|
||||||
|
BOOST_CHECK_EQUAL(sizeof(rr.data()), 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
block_manager<64 * 1024> bm("./test.data", 64);
|
||||||
|
auto rr = bm.read_lock(0);
|
||||||
|
BOOST_CHECK_EQUAL(sizeof(rr.data()), 64 * 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(read_validator_works)
|
||||||
|
{
|
||||||
|
typename block_manager<4096>::block_manager::validator::ptr v(new zero_validator<4096>());
|
||||||
|
block_manager<4096> bm("./test.data", 64);
|
||||||
|
bm.write_lock_zero(0);
|
||||||
|
bm.read_lock(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(write_validator_works)
|
||||||
|
{
|
||||||
|
typename block_manager<4096>::block_manager::validator::ptr v(new zero_validator<4096>());
|
||||||
|
block_manager<4096> bm("./test.data", 64);
|
||||||
|
{
|
||||||
|
auto wr = bm.write_lock(0, v);
|
||||||
|
::memset(wr.data(), 23, sizeof(wr.data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
check_all_bytes<4096>(bm.read_lock(0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user