diff options
author | Tobias Markmann <tm@ayena.de> | 2017-02-17 17:15:41 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2017-02-22 10:54:22 (GMT) |
commit | eea861301be0bf3e3f5db6cfc3cada38d133fef2 (patch) | |
tree | 3c2aa07ce3724a73ce2124832bee6b8c7884c9df /Swiften/Base/UnitTest | |
parent | 80801aaeba2d29e3a375a01d782cf081e778dfaf (diff) | |
download | swift-eea861301be0bf3e3f5db6cfc3cada38d133fef2.zip swift-eea861301be0bf3e3f5db6cfc3cada38d133fef2.tar.bz2 |
Add LRUCache utility class to Swiften
This implements a simple lookup cache with least recently used
replacement strategy.
This also adds Boost.MultiIndex from version 1.56 to 3rdParty.
Test-Information:
Added some unit tests for LRUCache, which pass on macOS 10.12.3
with clang-5.0
Change-Id: I0567945b1197d3fe786bf9d82fdb5e755743b975
Diffstat (limited to 'Swiften/Base/UnitTest')
-rw-r--r-- | Swiften/Base/UnitTest/LRUCacheTest.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Swiften/Base/UnitTest/LRUCacheTest.cpp b/Swiften/Base/UnitTest/LRUCacheTest.cpp new file mode 100644 index 0000000..7d54c5c --- /dev/null +++ b/Swiften/Base/UnitTest/LRUCacheTest.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <string> + +#include <boost/optional.hpp> + +#include <Swiften/Base/LogSerializers.h> +#include <Swiften/Base/LRUCache.h> + +#include <gtest/gtest.h> // This has to go after Swiften/Base/LogSerializers.h. + +using namespace Swift; +namespace b = boost; + +TEST(LRUCacheTest, testCacheLimit) { + LRUCache<std::string, std::string, 3> testling; + + testling.insert("A", "AA"); + testling.insert("B", "BB"); + testling.insert("C", "CC"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>(), testling.get("D")); + + testling.insert("D", "DD"); + + ASSERT_EQ(b::optional<std::string>(), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D")); +} + +TEST(LRUCacheTest, testMoveRecentToFrontOnGet) { + LRUCache<std::string, std::string, 3> testling; + + testling.insert("A", "AA"); + testling.insert("B", "BB"); + testling.insert("C", "CC"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>(), testling.get("D")); + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + + testling.insert("D", "DD"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>(), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D")); +} + +TEST(LRUCacheTest, testMoveRecentToFrontOnReinsert) { + LRUCache<std::string, std::string, 3> testling; + + testling.insert("A", "AA"); + testling.insert("B", "BB"); + testling.insert("C", "CC"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>(), testling.get("D")); + + testling.insert("B", "BB"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>(), testling.get("D")); + + testling.insert("D", "DD"); + + ASSERT_EQ(b::optional<std::string>(), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D")); +} + +TEST(LRUCacheTest, testCacheReturnsValuesPreviouslyInserted) { + LRUCache<std::string, std::string, 3> testling; + + testling.insert("A", "AA"); + testling.insert("B", "BB"); + testling.insert("C", "CC"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); +} + +TEST(LRUCacheTest, testCacheMissFunctionIsUsedOnCacheMiss) { + LRUCache<std::string, std::string, 3> testling; + + testling.insert("A", "AA"); + testling.insert("B", "BB"); + + ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A")); + ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B")); + + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C", [](const std::string&) { + return boost::optional<std::string>(std::string("CC")); + })); + ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C")); + + ASSERT_EQ(b::optional<std::string>(), testling.get("D", [](const std::string&) { + return boost::optional<std::string>(); + })); + ASSERT_EQ(b::optional<std::string>(), testling.get("D")); +} |