From fb68ed133ca6dfc368c235a646cb6d42fb6a935c Mon Sep 17 00:00:00 2001 From: Rodion Date: Mon, 27 Apr 2020 20:07:02 +0300 Subject: [PATCH 1/6] hw_1 fixed, new storage tests added --- src/storage/SimpleLRU.cpp | 155 +++++++++++++++++++++++++++++++++-- test/storage/StorageTest.cpp | 28 +++++++ 2 files changed, 178 insertions(+), 5 deletions(-) diff --git a/src/storage/SimpleLRU.cpp b/src/storage/SimpleLRU.cpp index 0b895bcdf..bc891356e 100644 --- a/src/storage/SimpleLRU.cpp +++ b/src/storage/SimpleLRU.cpp @@ -3,20 +3,165 @@ namespace Afina { namespace Backend { +void SimpleLRU::pop_front() { + lru_node &node = *head; + std::unique_ptr temp; + if (node.next) { + node.next.get()->prev = nullptr; + } + temp.swap(head); + head = std::move(node.next); + _lru_index.erase(node.key); + _current_size -= node.key.size() + node.value.size(); +} + +void SimpleLRU::push_back(const std::string &key, const std::string &value) { + std::unique_ptr temp(new lru_node{key, value}); + if (head.get() != nullptr) { + temp->prev = tail; + tail->next.swap(temp); + tail = tail->next.get(); + } else { + head.swap(temp); + tail = head.get(); + } +} + +void SimpleLRU::move_back(lru_node &node) { + if (tail == &node) { + return; + } + if (head.get() == &node) { + head.swap(node.next); + head->prev = nullptr; + tail->next.swap(node.next); + node.prev = tail; + tail = &node; + } else { + node.next->prev = node.prev; + node.prev->next.swap(node.next); + + // Now node.next points to the NODE + tail->next.swap(node.next); + node.prev = tail; + tail = &node; + } +} + +void SimpleLRU::add(const std::string &key, const std::string &value) { + auto requested_size = key.size() + value.size(); + while (requested_size + _current_size > _max_size) { + pop_front(); + } + // Update list + push_back(key, value); + + // Update index + _lru_index.emplace(std::make_pair(std::ref(tail->key), std::ref(*tail))); + _current_size += requested_size; +} + +void SimpleLRU::remove(lru_node &node) { + std::unique_ptr temp; + if (node.prev == nullptr) { // remove head + temp.swap(head); + head = std::move(node.next); + return; + } + if (node.next == nullptr) { // remove tail + temp.swap(node.prev->next); + node.prev->next = nullptr; + tail = node.prev; + return; + } + node.next->prev = node.prev; + temp.swap(node.prev->next); + node.prev->next = std::move(node.next); +} + // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Put(const std::string &key, const std::string &value) { return false; } +bool SimpleLRU::Put(const std::string &key, const std::string &value) { + auto requested_size = key.size() + value.size(); + if (requested_size > _max_size) { + return false; + } + auto it = _lru_index.find(key); + if (it == _lru_index.end()) { + add(key, value); + } else { + lru_node &node = it->second; + move_back(node); + while (value.size() - it->second.get().value.size() + _current_size > _max_size) { + pop_front(); + } + _current_size += value.size() - it->second.get().value.size(); + node.value = value; + + return true; + } + return true; +} // See MapBasedGlobalLockImpl.h -bool SimpleLRU::PutIfAbsent(const std::string &key, const std::string &value) { return false; } +bool SimpleLRU::PutIfAbsent(const std::string &key, const std::string &value) { + if (key.size() + value.size() > _max_size) { + return false; + } + if (_lru_index.find(key) != _lru_index.end()) { + return false; + } else { + add(key, value); + return true; + } +} // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Set(const std::string &key, const std::string &value) { return false; } +bool SimpleLRU::Set(const std::string &key, const std::string &value) { + if (key.size() + value.size() > _max_size) { + return false; + } + auto it = _lru_index.find(key); + if (it == _lru_index.end()) { + return false; + } else { + lru_node &node = it->second; + move_back(node); + while (value.size() - it->second.get().value.size() + _current_size > _max_size) { + pop_front(); + } + _current_size += value.size() - it->second.get().value.size(); + node.value = value; + return true; + } +} // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Delete(const std::string &key) { return false; } +bool SimpleLRU::Delete(const std::string &key) { + auto it = _lru_index.find(key); + if (it == _lru_index.end()) { + return false; + } + + // Update list + lru_node &node = it->second; + _current_size += node.key.size() + node.value.size(); + _lru_index.erase(it); + + remove(node); + return true; +} // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Get(const std::string &key, std::string &value) { return false; } +bool SimpleLRU::Get(const std::string &key, std::string &value) { + auto it = _lru_index.find(key); + if (it == _lru_index.end()) { + return false; + } + value = it->second.get().value; + lru_node &node = it->second; + move_back(node); + return true; +} } // namespace Backend } // namespace Afina diff --git a/test/storage/StorageTest.cpp b/test/storage/StorageTest.cpp index b3fae8d37..5e194c969 100644 --- a/test/storage/StorageTest.cpp +++ b/test/storage/StorageTest.cpp @@ -195,3 +195,31 @@ TEST(StorageTest, MaxTest) { EXPECT_FALSE(storage.Get(key, res)); } } + +TEST(StorageTest, DeleteByChanceOnSetTest) { + SimpleLRU storage(16); + + EXPECT_TRUE(storage.Put("KEY1", "king")); + EXPECT_TRUE(storage.Put("KEY2", "kong")); + + std::string value = "longlong"; + EXPECT_TRUE(storage.Set("KEY1", value)); + std::string res; + EXPECT_TRUE(storage.Get("KEY1", res)); + EXPECT_TRUE(res == "longlong"); +} + +TEST(StorageTest, PutIfAbsentEndlessLoop) { + SimpleLRU storage(16); + + EXPECT_TRUE(storage.Put("KEY1", "king")); + EXPECT_FALSE(storage.PutIfAbsent("KEY2", "longlonglong1")); +} + +TEST(StorageTest, PutOverwriteCustom) { + SimpleLRU storage(12); + + EXPECT_TRUE(storage.Put("KEY1", "king")); + EXPECT_TRUE(storage.Put("00", "11")); + EXPECT_TRUE(storage.Put("KEY1", "longlong")); +} \ No newline at end of file From aa2a392102c2f143607658d19786a62b3d8c628f Mon Sep 17 00:00:00 2001 From: Rodion Date: Tue, 26 May 2020 21:30:34 +0300 Subject: [PATCH 2/6] Add -Wall flag to cxx compiler to detect some errors --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16eb075f2..8dcc59e74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) project(afina LANGUAGES C CXX) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Werror -fPIC") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") set(CMAKE_THREAD_PREFER_PTHREAD) From af89f5d052e9b820eb6d2d261403995b46371e80 Mon Sep 17 00:00:00 2001 From: Rodion Date: Tue, 26 May 2020 21:37:37 +0300 Subject: [PATCH 3/6] d --- src/storage/SimpleLRU.cpp | 155 ++------------------------------------ 1 file changed, 5 insertions(+), 150 deletions(-) diff --git a/src/storage/SimpleLRU.cpp b/src/storage/SimpleLRU.cpp index bc891356e..0b895bcdf 100644 --- a/src/storage/SimpleLRU.cpp +++ b/src/storage/SimpleLRU.cpp @@ -3,165 +3,20 @@ namespace Afina { namespace Backend { -void SimpleLRU::pop_front() { - lru_node &node = *head; - std::unique_ptr temp; - if (node.next) { - node.next.get()->prev = nullptr; - } - temp.swap(head); - head = std::move(node.next); - _lru_index.erase(node.key); - _current_size -= node.key.size() + node.value.size(); -} - -void SimpleLRU::push_back(const std::string &key, const std::string &value) { - std::unique_ptr temp(new lru_node{key, value}); - if (head.get() != nullptr) { - temp->prev = tail; - tail->next.swap(temp); - tail = tail->next.get(); - } else { - head.swap(temp); - tail = head.get(); - } -} - -void SimpleLRU::move_back(lru_node &node) { - if (tail == &node) { - return; - } - if (head.get() == &node) { - head.swap(node.next); - head->prev = nullptr; - tail->next.swap(node.next); - node.prev = tail; - tail = &node; - } else { - node.next->prev = node.prev; - node.prev->next.swap(node.next); - - // Now node.next points to the NODE - tail->next.swap(node.next); - node.prev = tail; - tail = &node; - } -} - -void SimpleLRU::add(const std::string &key, const std::string &value) { - auto requested_size = key.size() + value.size(); - while (requested_size + _current_size > _max_size) { - pop_front(); - } - // Update list - push_back(key, value); - - // Update index - _lru_index.emplace(std::make_pair(std::ref(tail->key), std::ref(*tail))); - _current_size += requested_size; -} - -void SimpleLRU::remove(lru_node &node) { - std::unique_ptr temp; - if (node.prev == nullptr) { // remove head - temp.swap(head); - head = std::move(node.next); - return; - } - if (node.next == nullptr) { // remove tail - temp.swap(node.prev->next); - node.prev->next = nullptr; - tail = node.prev; - return; - } - node.next->prev = node.prev; - temp.swap(node.prev->next); - node.prev->next = std::move(node.next); -} - // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Put(const std::string &key, const std::string &value) { - auto requested_size = key.size() + value.size(); - if (requested_size > _max_size) { - return false; - } - auto it = _lru_index.find(key); - if (it == _lru_index.end()) { - add(key, value); - } else { - lru_node &node = it->second; - move_back(node); - while (value.size() - it->second.get().value.size() + _current_size > _max_size) { - pop_front(); - } - _current_size += value.size() - it->second.get().value.size(); - node.value = value; - - return true; - } - return true; -} +bool SimpleLRU::Put(const std::string &key, const std::string &value) { return false; } // See MapBasedGlobalLockImpl.h -bool SimpleLRU::PutIfAbsent(const std::string &key, const std::string &value) { - if (key.size() + value.size() > _max_size) { - return false; - } - if (_lru_index.find(key) != _lru_index.end()) { - return false; - } else { - add(key, value); - return true; - } -} +bool SimpleLRU::PutIfAbsent(const std::string &key, const std::string &value) { return false; } // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Set(const std::string &key, const std::string &value) { - if (key.size() + value.size() > _max_size) { - return false; - } - auto it = _lru_index.find(key); - if (it == _lru_index.end()) { - return false; - } else { - lru_node &node = it->second; - move_back(node); - while (value.size() - it->second.get().value.size() + _current_size > _max_size) { - pop_front(); - } - _current_size += value.size() - it->second.get().value.size(); - node.value = value; - return true; - } -} +bool SimpleLRU::Set(const std::string &key, const std::string &value) { return false; } // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Delete(const std::string &key) { - auto it = _lru_index.find(key); - if (it == _lru_index.end()) { - return false; - } - - // Update list - lru_node &node = it->second; - _current_size += node.key.size() + node.value.size(); - _lru_index.erase(it); - - remove(node); - return true; -} +bool SimpleLRU::Delete(const std::string &key) { return false; } // See MapBasedGlobalLockImpl.h -bool SimpleLRU::Get(const std::string &key, std::string &value) { - auto it = _lru_index.find(key); - if (it == _lru_index.end()) { - return false; - } - value = it->second.get().value; - lru_node &node = it->second; - move_back(node); - return true; -} +bool SimpleLRU::Get(const std::string &key, std::string &value) { return false; } } // namespace Backend } // namespace Afina From f24ffde4ebd13a058a4a2b1bcd6204c5d52c8145 Mon Sep 17 00:00:00 2001 From: Rodion Date: Tue, 26 May 2020 21:38:59 +0300 Subject: [PATCH 4/6] d --- test/storage/StorageTest.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/test/storage/StorageTest.cpp b/test/storage/StorageTest.cpp index 5e194c969..b3fae8d37 100644 --- a/test/storage/StorageTest.cpp +++ b/test/storage/StorageTest.cpp @@ -195,31 +195,3 @@ TEST(StorageTest, MaxTest) { EXPECT_FALSE(storage.Get(key, res)); } } - -TEST(StorageTest, DeleteByChanceOnSetTest) { - SimpleLRU storage(16); - - EXPECT_TRUE(storage.Put("KEY1", "king")); - EXPECT_TRUE(storage.Put("KEY2", "kong")); - - std::string value = "longlong"; - EXPECT_TRUE(storage.Set("KEY1", value)); - std::string res; - EXPECT_TRUE(storage.Get("KEY1", res)); - EXPECT_TRUE(res == "longlong"); -} - -TEST(StorageTest, PutIfAbsentEndlessLoop) { - SimpleLRU storage(16); - - EXPECT_TRUE(storage.Put("KEY1", "king")); - EXPECT_FALSE(storage.PutIfAbsent("KEY2", "longlonglong1")); -} - -TEST(StorageTest, PutOverwriteCustom) { - SimpleLRU storage(12); - - EXPECT_TRUE(storage.Put("KEY1", "king")); - EXPECT_TRUE(storage.Put("00", "11")); - EXPECT_TRUE(storage.Put("KEY1", "longlong")); -} \ No newline at end of file From 0e0e0e7325f4916f82cfabb77fac94c417d9b52a Mon Sep 17 00:00:00 2001 From: Rodion Date: Tue, 26 May 2020 21:44:13 +0300 Subject: [PATCH 5/6] Initial commit --- src/storage/SimpleLRU.cpp | 1 + test/storage/StorageTest.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/storage/SimpleLRU.cpp b/src/storage/SimpleLRU.cpp index 0b895bcdf..632c71994 100644 --- a/src/storage/SimpleLRU.cpp +++ b/src/storage/SimpleLRU.cpp @@ -3,6 +3,7 @@ namespace Afina { namespace Backend { + // See MapBasedGlobalLockImpl.h bool SimpleLRU::Put(const std::string &key, const std::string &value) { return false; } diff --git a/test/storage/StorageTest.cpp b/test/storage/StorageTest.cpp index b3fae8d37..b70c73de5 100644 --- a/test/storage/StorageTest.cpp +++ b/test/storage/StorageTest.cpp @@ -19,6 +19,7 @@ using namespace std; + TEST(StorageTest, PutGet) { SimpleLRU storage; From 99dcf4725b53eb78b6ece8f843cf0cd44ab52b54 Mon Sep 17 00:00:00 2001 From: Rodion Date: Tue, 26 May 2020 21:44:49 +0300 Subject: [PATCH 6/6] Initial commit --- src/storage/SimpleLRU.cpp | 1 - test/storage/StorageTest.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/storage/SimpleLRU.cpp b/src/storage/SimpleLRU.cpp index 632c71994..0b895bcdf 100644 --- a/src/storage/SimpleLRU.cpp +++ b/src/storage/SimpleLRU.cpp @@ -3,7 +3,6 @@ namespace Afina { namespace Backend { - // See MapBasedGlobalLockImpl.h bool SimpleLRU::Put(const std::string &key, const std::string &value) { return false; } diff --git a/test/storage/StorageTest.cpp b/test/storage/StorageTest.cpp index b70c73de5..b3fae8d37 100644 --- a/test/storage/StorageTest.cpp +++ b/test/storage/StorageTest.cpp @@ -19,7 +19,6 @@ using namespace std; - TEST(StorageTest, PutGet) { SimpleLRU storage;