system/core: fix iterator for LruCache

Was failing to return the first element

Change-Id: Ic803f5d463a56519212014d0d190407cf4b859cf
This commit is contained in:
Sergio Giro 2015-10-02 17:31:34 +01:00
parent 2fb90dc8b2
commit 0cb59c0dce
2 changed files with 122 additions and 3 deletions

View file

@ -99,17 +99,29 @@ private:
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 {
@ -122,6 +134,7 @@ public:
private:
const LruCache<TKey, TValue>& mCache;
typename LruCacheSet::iterator mIterator;
bool mBeginReturned;
};
};

View file

@ -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);
}
}