Fix FakeBlockStore

This commit is contained in:
Sebastian Messmer 2015-04-15 14:51:41 +02:00
parent afce75b461
commit cc30dcde10
8 changed files with 30 additions and 15 deletions

View File

@ -80,6 +80,7 @@ void OnDiskBlock::RemoveFromDisk(const bf::path &rootdir, const Key &key) {
void OnDiskBlock::_fillDataWithZeroes() { void OnDiskBlock::_fillDataWithZeroes() {
_data.FillWithZeroes(); _data.FillWithZeroes();
_dataChanged = true;
} }
void OnDiskBlock::_storeToDisk() const { void OnDiskBlock::_storeToDisk() const {

View File

@ -14,8 +14,8 @@ using std::string;
namespace blockstore { namespace blockstore {
namespace testfake { namespace testfake {
FakeBlock::FakeBlock(FakeBlockStore *store, const Key &key, shared_ptr<Data> data) FakeBlock::FakeBlock(FakeBlockStore *store, const Key &key, shared_ptr<Data> data, bool dirty)
: Block(key), _store(store), _data(data), _dataChanged(false) { : Block(key), _store(store), _data(data), _dataChanged(dirty) {
} }
FakeBlock::~FakeBlock() { FakeBlock::~FakeBlock() {

View File

@ -13,7 +13,7 @@ class FakeBlockStore;
class FakeBlock: public Block { class FakeBlock: public Block {
public: public:
FakeBlock(FakeBlockStore *store, const Key &key, std::shared_ptr<Data> data); FakeBlock(FakeBlockStore *store, const Key &key, std::shared_ptr<Data> data, bool dirty);
virtual ~FakeBlock(); virtual ~FakeBlock();
const void *data() const override; const void *data() const override;

View File

@ -15,22 +15,19 @@ FakeBlockStore::FakeBlockStore()
: _blocks(), _used_dataregions_for_blocks() {} : _blocks(), _used_dataregions_for_blocks() {}
unique_ptr<Block> FakeBlockStore::create(const Key &key, size_t size) { unique_ptr<Block> FakeBlockStore::create(const Key &key, size_t size) {
auto insert_result = _blocks.emplace(key.ToString(), size); if (_blocks.find(key.ToString()) != _blocks.end()) {
insert_result.first->second.FillWithZeroes();
if (!insert_result.second) {
return nullptr; return nullptr;
} }
Data data(size);
//Return a copy of the stored data data.FillWithZeroes();
return load(key); return makeFakeBlockFromData(key, data, true);
} }
unique_ptr<Block> FakeBlockStore::load(const Key &key) { unique_ptr<Block> FakeBlockStore::load(const Key &key) {
//Return a copy of the stored data //Return a copy of the stored data
string key_string = key.ToString(); string key_string = key.ToString();
try { try {
return makeFakeBlockFromData(key, _blocks.at(key_string)); return makeFakeBlockFromData(key, _blocks.at(key_string), false);
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
return nullptr; return nullptr;
} }
@ -43,14 +40,20 @@ void FakeBlockStore::remove(unique_ptr<Block> block) {
assert(numRemoved == 1); assert(numRemoved == 1);
} }
unique_ptr<Block> FakeBlockStore::makeFakeBlockFromData(const Key &key, const Data &data) { unique_ptr<Block> FakeBlockStore::makeFakeBlockFromData(const Key &key, const Data &data, bool dirty) {
auto newdata = make_shared<Data>(data.copy()); auto newdata = make_shared<Data>(data.copy());
_used_dataregions_for_blocks.push_back(newdata); _used_dataregions_for_blocks.push_back(newdata);
return make_unique<FakeBlock>(this, key, newdata); return make_unique<FakeBlock>(this, key, newdata, dirty);
} }
void FakeBlockStore::updateData(const Key &key, const Data &data) { void FakeBlockStore::updateData(const Key &key, const Data &data) {
Data &stored_data = _blocks.at(key.ToString()); auto found = _blocks.find(key.ToString());
if (found == _blocks.end()) {
auto insertResult = _blocks.emplace(key.ToString(), data.size());
assert(true == insertResult.second);
found = insertResult.first;
}
Data &stored_data = found->second;
assert(data.size() == stored_data.size()); assert(data.size() == stored_data.size());
std::memcpy(stored_data.data(), data.data(), data.size()); std::memcpy(stored_data.data(), data.data(), data.size());
} }

View File

@ -48,7 +48,7 @@ private:
//We want to avoid this for the reasons mentioned above (overflow data). //We want to avoid this for the reasons mentioned above (overflow data).
std::vector<std::shared_ptr<Data>> _used_dataregions_for_blocks; std::vector<std::shared_ptr<Data>> _used_dataregions_for_blocks;
std::unique_ptr<Block> makeFakeBlockFromData(const Key &key, const Data &data); std::unique_ptr<Block> makeFakeBlockFromData(const Key &key, const Data &data, bool dirty);
DISALLOW_COPY_AND_ASSIGN(FakeBlockStore); DISALLOW_COPY_AND_ASSIGN(FakeBlockStore);
}; };

View File

@ -7,6 +7,9 @@
namespace blockstore { namespace blockstore {
//TODO Make Block non-virtual class that stores ptr to its blockstore and writes itself back to the blockstore who is offering a corresponding function.
// Then ondisk blockstore can be actually create the file on disk in blockstore::create() and cachingblockstore will delay that call to its base block store.
class Block { class Block {
public: public:
virtual ~Block() {} virtual ~Block() {}

View File

@ -36,6 +36,7 @@ TEST_F(OnDiskBlockCreateTest, CreatingBlockCreatesFile) {
EXPECT_FALSE(bf::exists(file.path())); EXPECT_FALSE(bf::exists(file.path()));
auto block = OnDiskBlock::CreateOnDisk(dir.path(), key, 0); auto block = OnDiskBlock::CreateOnDisk(dir.path(), key, 0);
block->flush();
EXPECT_TRUE(bf::exists(file.path())); EXPECT_TRUE(bf::exists(file.path()));
EXPECT_TRUE(bf::is_regular_file(file.path())); EXPECT_TRUE(bf::is_regular_file(file.path()));
@ -43,6 +44,7 @@ TEST_F(OnDiskBlockCreateTest, CreatingBlockCreatesFile) {
TEST_F(OnDiskBlockCreateTest, CreatingExistingBlockReturnsNull) { TEST_F(OnDiskBlockCreateTest, CreatingExistingBlockReturnsNull) {
auto block1 = OnDiskBlock::CreateOnDisk(dir.path(), key, 0); auto block1 = OnDiskBlock::CreateOnDisk(dir.path(), key, 0);
block1->flush();
auto block2 = OnDiskBlock::CreateOnDisk(dir.path(), key, 0); auto block2 = OnDiskBlock::CreateOnDisk(dir.path(), key, 0);
EXPECT_TRUE((bool)block1); EXPECT_TRUE((bool)block1);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);
@ -57,6 +59,7 @@ public:
block(OnDiskBlock::CreateOnDisk(dir.path(), key, GetParam())), block(OnDiskBlock::CreateOnDisk(dir.path(), key, GetParam())),
ZEROES(block->size()) ZEROES(block->size())
{ {
block->flush();
ZEROES.FillWithZeroes(); ZEROES.FillWithZeroes();
} }
}; };

View File

@ -32,6 +32,7 @@ TYPED_TEST_CASE_P(BlockStoreWithRandomKeysTest);
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSameSize) { TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSameSize) {
auto blockStore = this->fixture.createBlockStore(); auto blockStore = this->fixture.createBlockStore();
auto block = blockStore->create(this->key, 1024); auto block = blockStore->create(this->key, 1024);
block->flush();
auto block2 = blockStore->create(this->key, 1024); auto block2 = blockStore->create(this->key, 1024);
EXPECT_TRUE((bool)block); EXPECT_TRUE((bool)block);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);
@ -40,6 +41,7 @@ TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSameSize
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndDifferentSize) { TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndDifferentSize) {
auto blockStore = this->fixture.createBlockStore(); auto blockStore = this->fixture.createBlockStore();
auto block = blockStore->create(this->key, 1024); auto block = blockStore->create(this->key, 1024);
block->flush();
auto block2 = blockStore->create(this->key, 4096); auto block2 = blockStore->create(this->key, 4096);
EXPECT_TRUE((bool)block); EXPECT_TRUE((bool)block);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);
@ -48,6 +50,7 @@ TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndDifferen
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndFirstNullSize) { TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndFirstNullSize) {
auto blockStore = this->fixture.createBlockStore(); auto blockStore = this->fixture.createBlockStore();
auto block = blockStore->create(this->key, 0); auto block = blockStore->create(this->key, 0);
block->flush();
auto block2 = blockStore->create(this->key, 1024); auto block2 = blockStore->create(this->key, 1024);
EXPECT_TRUE((bool)block); EXPECT_TRUE((bool)block);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);
@ -56,6 +59,7 @@ TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndFirstNul
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSecondNullSize) { TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSecondNullSize) {
auto blockStore = this->fixture.createBlockStore(); auto blockStore = this->fixture.createBlockStore();
auto block = blockStore->create(this->key, 1024); auto block = blockStore->create(this->key, 1024);
block->flush();
auto block2 = blockStore->create(this->key, 0); auto block2 = blockStore->create(this->key, 0);
EXPECT_TRUE((bool)block); EXPECT_TRUE((bool)block);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);
@ -64,6 +68,7 @@ TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSecondNu
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndBothNullSize) { TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndBothNullSize) {
auto blockStore = this->fixture.createBlockStore(); auto blockStore = this->fixture.createBlockStore();
auto block = blockStore->create(this->key, 0); auto block = blockStore->create(this->key, 0);
block->flush();
auto block2 = blockStore->create(this->key, 0); auto block2 = blockStore->create(this->key, 0);
EXPECT_TRUE((bool)block); EXPECT_TRUE((bool)block);
EXPECT_FALSE((bool)block2); EXPECT_FALSE((bool)block2);