Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
system/core: fix iterator for LruCache
Browse files Browse the repository at this point in the history
Was failing to return the first element

Change-Id: Ic803f5d463a56519212014d0d190407cf4b859cf
  • Loading branch information
Sergio Giro committed Oct 12, 2015
1 parent 2fb90dc commit 0cb59c0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 3 deletions.
19 changes: 16 additions & 3 deletions include/utils/LruCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,29 @@ class LruCache {
TValue mNullValue;

public:
// To be used like:
// while (it.next()) {
// it.value(); it.key();
// }
class Iterator {
public:
Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIterator(mCache.mSet->begin()) {
Iterator(const LruCache<TKey, TValue>& cache):
mCache(cache), mIterator(mCache.mSet->begin()), mBeginReturned(false) {
}

bool next() {
if (mIterator == mCache.mSet->end()) {
return false;
}
std::advance(mIterator, 1);
return mIterator != mCache.mSet->end();
if (!mBeginReturned) {
// mIterator has been initialized to the beginning and
// hasn't been returned. Do not advance:
mBeginReturned = true;
} else {
std::advance(mIterator, 1);
}
bool ret = (mIterator != mCache.mSet->end());
return ret;
}

const TValue& value() const {
Expand All @@ -122,6 +134,7 @@ class LruCache {
private:
const LruCache<TKey, TValue>& mCache;
typename LruCacheSet::iterator mIterator;
bool mBeginReturned;
};
};

Expand Down
106 changes: 106 additions & 0 deletions libutils/tests/LruCache_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,110 @@ TEST_F(LruCacheTest, CallbackOnClear) {
EXPECT_EQ(3, callback.callbackCount);
}

TEST_F(LruCacheTest, IteratorCheck) {
LruCache<int, int> cache(100);

cache.put(1, 4);
cache.put(2, 5);
cache.put(3, 6);
EXPECT_EQ(3U, cache.size());

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
int v = it.value();
// Check we haven't seen the value before.
EXPECT_TRUE(returnedValues.find(v) == returnedValues.end());
returnedValues.insert(v);
}
EXPECT_EQ(std::unordered_set<int>({4, 5, 6}), returnedValues);
}

TEST_F(LruCacheTest, EmptyCacheIterator) {
// Check that nothing crashes...
LruCache<int, int> cache(100);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>(), returnedValues);
}

TEST_F(LruCacheTest, OneElementCacheIterator) {
// Check that nothing crashes...
LruCache<int, int> cache(100);
cache.put(1, 2);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>({ 2 }), returnedValues);
}

TEST_F(LruCacheTest, OneElementCacheRemove) {
LruCache<int, int> cache(100);
cache.put(1, 2);

cache.remove(1);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>({ }), returnedValues);
}

TEST_F(LruCacheTest, Remove) {
LruCache<int, int> cache(100);
cache.put(1, 4);
cache.put(2, 5);
cache.put(3, 6);

cache.remove(2);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>({ 4, 6 }), returnedValues);
}

TEST_F(LruCacheTest, RemoveYoungest) {
LruCache<int, int> cache(100);
cache.put(1, 4);
cache.put(2, 5);
cache.put(3, 6);

cache.remove(3);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>({ 4, 5 }), returnedValues);
}

TEST_F(LruCacheTest, RemoveNonMember) {
LruCache<int, int> cache(100);
cache.put(1, 4);
cache.put(2, 5);
cache.put(3, 6);

cache.remove(7);

LruCache<int, int>::Iterator it(cache);
std::unordered_set<int> returnedValues;
while (it.next()) {
returnedValues.insert(it.value());
}
EXPECT_EQ(std::unordered_set<int>({ 4, 5, 6 }), returnedValues);
}

}

0 comments on commit 0cb59c0

Please sign in to comment.