[block] always use a validator, but default to a noop one

This commit is contained in:
Joe Thornber 2011-08-31 13:18:28 +01:00
parent 9cfdbfb8cc
commit 6d37d86d55
2 changed files with 23 additions and 113 deletions

47
block.h
View File

@ -57,16 +57,21 @@ namespace persistent_data {
virtual void prepare(block &b) const = 0;
};
class noop_validator : public validator {
public:
void check(block const &b) const {}
void prepare(block &b) const {}
};
struct block {
typedef boost::shared_ptr<block> ptr;
typedef boost::optional<typename validator::ptr> maybe_validator;
block(block_address location,
const_buffer &data,
unsigned &count,
unsigned &type_count,
bool is_superblock = false,
maybe_validator v = maybe_validator())
bool is_superblock, // FIXME: make this an enum
typename validator::ptr v)
: location_(location),
adjuster_(count),
type_adjuster_(type_count),
@ -79,7 +84,7 @@ namespace persistent_data {
count_adjuster adjuster_;
count_adjuster type_adjuster_;
buffer data_;
maybe_validator validator_;
typename validator::ptr validator_;
bool is_superblock_;
};
@ -108,33 +113,24 @@ namespace persistent_data {
// Locking methods
read_ref
read_lock(block_address location) const;
boost::optional<read_ref>
read_try_lock(block_address location) const;
write_ref
write_lock(block_address location);
write_ref
write_lock_zero(block_address location);
// Validator variants
read_ref
read_lock(block_address location,
typename validator::ptr v) const;
typename validator::ptr v =
typename validator::ptr(new noop_validator())) const;
boost::optional<read_ref>
read_try_lock(block_address location,
typename validator::ptr v) const;
typename validator::ptr v =
typename validator::ptr(new noop_validator())) const;
write_ref
write_lock(block_address location,
typename validator::ptr v);
typename validator::ptr v =
typename validator::ptr(new noop_validator()));
write_ref
write_lock_zero(block_address location,
typename validator::ptr v);
typename validator::ptr v =
typename validator::ptr(new noop_validator()));
// The super block is the one that should be written last.
// Unlocking this block triggers the following events:
@ -146,16 +142,17 @@ namespace persistent_data {
//
// If any locks are held at the time of the superblock
// being unlocked then an exception will be thrown.
write_ref superblock(block_address b);
write_ref superblock_zero(block_address b);
write_ref superblock(block_address b,
typename validator::ptr v);
typename validator::ptr v =
typename validator::ptr(new noop_validator()));
write_ref superblock_zero(block_address b,
typename validator::ptr v);
typename validator::ptr v =
typename validator::ptr(new noop_validator()));
// If you aren't using a superblock, then this flush method
// will write all dirty data. Throws if any locks are
// held.
// FIXME: do we need this?
void flush();
block_address get_nr_blocks() const;

View File

@ -68,58 +68,6 @@ block_manager<BlockSize>::~block_manager()
::close(fd_);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::read_ref
block_manager<BlockSize>::read_lock(block_address location) const
{
check(location);
buffer buf;
read_buffer(location, buf);
register_lock(location, READ_LOCK);
return read_ref(
typename block::ptr(
new block(location, buf, lock_count_, ordinary_count_),
bind(&block_manager::read_release, this, _1)));
}
template <uint32_t BlockSize>
optional<typename block_manager<BlockSize>::read_ref>
block_manager<BlockSize>::read_try_lock(block_address location) const
{
return read_lock(location);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::write_lock(block_address location)
{
check(location);
buffer buf;
read_buffer(location, buf);
register_lock(location, WRITE_LOCK);
return write_ref(
typename block::ptr(
new block(location, buf, lock_count_, ordinary_count_),
bind(&block_manager::write_release, this, _1)));
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::write_lock_zero(block_address location)
{
check(location);
buffer buf;
zero_buffer(buf);
register_lock(location, WRITE_LOCK);
typename block::ptr b(new block(location, buf, lock_count_, ordinary_count_),
bind(&block_manager<BlockSize>::write_release, this, _1));
return write_ref(b);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::read_ref
block_manager<BlockSize>::read_lock(block_address location,
@ -173,40 +121,6 @@ block_manager<BlockSize>::write_lock_zero(block_address location,
return write_ref(b);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::superblock(block_address location)
{
check(location);
if (superblock_count_ > 0)
throw runtime_error("already have superblock");
buffer buf;
read_buffer(location, buf);
typename block::ptr b(new block(location, buf, lock_count_, superblock_count_, true),
bind(&block_manager::write_release, this, _1));
register_lock(location, WRITE_LOCK);
return write_ref(b);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::superblock_zero(block_address location)
{
check(location);
if (superblock_count_ > 0)
throw runtime_error("already have superblock");
buffer buf;
zero_buffer(buf);
typename block::ptr b(new block(location, buf, lock_count_, superblock_count_, true),
bind(&block_manager::write_release, this, _1));
register_lock(location, WRITE_LOCK);
return write_ref(b);
}
template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::superblock(block_address location,
@ -325,8 +239,7 @@ block_manager<BlockSize>::write_release(block *b)
throw runtime_error("superblock isn't the last block");
}
if (b->validator_)
(*b->validator_)->prepare(*b);
b->validator_->prepare(*b);
write_buffer(b->location_, b->data_);
unregister_lock(b->location_, WRITE_LOCK);