1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdlib.h> 18 19 #include <android/log.h> 20 #include <gtest/gtest.h> 21 #include <utils/JenkinsHash.h> 22 #include <utils/LruCache.h> 23 24 namespace { 25 26 typedef int SimpleKey; 27 typedef const char* StringValue; 28 29 struct ComplexKey { 30 int k; 31 32 explicit ComplexKey(int k) : k(k) { 33 instanceCount += 1; 34 } 35 36 ComplexKey(const ComplexKey& other) : k(other.k) { 37 instanceCount += 1; 38 } 39 40 ~ComplexKey() { 41 instanceCount -= 1; 42 } 43 44 bool operator ==(const ComplexKey& other) const { 45 return k == other.k; 46 } 47 48 bool operator !=(const ComplexKey& other) const { 49 return k != other.k; 50 } 51 52 static ssize_t instanceCount; 53 }; 54 55 ssize_t ComplexKey::instanceCount = 0; 56 57 struct ComplexValue { 58 int v; 59 60 explicit ComplexValue(int v) : v(v) { 61 instanceCount += 1; 62 } 63 64 ComplexValue(const ComplexValue& other) : v(other.v) { 65 instanceCount += 1; 66 } 67 68 ~ComplexValue() { 69 instanceCount -= 1; 70 } 71 72 static ssize_t instanceCount; 73 }; 74 75 ssize_t ComplexValue::instanceCount = 0; 76 77 struct KeyWithPointer { 78 int *ptr; 79 bool operator ==(const KeyWithPointer& other) const { 80 return *ptr == *other.ptr; 81 } 82 }; 83 84 struct KeyFailsOnCopy : public ComplexKey { 85 public: 86 KeyFailsOnCopy(const KeyFailsOnCopy& key) : ComplexKey(key) { 87 ADD_FAILURE(); 88 } 89 KeyFailsOnCopy(int key) : ComplexKey(key) { } 90 }; 91 92 } // namespace 93 94 95 namespace android { 96 97 typedef LruCache<ComplexKey, ComplexValue> ComplexCache; 98 99 template<> inline android::hash_t hash_type(const ComplexKey& value) { 100 return hash_type(value.k); 101 } 102 103 template<> inline android::hash_t hash_type(const KeyWithPointer& value) { 104 return hash_type(*value.ptr); 105 } 106 107 template<> inline android::hash_t hash_type(const KeyFailsOnCopy& value) { 108 return hash_type<ComplexKey>(value); 109 } 110 111 class EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> { 112 public: 113 EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { } 114 ~EntryRemovedCallback() {} 115 void operator()(SimpleKey& k, StringValue& v) { 116 callbackCount += 1; 117 lastKey = k; 118 lastValue = v; 119 } 120 ssize_t callbackCount; 121 SimpleKey lastKey; 122 StringValue lastValue; 123 }; 124 125 class InvalidateKeyCallback : public OnEntryRemoved<KeyWithPointer, StringValue> { 126 public: 127 void operator()(KeyWithPointer& k, StringValue&) { 128 delete k.ptr; 129 k.ptr = nullptr; 130 } 131 }; 132 133 class LruCacheTest : public testing::Test { 134 protected: 135 virtual void SetUp() { 136 ComplexKey::instanceCount = 0; 137 ComplexValue::instanceCount = 0; 138 } 139 140 virtual void TearDown() { 141 ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 142 } 143 144 void assertInstanceCount(ssize_t keys, ssize_t values) { 145 if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) { 146 FAIL() << "Expected " << keys << " keys and " << values << " values " 147 "but there were actually " << ComplexKey::instanceCount << " keys and " 148 << ComplexValue::instanceCount << " values"; 149 } 150 } 151 }; 152 153 TEST_F(LruCacheTest, Empty) { 154 LruCache<SimpleKey, StringValue> cache(100); 155 156 EXPECT_EQ(NULL, cache.get(0)); 157 EXPECT_EQ(0u, cache.size()); 158 } 159 160 TEST_F(LruCacheTest, Simple) { 161 LruCache<SimpleKey, StringValue> cache(100); 162 163 cache.put(1, "one"); 164 cache.put(2, "two"); 165 cache.put(3, "three"); 166 EXPECT_STREQ("one", cache.get(1)); 167 EXPECT_STREQ("two", cache.get(2)); 168 EXPECT_STREQ("three", cache.get(3)); 169 EXPECT_EQ(3u, cache.size()); 170 } 171 172 TEST_F(LruCacheTest, MaxCapacity) { 173 LruCache<SimpleKey, StringValue> cache(2); 174 175 cache.put(1, "one"); 176 cache.put(2, "two"); 177 cache.put(3, "three"); 178 EXPECT_EQ(NULL, cache.get(1)); 179 EXPECT_STREQ("two", cache.get(2)); 180 EXPECT_STREQ("three", cache.get(3)); 181 EXPECT_EQ(2u, cache.size()); 182 } 183 184 TEST_F(LruCacheTest, RemoveLru) { 185 LruCache<SimpleKey, StringValue> cache(100); 186 187 cache.put(1, "one"); 188 cache.put(2, "two"); 189 cache.put(3, "three"); 190 cache.removeOldest(); 191 EXPECT_EQ(NULL, cache.get(1)); 192 EXPECT_STREQ("two", cache.get(2)); 193 EXPECT_STREQ("three", cache.get(3)); 194 EXPECT_EQ(2u, cache.size()); 195 } 196 197 TEST_F(LruCacheTest, GetUpdatesLru) { 198 LruCache<SimpleKey, StringValue> cache(100); 199 200 cache.put(1, "one"); 201 cache.put(2, "two"); 202 cache.put(3, "three"); 203 EXPECT_STREQ("one", cache.get(1)); 204 cache.removeOldest(); 205 EXPECT_STREQ("one", cache.get(1)); 206 EXPECT_EQ(NULL, cache.get(2)); 207 EXPECT_STREQ("three", cache.get(3)); 208 EXPECT_EQ(2u, cache.size()); 209 } 210 211 uint32_t hash_int(int x) { 212 return JenkinsHashWhiten(JenkinsHashMix(0, x)); 213 } 214 215 TEST_F(LruCacheTest, StressTest) { 216 const size_t kCacheSize = 512; 217 LruCache<SimpleKey, StringValue> cache(512); 218 const size_t kNumKeys = 16 * 1024; 219 const size_t kNumIters = 100000; 220 char* strings[kNumKeys]; 221 222 for (size_t i = 0; i < kNumKeys; i++) { 223 strings[i] = (char *)malloc(16); 224 sprintf(strings[i], "%zu", i); 225 } 226 227 srandom(12345); 228 int hitCount = 0; 229 for (size_t i = 0; i < kNumIters; i++) { 230 int index = random() % kNumKeys; 231 uint32_t key = hash_int(index); 232 const char *val = cache.get(key); 233 if (val != NULL) { 234 EXPECT_EQ(strings[index], val); 235 hitCount++; 236 } else { 237 cache.put(key, strings[index]); 238 } 239 } 240 size_t expectedHitCount = kNumIters * kCacheSize / kNumKeys; 241 EXPECT_LT(int(expectedHitCount * 0.9), hitCount); 242 EXPECT_GT(int(expectedHitCount * 1.1), hitCount); 243 EXPECT_EQ(kCacheSize, cache.size()); 244 245 for (size_t i = 0; i < kNumKeys; i++) { 246 free((void *)strings[i]); 247 } 248 } 249 250 TEST_F(LruCacheTest, NoLeak) { 251 ComplexCache cache(100); 252 253 cache.put(ComplexKey(0), ComplexValue(0)); 254 cache.put(ComplexKey(1), ComplexValue(1)); 255 EXPECT_EQ(2U, cache.size()); 256 assertInstanceCount(2, 3); // the member mNullValue counts as an instance 257 } 258 259 TEST_F(LruCacheTest, Clear) { 260 ComplexCache cache(100); 261 262 cache.put(ComplexKey(0), ComplexValue(0)); 263 cache.put(ComplexKey(1), ComplexValue(1)); 264 EXPECT_EQ(2U, cache.size()); 265 assertInstanceCount(2, 3); 266 cache.clear(); 267 assertInstanceCount(0, 1); 268 } 269 270 TEST_F(LruCacheTest, ClearNoDoubleFree) { 271 { 272 ComplexCache cache(100); 273 274 cache.put(ComplexKey(0), ComplexValue(0)); 275 cache.put(ComplexKey(1), ComplexValue(1)); 276 EXPECT_EQ(2U, cache.size()); 277 assertInstanceCount(2, 3); 278 cache.removeOldest(); 279 cache.clear(); 280 assertInstanceCount(0, 1); 281 } 282 assertInstanceCount(0, 0); 283 } 284 285 TEST_F(LruCacheTest, ClearReuseOk) { 286 ComplexCache cache(100); 287 288 cache.put(ComplexKey(0), ComplexValue(0)); 289 cache.put(ComplexKey(1), ComplexValue(1)); 290 EXPECT_EQ(2U, cache.size()); 291 assertInstanceCount(2, 3); 292 cache.clear(); 293 assertInstanceCount(0, 1); 294 cache.put(ComplexKey(0), ComplexValue(0)); 295 cache.put(ComplexKey(1), ComplexValue(1)); 296 EXPECT_EQ(2U, cache.size()); 297 assertInstanceCount(2, 3); 298 } 299 300 TEST_F(LruCacheTest, Callback) { 301 LruCache<SimpleKey, StringValue> cache(100); 302 EntryRemovedCallback callback; 303 cache.setOnEntryRemovedListener(&callback); 304 305 cache.put(1, "one"); 306 cache.put(2, "two"); 307 cache.put(3, "three"); 308 EXPECT_EQ(3U, cache.size()); 309 cache.removeOldest(); 310 EXPECT_EQ(1, callback.callbackCount); 311 EXPECT_EQ(1, callback.lastKey); 312 EXPECT_STREQ("one", callback.lastValue); 313 } 314 315 TEST_F(LruCacheTest, CallbackOnClear) { 316 LruCache<SimpleKey, StringValue> cache(100); 317 EntryRemovedCallback callback; 318 cache.setOnEntryRemovedListener(&callback); 319 320 cache.put(1, "one"); 321 cache.put(2, "two"); 322 cache.put(3, "three"); 323 EXPECT_EQ(3U, cache.size()); 324 cache.clear(); 325 EXPECT_EQ(3, callback.callbackCount); 326 } 327 328 TEST_F(LruCacheTest, CallbackRemovesKeyWorksOK) { 329 LruCache<KeyWithPointer, StringValue> cache(1); 330 InvalidateKeyCallback callback; 331 cache.setOnEntryRemovedListener(&callback); 332 KeyWithPointer key1; 333 key1.ptr = new int(1); 334 KeyWithPointer key2; 335 key2.ptr = new int(2); 336 337 cache.put(key1, "one"); 338 // As the size of the cache is 1, the put will call the callback. 339 // Make sure everything goes smoothly even if the callback invalidates 340 // the key (b/24785286) 341 cache.put(key2, "two"); 342 EXPECT_EQ(1U, cache.size()); 343 EXPECT_STREQ("two", cache.get(key2)); 344 cache.clear(); 345 } 346 347 TEST_F(LruCacheTest, IteratorCheck) { 348 LruCache<int, int> cache(100); 349 350 cache.put(1, 4); 351 cache.put(2, 5); 352 cache.put(3, 6); 353 EXPECT_EQ(3U, cache.size()); 354 355 LruCache<int, int>::Iterator it(cache); 356 std::unordered_set<int> returnedValues; 357 while (it.next()) { 358 int v = it.value(); 359 // Check we haven't seen the value before. 360 EXPECT_TRUE(returnedValues.find(v) == returnedValues.end()); 361 returnedValues.insert(v); 362 } 363 EXPECT_EQ(std::unordered_set<int>({4, 5, 6}), returnedValues); 364 } 365 366 TEST_F(LruCacheTest, EmptyCacheIterator) { 367 // Check that nothing crashes... 368 LruCache<int, int> cache(100); 369 370 LruCache<int, int>::Iterator it(cache); 371 std::unordered_set<int> returnedValues; 372 while (it.next()) { 373 returnedValues.insert(it.value()); 374 } 375 EXPECT_EQ(std::unordered_set<int>(), returnedValues); 376 } 377 378 TEST_F(LruCacheTest, OneElementCacheIterator) { 379 // Check that nothing crashes... 380 LruCache<int, int> cache(100); 381 cache.put(1, 2); 382 383 LruCache<int, int>::Iterator it(cache); 384 std::unordered_set<int> returnedValues; 385 while (it.next()) { 386 returnedValues.insert(it.value()); 387 } 388 EXPECT_EQ(std::unordered_set<int>({ 2 }), returnedValues); 389 } 390 391 TEST_F(LruCacheTest, OneElementCacheRemove) { 392 LruCache<int, int> cache(100); 393 cache.put(1, 2); 394 395 cache.remove(1); 396 397 LruCache<int, int>::Iterator it(cache); 398 std::unordered_set<int> returnedValues; 399 while (it.next()) { 400 returnedValues.insert(it.value()); 401 } 402 EXPECT_EQ(std::unordered_set<int>({ }), returnedValues); 403 } 404 405 TEST_F(LruCacheTest, Remove) { 406 LruCache<int, int> cache(100); 407 cache.put(1, 4); 408 cache.put(2, 5); 409 cache.put(3, 6); 410 411 cache.remove(2); 412 413 LruCache<int, int>::Iterator it(cache); 414 std::unordered_set<int> returnedValues; 415 while (it.next()) { 416 returnedValues.insert(it.value()); 417 } 418 EXPECT_EQ(std::unordered_set<int>({ 4, 6 }), returnedValues); 419 } 420 421 TEST_F(LruCacheTest, RemoveYoungest) { 422 LruCache<int, int> cache(100); 423 cache.put(1, 4); 424 cache.put(2, 5); 425 cache.put(3, 6); 426 427 cache.remove(3); 428 429 LruCache<int, int>::Iterator it(cache); 430 std::unordered_set<int> returnedValues; 431 while (it.next()) { 432 returnedValues.insert(it.value()); 433 } 434 EXPECT_EQ(std::unordered_set<int>({ 4, 5 }), returnedValues); 435 } 436 437 TEST_F(LruCacheTest, RemoveNonMember) { 438 LruCache<int, int> cache(100); 439 cache.put(1, 4); 440 cache.put(2, 5); 441 cache.put(3, 6); 442 443 cache.remove(7); 444 445 LruCache<int, int>::Iterator it(cache); 446 std::unordered_set<int> returnedValues; 447 while (it.next()) { 448 returnedValues.insert(it.value()); 449 } 450 EXPECT_EQ(std::unordered_set<int>({ 4, 5, 6 }), returnedValues); 451 } 452 453 TEST_F(LruCacheTest, DontCopyKeyInGet) { 454 LruCache<KeyFailsOnCopy, KeyFailsOnCopy> cache(1); 455 // Check that get doesn't copy the key 456 cache.get(KeyFailsOnCopy(0)); 457 } 458 459 } 460