block_manager and unit test
This commit is contained in:
75
block.tcc
75
block.tcc
@@ -16,7 +16,7 @@ using namespace std;
|
||||
//----------------------------------------------------------------
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -36,7 +36,7 @@ block_manager<BlockSize>::read_ref::data() const
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -51,9 +51,10 @@ block_manager<BlockSize>::write_ref::data()
|
||||
//----------------------------------------------------------------
|
||||
|
||||
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)
|
||||
throw std::runtime_error("couldn't open file");
|
||||
}
|
||||
@@ -66,16 +67,18 @@ block_manager<BlockSize>::~block_manager()
|
||||
|
||||
template <uint32_t BlockSize>
|
||||
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);
|
||||
return read_ref(b);
|
||||
}
|
||||
|
||||
template <uint32_t BlockSize>
|
||||
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);
|
||||
}
|
||||
@@ -84,7 +87,9 @@ template <uint32_t BlockSize>
|
||||
typename block_manager<BlockSize>::write_ref
|
||||
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);
|
||||
return write_ref(b);
|
||||
}
|
||||
@@ -93,7 +98,9 @@ template <uint32_t BlockSize>
|
||||
typename block_manager<BlockSize>::write_ref
|
||||
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);
|
||||
return write_ref(b);
|
||||
}
|
||||
@@ -101,9 +108,11 @@ block_manager<BlockSize>::write_lock_zero(block_address location)
|
||||
template <uint32_t BlockSize>
|
||||
typename block_manager<BlockSize>::read_ref
|
||||
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);
|
||||
return read_ref(b);
|
||||
}
|
||||
@@ -111,7 +120,7 @@ block_manager<BlockSize>::read_lock(block_address location,
|
||||
template <uint32_t BlockSize>
|
||||
optional<typename block_manager<BlockSize>::read_ref>
|
||||
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);
|
||||
}
|
||||
@@ -119,9 +128,12 @@ block_manager<BlockSize>::read_try_lock(block_address location,
|
||||
template <uint32_t BlockSize>
|
||||
typename block_manager<BlockSize>::write_ref
|
||||
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);
|
||||
return write_ref(b);
|
||||
}
|
||||
@@ -129,9 +141,12 @@ block_manager<BlockSize>::write_lock(block_address location,
|
||||
template <uint32_t BlockSize>
|
||||
typename block_manager<BlockSize>::write_ref
|
||||
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);
|
||||
return write_ref(b);
|
||||
}
|
||||
@@ -140,16 +155,16 @@ template <uint32_t BlockSize>
|
||||
void
|
||||
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);
|
||||
::fsync(fd_);
|
||||
}
|
||||
|
||||
template <uint32_t BlockSize>
|
||||
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;
|
||||
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
||||
if (r == (off_t) -1)
|
||||
@@ -168,15 +183,14 @@ block_manager<BlockSize>::read_block(block &b)
|
||||
|
||||
if (n < 0)
|
||||
throw std::runtime_error("read failed");
|
||||
|
||||
b.initialised_ = true;
|
||||
}
|
||||
|
||||
template <uint32_t BlockSize>
|
||||
void
|
||||
block_manager<BlockSize>::write_block(block const &b)
|
||||
{
|
||||
|
||||
std::cerr << "writing block: " << b.location_ << std::endl;
|
||||
|
||||
off_t r;
|
||||
r = ::lseek(fd_, BlockSize * b.location_, SEEK_SET);
|
||||
if (r == (off_t) -1)
|
||||
@@ -202,14 +216,29 @@ void
|
||||
block_manager<BlockSize>::zero_block(block &b)
|
||||
{
|
||||
memset(b.data_, 0, BlockSize);
|
||||
b.initialised_ = true;
|
||||
}
|
||||
|
||||
template <uint32_t BlockSize>
|
||||
void
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user