Improve performance of InMemoryBlockStore and FakeBlockStore by using std::unordered_map instead of std::map and the direct representation of a block Key as Key instead of a string representation.

This commit is contained in:
Sebastian Messmer 2016-06-23 12:26:47 -07:00
parent 3db931c54d
commit fcbca9ddea
4 changed files with 12 additions and 13 deletions

View File

@ -23,7 +23,7 @@ InMemoryBlockStore::InMemoryBlockStore()
: _blocks() {} : _blocks() {}
optional<unique_ref<Block>> InMemoryBlockStore::tryCreate(const Key &key, Data data) { optional<unique_ref<Block>> InMemoryBlockStore::tryCreate(const Key &key, Data data) {
auto insert_result = _blocks.emplace(piecewise_construct, make_tuple(key.ToString()), make_tuple(key, std::move(data))); auto insert_result = _blocks.emplace(piecewise_construct, make_tuple(key), make_tuple(key, std::move(data)));
if (!insert_result.second) { if (!insert_result.second) {
return none; return none;
@ -36,7 +36,7 @@ optional<unique_ref<Block>> InMemoryBlockStore::tryCreate(const Key &key, Data d
optional<unique_ref<Block>> InMemoryBlockStore::load(const Key &key) { optional<unique_ref<Block>> InMemoryBlockStore::load(const Key &key) {
//Return a pointer to the stored InMemoryBlock //Return a pointer to the stored InMemoryBlock
try { try {
return optional<unique_ref<Block>>(make_unique_ref<InMemoryBlock>(_blocks.at(key.ToString()))); return optional<unique_ref<Block>>(make_unique_ref<InMemoryBlock>(_blocks.at(key)));
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
return none; return none;
} }
@ -45,7 +45,7 @@ optional<unique_ref<Block>> InMemoryBlockStore::load(const Key &key) {
void InMemoryBlockStore::remove(unique_ref<Block> block) { void InMemoryBlockStore::remove(unique_ref<Block> block) {
Key key = block->key(); Key key = block->key();
cpputils::destruct(std::move(block)); cpputils::destruct(std::move(block));
int numRemoved = _blocks.erase(key.ToString()); int numRemoved = _blocks.erase(key);
ASSERT(1==numRemoved, "Didn't find block to remove"); ASSERT(1==numRemoved, "Didn't find block to remove");
} }

View File

@ -6,7 +6,7 @@
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <mutex> #include <mutex>
#include <map> #include <unordered_map>
namespace blockstore { namespace blockstore {
namespace inmemory { namespace inmemory {
@ -24,7 +24,7 @@ public:
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
private: private:
std::map<std::string, InMemoryBlock> _blocks; std::unordered_map<Key, InMemoryBlock> _blocks;
DISALLOW_COPY_AND_ASSIGN(InMemoryBlockStore); DISALLOW_COPY_AND_ASSIGN(InMemoryBlockStore);
}; };

View File

@ -21,7 +21,7 @@ FakeBlockStore::FakeBlockStore()
optional<unique_ref<Block>> FakeBlockStore::tryCreate(const Key &key, Data data) { optional<unique_ref<Block>> FakeBlockStore::tryCreate(const Key &key, Data data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto insert_result = _blocks.emplace(key.ToString(), std::move(data)); auto insert_result = _blocks.emplace(key, std::move(data));
if (!insert_result.second) { if (!insert_result.second) {
return none; return none;
@ -38,9 +38,8 @@ optional<unique_ref<Block>> FakeBlockStore::load(const Key &key) {
optional<unique_ref<Block>> FakeBlockStore::_load(const Key &key) { optional<unique_ref<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();
try { try {
return makeFakeBlockFromData(key, _blocks.at(key_string), false); return makeFakeBlockFromData(key, _blocks.at(key), false);
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
return none; return none;
} }
@ -50,7 +49,7 @@ void FakeBlockStore::remove(unique_ref<Block> block) {
Key key = block->key(); Key key = block->key();
cpputils::destruct(std::move(block)); cpputils::destruct(std::move(block));
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
int numRemoved = _blocks.erase(key.ToString()); int numRemoved = _blocks.erase(key);
ASSERT(numRemoved == 1, "Block not found"); ASSERT(numRemoved == 1, "Block not found");
} }
@ -62,9 +61,9 @@ unique_ref<Block> FakeBlockStore::makeFakeBlockFromData(const Key &key, const Da
void FakeBlockStore::updateData(const Key &key, const Data &data) { void FakeBlockStore::updateData(const Key &key, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(key.ToString()); auto found = _blocks.find(key);
if (found == _blocks.end()) { if (found == _blocks.end()) {
auto insertResult = _blocks.emplace(key.ToString(), data.copy()); auto insertResult = _blocks.emplace(key, data.copy());
ASSERT(true == insertResult.second, "Inserting didn't work"); ASSERT(true == insertResult.second, "Inserting didn't work");
found = insertResult.first; found = insertResult.first;
} }

View File

@ -7,7 +7,7 @@
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <mutex> #include <mutex>
#include <map> #include <unordered_map>
namespace blockstore { namespace blockstore {
namespace testfake { namespace testfake {
@ -41,7 +41,7 @@ public:
void updateData(const Key &key, const cpputils::Data &data); void updateData(const Key &key, const cpputils::Data &data);
private: private:
std::map<std::string, cpputils::Data> _blocks; std::unordered_map<Key, cpputils::Data> _blocks;
//This vector keeps a handle of the data regions for all created FakeBlock objects. //This vector keeps a handle of the data regions for all created FakeBlock objects.
//This way, it is ensured that no two created FakeBlock objects will work on the //This way, it is ensured that no two created FakeBlock objects will work on the