1b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien/* 2b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * Copyright (C) 2012 The Android Open Source Project 3b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * 4b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 5b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * you may not use this file except in compliance with the License. 6b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * You may obtain a copy of the License at 7b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * 8b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * http://www.apache.org/licenses/LICENSE-2.0 9b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * 10b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * Unless required by applicable law or agreed to in writing, software 11b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * distributed under the License is distributed on an "AS IS" BASIS, 12b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * See the License for the specific language governing permissions and 14b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien * limitations under the License. 15b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien */ 16b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 17b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien#include <stdlib.h> 18b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien#include <utils/JenkinsHash.h> 19b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien#include <utils/LruCache.h> 20b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien#include <cutils/log.h> 21b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien#include <gtest/gtest.h> 22b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 2327d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albertnamespace { 24b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 25b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levientypedef int SimpleKey; 26b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levientypedef const char* StringValue; 27b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 28b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienstruct ComplexKey { 29b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien int k; 30b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 31b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien explicit ComplexKey(int k) : k(k) { 32b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount += 1; 33b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 34b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 35b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexKey(const ComplexKey& other) : k(other.k) { 36b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount += 1; 37b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 38b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 39b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ~ComplexKey() { 40b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount -= 1; 41b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 42b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 43b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien bool operator ==(const ComplexKey& other) const { 44b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien return k == other.k; 45b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 46b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 47b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien bool operator !=(const ComplexKey& other) const { 48b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien return k != other.k; 49b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 50b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 51b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien static ssize_t instanceCount; 52b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien}; 53b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 54b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienssize_t ComplexKey::instanceCount = 0; 55b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 56b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienstruct ComplexValue { 57b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien int v; 58b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 59b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien explicit ComplexValue(int v) : v(v) { 60b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount += 1; 61b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 62b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 63b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexValue(const ComplexValue& other) : v(other.v) { 64b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount += 1; 65b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 66b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 67b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ~ComplexValue() { 68b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien instanceCount -= 1; 69b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 70b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 71b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien static ssize_t instanceCount; 72b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien}; 73b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 74b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienssize_t ComplexValue::instanceCount = 0; 75b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 76b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Girostruct KeyWithPointer { 77b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro int *ptr; 78b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro bool operator ==(const KeyWithPointer& other) const { 79b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro return *ptr == *other.ptr; 80b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro } 81b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro}; 82b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro 8327d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert} // namespace 8427d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 8527d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 8627d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albertnamespace android { 8727d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 88b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levientypedef LruCache<ComplexKey, ComplexValue> ComplexCache; 89b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 9027d166cb3aecc003b2ea576ec23695aff78de1a5Dan Alberttemplate<> inline android::hash_t hash_type(const ComplexKey& value) { 9127d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert return hash_type(value.k); 9227d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert} 9327d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 94b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Girotemplate<> inline android::hash_t hash_type(const KeyWithPointer& value) { 95b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro return hash_type(*value.ptr); 96b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro} 97b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro 98b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienclass EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> { 99b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienpublic: 100b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { } 101b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ~EntryRemovedCallback() {} 102b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien void operator()(SimpleKey& k, StringValue& v) { 103b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien callbackCount += 1; 104b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien lastKey = k; 105b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien lastValue = v; 106b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 107b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ssize_t callbackCount; 108b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien SimpleKey lastKey; 109b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien StringValue lastValue; 110b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien}; 111b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 112b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giroclass InvalidateKeyCallback : public OnEntryRemoved<KeyWithPointer, StringValue> { 113b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giropublic: 114b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro void operator()(KeyWithPointer& k, StringValue&) { 115b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro delete k.ptr; 116b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro k.ptr = nullptr; 117b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro } 118b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro}; 119b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro 120b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienclass LruCacheTest : public testing::Test { 121b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienprotected: 122b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien virtual void SetUp() { 123b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexKey::instanceCount = 0; 124b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexValue::instanceCount = 0; 125b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 126b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 127b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien virtual void TearDown() { 128b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 129b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 130b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 131b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien void assertInstanceCount(ssize_t keys, ssize_t values) { 132b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) { 133b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien FAIL() << "Expected " << keys << " keys and " << values << " values " 134b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien "but there were actually " << ComplexKey::instanceCount << " keys and " 135b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien << ComplexValue::instanceCount << " values"; 136b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 137b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 138b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien}; 139b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 140b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, Empty) { 141b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 142b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 143b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(NULL, cache.get(0)); 144b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(0u, cache.size()); 145b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 146b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 147b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, Simple) { 148b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 149b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 150b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 151b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 152b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 153b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("one", cache.get(1)); 154b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("two", cache.get(2)); 155b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("three", cache.get(3)); 156b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(3u, cache.size()); 157b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 158b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 159b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, MaxCapacity) { 160b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(2); 161b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 162b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 163b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 164b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 165b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(NULL, cache.get(1)); 166b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("two", cache.get(2)); 167b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("three", cache.get(3)); 168b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(2u, cache.size()); 169b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 170b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 171b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, RemoveLru) { 172b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 173b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 174b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 175b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 176b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 177b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.removeOldest(); 178b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(NULL, cache.get(1)); 179b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("two", cache.get(2)); 180b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("three", cache.get(3)); 181b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(2u, cache.size()); 182b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 183b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 184b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, GetUpdatesLru) { 185b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 186b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 187b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 188b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 189b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 190b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("one", cache.get(1)); 191b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.removeOldest(); 192b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("one", cache.get(1)); 193b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(NULL, cache.get(2)); 194b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("three", cache.get(3)); 195b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(2u, cache.size()); 196b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 197b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 198b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levienuint32_t hash_int(int x) { 199b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien return JenkinsHashWhiten(JenkinsHashMix(0, x)); 200b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 201b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 202b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, StressTest) { 203b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien const size_t kCacheSize = 512; 204b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(512); 205b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien const size_t kNumKeys = 16 * 1024; 206b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien const size_t kNumIters = 100000; 207b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien char* strings[kNumKeys]; 208b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 209b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien for (size_t i = 0; i < kNumKeys; i++) { 210b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien strings[i] = (char *)malloc(16); 211cdc1cfb3e51f3caddc1f290b46dc789c036f22edSasha Levitskiy sprintf(strings[i], "%zu", i); 212b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 213b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 214b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien srandom(12345); 215b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien int hitCount = 0; 216b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien for (size_t i = 0; i < kNumIters; i++) { 217b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien int index = random() % kNumKeys; 218b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien uint32_t key = hash_int(index); 219b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien const char *val = cache.get(key); 220b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien if (val != NULL) { 221b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(strings[index], val); 222b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien hitCount++; 223b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } else { 224b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(key, strings[index]); 225b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 226b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 227b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien size_t expectedHitCount = kNumIters * kCacheSize / kNumKeys; 228b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_LT(int(expectedHitCount * 0.9), hitCount); 229b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_GT(int(expectedHitCount * 1.1), hitCount); 230b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(kCacheSize, cache.size()); 231b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 232b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien for (size_t i = 0; i < kNumKeys; i++) { 233b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien free((void *)strings[i]); 234b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 235b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 236b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 237b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, NoLeak) { 238b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexCache cache(100); 239b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 240b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(0), ComplexValue(0)); 241b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(1), ComplexValue(1)); 2423e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(2U, cache.size()); 243bb58cde899dc331d0146faa8a85e7fe2e8f1f490Sergio Giro assertInstanceCount(2, 3); // the member mNullValue counts as an instance 244b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 245b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 246b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, Clear) { 247b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexCache cache(100); 248b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 249b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(0), ComplexValue(0)); 250b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(1), ComplexValue(1)); 2513e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(2U, cache.size()); 252b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(2, 3); 253b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.clear(); 254b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(0, 1); 255b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 256b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 257b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, ClearNoDoubleFree) { 258b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien { 259b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexCache cache(100); 260b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 261b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(0), ComplexValue(0)); 262b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(1), ComplexValue(1)); 2633e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(2U, cache.size()); 264b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(2, 3); 265b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.removeOldest(); 266b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.clear(); 267b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(0, 1); 268b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien } 269b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(0, 0); 270b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 271b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 272b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, ClearReuseOk) { 273b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien ComplexCache cache(100); 274b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 275b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(0), ComplexValue(0)); 276b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(1), ComplexValue(1)); 2773e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(2U, cache.size()); 278b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(2, 3); 279b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.clear(); 280b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(0, 1); 281b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(0), ComplexValue(0)); 282b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(ComplexKey(1), ComplexValue(1)); 2833e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(2U, cache.size()); 284b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien assertInstanceCount(2, 3); 285b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 286b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 287b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, Callback) { 288b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 289b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EntryRemovedCallback callback; 290b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.setOnEntryRemovedListener(&callback); 291b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 292b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 293b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 294b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 2953e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(3U, cache.size()); 296b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.removeOldest(); 297b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(1, callback.callbackCount); 298b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(1, callback.lastKey); 299b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_STREQ("one", callback.lastValue); 300b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 301b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 302b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph LevienTEST_F(LruCacheTest, CallbackOnClear) { 303b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien LruCache<SimpleKey, StringValue> cache(100); 304b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EntryRemovedCallback callback; 305b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.setOnEntryRemovedListener(&callback); 306b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 307b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(1, "one"); 308b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(2, "two"); 309b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.put(3, "three"); 3103e6c451908418484d6e3b4a9f26e793af5d04b62Nick Kralevich EXPECT_EQ(3U, cache.size()); 311b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien cache.clear(); 312b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien EXPECT_EQ(3, callback.callbackCount); 313b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 314b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien 315b7170fe3fe0d8933de57968222bab95ef6615a5aSergio GiroTEST_F(LruCacheTest, CallbackRemovesKeyWorksOK) { 316b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro LruCache<KeyWithPointer, StringValue> cache(1); 317b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro InvalidateKeyCallback callback; 318b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro cache.setOnEntryRemovedListener(&callback); 319b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro KeyWithPointer key1; 320b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro key1.ptr = new int(1); 321b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro KeyWithPointer key2; 322b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro key2.ptr = new int(2); 323b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro 324b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro cache.put(key1, "one"); 325b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro // As the size of the cache is 1, the put will call the callback. 326b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro // Make sure everything goes smoothly even if the callback invalidates 327b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro // the key (b/24785286) 328b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro cache.put(key2, "two"); 329b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro EXPECT_EQ(1U, cache.size()); 330b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro EXPECT_STREQ("two", cache.get(key2)); 331b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro cache.clear(); 332b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro} 333b7170fe3fe0d8933de57968222bab95ef6615a5aSergio Giro 3340cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, IteratorCheck) { 3350cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 3360cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3370cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 4); 3380cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(2, 5); 3390cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(3, 6); 3400cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(3U, cache.size()); 3410cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3420cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 3430cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 3440cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 3450cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro int v = it.value(); 3460cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro // Check we haven't seen the value before. 3470cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_TRUE(returnedValues.find(v) == returnedValues.end()); 3480cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(v); 3490cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 3500cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({4, 5, 6}), returnedValues); 3510cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 3520cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3530cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, EmptyCacheIterator) { 3540cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro // Check that nothing crashes... 3550cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 3560cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3570cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 3580cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 3590cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 3600cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 3610cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 3620cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>(), returnedValues); 3630cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 3640cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3650cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, OneElementCacheIterator) { 3660cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro // Check that nothing crashes... 3670cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 3680cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 2); 3690cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3700cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 3710cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 3720cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 3730cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 3740cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 3750cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({ 2 }), returnedValues); 3760cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 3770cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3780cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, OneElementCacheRemove) { 3790cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 3800cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 2); 3810cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3820cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.remove(1); 3830cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3840cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 3850cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 3860cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 3870cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 3880cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 3890cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({ }), returnedValues); 3900cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 3910cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3920cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, Remove) { 3930cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 3940cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 4); 3950cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(2, 5); 3960cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(3, 6); 3970cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 3980cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.remove(2); 3990cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4000cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 4010cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 4020cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 4030cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 4040cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 4050cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({ 4, 6 }), returnedValues); 4060cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 4070cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4080cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, RemoveYoungest) { 4090cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 4100cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 4); 4110cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(2, 5); 4120cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(3, 6); 4130cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4140cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.remove(3); 4150cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4160cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 4170cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 4180cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 4190cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 4200cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 4210cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({ 4, 5 }), returnedValues); 4220cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 4230cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4240cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio GiroTEST_F(LruCacheTest, RemoveNonMember) { 4250cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int> cache(100); 4260cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(1, 4); 4270cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(2, 5); 4280cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.put(3, 6); 4290cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4300cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro cache.remove(7); 4310cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 4320cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro LruCache<int, int>::Iterator it(cache); 4330cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro std::unordered_set<int> returnedValues; 4340cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro while (it.next()) { 4350cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro returnedValues.insert(it.value()); 4360cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro } 4370cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro EXPECT_EQ(std::unordered_set<int>({ 4, 5, 6 }), returnedValues); 4380cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro} 4390cb59c0dce34bd1518aa775e45e1dd7810195b78Sergio Giro 440b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levien} 441