From f286886b4903df1a3d7c7923fc7395e9c22a9c8f Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 27 Apr 2015 22:11:15 +0200 Subject: [PATCH] Handle QueueMap::push(existing_key) better and write more test cases for QueueMap --- implementations/caching/QueueMap.h | 4 ++- test/implementations/caching/QueueMapTest.cpp | 30 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/implementations/caching/QueueMap.h b/implementations/caching/QueueMap.h index e3cbb0ec..f412432b 100644 --- a/implementations/caching/QueueMap.h +++ b/implementations/caching/QueueMap.h @@ -25,7 +25,9 @@ public: void push(const Key &key, Value value) { auto newEntry = _entries.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(_sentinel.prev, &_sentinel)); - assert(newEntry.second == true); + if(newEntry.second != true) { + throw std::logic_error("There is already an element with this key"); + } newEntry.first->second.init(&newEntry.first->first, std::move(value)); //The following is ok, because std::unordered_map never invalidates pointers to its entries _sentinel.prev->next = &newEntry.first->second; diff --git a/test/implementations/caching/QueueMapTest.cpp b/test/implementations/caching/QueueMapTest.cpp index 851180e9..c49e6889 100644 --- a/test/implementations/caching/QueueMapTest.cpp +++ b/test/implementations/caching/QueueMapTest.cpp @@ -398,6 +398,34 @@ TEST_F(QueueMapValueTest, PushingSomePoppingLastPerKey) { EXPECT_EQ(boost::none, pop()); } +//This test forces the underlying datastructure (std::map or std::unordered_map) to grow and reallocate memory. +//So it tests, that QueueMap still works after reallocating memory. +TEST_F(QueueMapValueTest, ManyValues) { + //Push 1 million entries + for (int i = 0; i < 1000000; ++i) { + push(i, 2*i); + } + //pop every other one by key + for (int i = 0; i < 1000000; i += 2) { + EXPECT_EQ(2*i, pop(i).value()); + } + //pop the rest in queue order + for (int i = 1; i < 1000000; i += 2) { + EXPECT_EQ(2*i, peek().value()); + EXPECT_EQ(2*i, pop().value()); + } + EXPECT_EQ(0, size()); + EXPECT_EQ(boost::none, pop()); + EXPECT_EQ(boost::none, peek()); +} + +TEST_F(QueueMapValueTest, PushAlreadyExistingValue) { + push(2, 3); + EXPECT_ANY_THROW( + push(2, 4); + ); +} + class QueueMapPeekTest: public QueueMapTest {}; TEST_F(QueueMapPeekTest, PoppingFromEmpty) { @@ -483,5 +511,3 @@ TEST_F(QueueMapMoveConstructorTest, PushingAndPoppingPerKey_CopyIntoMap) { CopyableValueType val = map->pop(MinimalKeyType::create(0)).value(); EXPECT_EQ(1, CopyableValueType::numCopyConstructorCalled); } - -//TODO Pushing the same key twice