diff --git a/implementations/inmemory/InMemoryBlockStore.cpp b/implementations/inmemory/InMemoryBlockStore.cpp index feea58dd..c49d8c4c 100644 --- a/implementations/inmemory/InMemoryBlockStore.cpp +++ b/implementations/inmemory/InMemoryBlockStore.cpp @@ -36,5 +36,10 @@ unique_ptr InMemoryBlockStore::load(const Key &key) { } } +void InMemoryBlockStore::remove(const Key &key) { + int numRemoved = _blocks.erase(key.ToString()); + assert(1==numRemoved); +} + } } diff --git a/implementations/inmemory/InMemoryBlockStore.h b/implementations/inmemory/InMemoryBlockStore.h index 3531534a..2bd591db 100644 --- a/implementations/inmemory/InMemoryBlockStore.h +++ b/implementations/inmemory/InMemoryBlockStore.h @@ -18,6 +18,7 @@ public: std::unique_ptr create(const Key &key, size_t size) override; std::unique_ptr load(const Key &key) override; + void remove(const Key &key) override; private: std::map _blocks; diff --git a/implementations/ondisk/OnDiskBlock.cpp b/implementations/ondisk/OnDiskBlock.cpp index 0ab18d74..ee4aa70f 100644 --- a/implementations/ondisk/OnDiskBlock.cpp +++ b/implementations/ondisk/OnDiskBlock.cpp @@ -71,6 +71,12 @@ unique_ptr OnDiskBlock::CreateOnDisk(const bf::path &rootdir, const return block; } +void OnDiskBlock::RemoveFromDisk(const bf::path &rootdir, const Key &key) { + auto filepath = rootdir / key.ToString(); + assert(bf::is_regular_file(filepath)); + bf::remove(filepath); +} + void OnDiskBlock::_fillDataWithZeroes() { _data.FillWithZeroes(); } diff --git a/implementations/ondisk/OnDiskBlock.h b/implementations/ondisk/OnDiskBlock.h index ce4aaf2f..f4271cd4 100644 --- a/implementations/ondisk/OnDiskBlock.h +++ b/implementations/ondisk/OnDiskBlock.h @@ -19,6 +19,7 @@ public: static std::unique_ptr LoadFromDisk(const boost::filesystem::path &rootdir, const Key &key); static std::unique_ptr CreateOnDisk(const boost::filesystem::path &rootdir, const Key &key, size_t size); + static void RemoveFromDisk(const boost::filesystem::path &rootdir, const Key &key); void *data() override; const void *data() const override; diff --git a/implementations/ondisk/OnDiskBlockStore.cpp b/implementations/ondisk/OnDiskBlockStore.cpp index 4c60b291..5ff43fa0 100644 --- a/implementations/ondisk/OnDiskBlockStore.cpp +++ b/implementations/ondisk/OnDiskBlockStore.cpp @@ -28,5 +28,9 @@ unique_ptr OnDiskBlockStore::load(const Key &key) { return OnDiskBlock::LoadFromDisk(_rootdir, key); } +void OnDiskBlockStore::remove(const Key &key) { + OnDiskBlock::RemoveFromDisk(_rootdir, key); +} + } } diff --git a/implementations/ondisk/OnDiskBlockStore.h b/implementations/ondisk/OnDiskBlockStore.h index 92af8ed7..6dedafa4 100644 --- a/implementations/ondisk/OnDiskBlockStore.h +++ b/implementations/ondisk/OnDiskBlockStore.h @@ -18,6 +18,7 @@ public: std::unique_ptr create(const Key &key, size_t size) override; std::unique_ptr load(const Key &key) override; + void remove(const Key &key) override; private: const boost::filesystem::path _rootdir; diff --git a/implementations/testfake/FakeBlockStore.cpp b/implementations/testfake/FakeBlockStore.cpp index 35356268..f63a9729 100644 --- a/implementations/testfake/FakeBlockStore.cpp +++ b/implementations/testfake/FakeBlockStore.cpp @@ -36,6 +36,11 @@ unique_ptr FakeBlockStore::load(const Key &key) { } } +void FakeBlockStore::remove(const Key &key) { + int numRemoved = _blocks.erase(key.ToString()); + assert(numRemoved == 1); +} + unique_ptr FakeBlockStore::makeFakeBlockFromData(const Key &key, const Data &data) { auto newdata = make_shared(data.copy()); _used_dataregions_for_blocks.push_back(newdata); diff --git a/implementations/testfake/FakeBlockStore.h b/implementations/testfake/FakeBlockStore.h index bb3c022f..12a4cd55 100644 --- a/implementations/testfake/FakeBlockStore.h +++ b/implementations/testfake/FakeBlockStore.h @@ -33,6 +33,7 @@ public: std::unique_ptr create(const Key &key, size_t size) override; std::unique_ptr load(const Key &key) override; + void remove(const Key &key) override; void updateData(const Key &key, const Data &data); diff --git a/interface/BlockStore.h b/interface/BlockStore.h index 0585c76f..44adece9 100644 --- a/interface/BlockStore.h +++ b/interface/BlockStore.h @@ -19,8 +19,7 @@ public: //TODO Use boost::optional (if key doesn't exist) // Return nullptr if block with this key doesn't exists virtual std::unique_ptr load(const Key &key) = 0; - //TODO Needed for performance? Or is deleting loaded blocks enough? - //virtual void remove(const std::string &key) = 0; + virtual void remove(const Key &key) = 0; }; } diff --git a/test/interface/helpers/BlockStoreWithRandomKeysTest.cpp b/test/interface/helpers/BlockStoreWithRandomKeysTest.cpp index f7c4f350..2b054510 100644 --- a/test/interface/helpers/BlockStoreWithRandomKeysTest.cpp +++ b/test/interface/helpers/BlockStoreWithRandomKeysTest.cpp @@ -24,6 +24,7 @@ public: return unique_ptr(do_load(key)); } MOCK_METHOD1(do_load, Block*(const Key &)); + MOCK_METHOD1(remove, void(const Key &)); }; class BlockMock: public Block { diff --git a/test/testutils/BlockStoreTest.h b/test/testutils/BlockStoreTest.h index 2884648f..ede6af57 100644 --- a/test/testutils/BlockStoreTest.h +++ b/test/testutils/BlockStoreTest.h @@ -200,6 +200,21 @@ TYPED_TEST_P(BlockStoreTest, TwoCreatedBlocksHaveDifferentKeys) { EXPECT_NE(block1->key(), block2->key()); } +TYPED_TEST_P(BlockStoreTest, BlockIsNotLoadableAfterDeleting) { + auto blockStore = this->fixture.createBlockStore(); + auto blockkey = blockStore->create(1024)->key(); + EXPECT_NE(nullptr, blockStore->load(blockkey)); + blockStore->remove(blockkey); + EXPECT_EQ(nullptr, blockStore->load(blockkey)); +} + +TYPED_TEST_P(BlockStoreTest, CrashesWhenTryingToDeleteNonexistingBlock) { + auto blockStore = this->fixture.createBlockStore(); + auto blockkey = blockStore->create(1024)->key(); + blockStore->remove(blockkey); + EXPECT_DEATH(blockStore->remove(blockkey), ""); +} + REGISTER_TYPED_TEST_CASE_P(BlockStoreTest, CreatedBlockHasCorrectSize, LoadingUnchangedBlockHasCorrectSize, @@ -213,7 +228,9 @@ REGISTER_TYPED_TEST_CASE_P(BlockStoreTest, AfterLoad_FlushesWhenDestructed, LoadNonExistingBlock, LoadNonExistingBlockWithEmptyKey, - TwoCreatedBlocksHaveDifferentKeys + TwoCreatedBlocksHaveDifferentKeys, + BlockIsNotLoadableAfterDeleting, + CrashesWhenTryingToDeleteNonexistingBlock );