1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SizedMRUCache_unittest.h: Unit tests for the sized MRU cached.
7
8 #include <gtest/gtest.h>
9
10 #include "libANGLE/SizedMRUCache.h"
11
12 namespace angle
13 {
14
15 using Blob = std::vector<uint8_t>;
16
MakeBlob(size_t size)17 Blob MakeBlob(size_t size)
18 {
19 Blob blob;
20 for (uint8_t value = 0; value < size; ++value)
21 {
22 blob.push_back(value);
23 }
24 return blob;
25 }
26
27 // Test a cache with a value that takes up maximum size.
TEST(SizedMRUCacheTest,MaxSizedValue)28 TEST(SizedMRUCacheTest, MaxSizedValue)
29 {
30 constexpr size_t kSize = 32;
31 SizedMRUCache<std::string, Blob> sizedCache(kSize);
32
33 EXPECT_TRUE(sizedCache.put("test", MakeBlob(kSize), kSize));
34 EXPECT_EQ(32u, sizedCache.size());
35 EXPECT_FALSE(sizedCache.empty());
36
37 EXPECT_TRUE(sizedCache.put("test2", MakeBlob(kSize), kSize));
38 EXPECT_EQ(32u, sizedCache.size());
39 EXPECT_FALSE(sizedCache.empty());
40
41 const Blob *blob = nullptr;
42 EXPECT_FALSE(sizedCache.get("test", &blob));
43
44 sizedCache.clear();
45 EXPECT_TRUE(sizedCache.empty());
46 }
47
48 // Test a cache with many small values, that it can handle unlimited inserts.
TEST(SizedMRUCacheTest,ManySmallValues)49 TEST(SizedMRUCacheTest, ManySmallValues)
50 {
51 constexpr size_t kSize = 32;
52 SizedMRUCache<size_t, size_t> sizedCache(kSize);
53
54 for (size_t value = 0; value < kSize; ++value)
55 {
56 EXPECT_TRUE(sizedCache.put(value, std::move(value), 1));
57
58 const size_t *qvalue = nullptr;
59 EXPECT_TRUE(sizedCache.get(value, &qvalue));
60 if (qvalue)
61 {
62 EXPECT_EQ(value, *qvalue);
63 }
64 }
65
66 EXPECT_EQ(32u, sizedCache.size());
67 EXPECT_FALSE(sizedCache.empty());
68
69 // Putting one element evicts the first element.
70 EXPECT_TRUE(sizedCache.put(kSize, std::move(static_cast<int>(kSize)), 1));
71
72 const size_t *qvalue = nullptr;
73 EXPECT_FALSE(sizedCache.get(0, &qvalue));
74
75 // Putting one large element cleans out the whole stack.
76 EXPECT_TRUE(sizedCache.put(kSize + 1, kSize + 1, kSize));
77 EXPECT_EQ(32u, sizedCache.size());
78 EXPECT_FALSE(sizedCache.empty());
79
80 for (size_t value = 0; value <= kSize; ++value)
81 {
82 EXPECT_FALSE(sizedCache.get(value, &qvalue));
83 }
84 EXPECT_TRUE(sizedCache.get(kSize + 1, &qvalue));
85 if (qvalue)
86 {
87 EXPECT_EQ(kSize + 1, *qvalue);
88 }
89
90 // Put a bunch of items in the cache sequentially.
91 for (size_t value = 0; value < kSize * 10; ++value)
92 {
93 EXPECT_TRUE(sizedCache.put(value, std::move(value), 1));
94 }
95
96 EXPECT_EQ(32u, sizedCache.size());
97 }
98
99 // Tests putting an oversize element.
TEST(SizedMRUCacheTest,OversizeValue)100 TEST(SizedMRUCacheTest, OversizeValue)
101 {
102 constexpr size_t kSize = 32;
103 SizedMRUCache<size_t, size_t> sizedCache(kSize);
104
105 EXPECT_FALSE(sizedCache.put(5, 5, 100));
106 }
107
108 } // namespace angle
109