OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/basictypes.h" | |
6 #include "chrome/common/mru_cache.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 | |
9 namespace { | |
10 | |
11 int cached_item_live_count = 0; | |
12 | |
13 struct CachedItem { | |
14 CachedItem() : value(0) { | |
15 cached_item_live_count++; | |
16 } | |
17 | |
18 explicit CachedItem(int new_value) : value(new_value) { | |
19 cached_item_live_count++; | |
20 } | |
21 | |
22 explicit CachedItem(const CachedItem& other) : value(other.value) { | |
23 cached_item_live_count++; | |
24 } | |
25 | |
26 ~CachedItem() { | |
27 cached_item_live_count--; | |
28 } | |
29 | |
30 int value; | |
31 }; | |
32 | |
33 } // namespace | |
34 | |
35 TEST(MRUCacheTest, Basic) { | |
36 typedef MRUCache<int, CachedItem> Cache; | |
37 Cache cache(Cache::NO_AUTO_EVICT); | |
38 | |
39 // Check failure conditions | |
40 { | |
41 CachedItem test_item; | |
42 EXPECT_TRUE(cache.Get(0) == cache.end()); | |
43 EXPECT_TRUE(cache.Peek(0) == cache.end()); | |
44 } | |
45 | |
46 static const int kItem1Key = 5; | |
47 CachedItem item1(10); | |
48 Cache::iterator inserted_item = cache.Put(kItem1Key, item1); | |
49 EXPECT_EQ(1U, cache.size()); | |
50 | |
51 // Check that item1 was properly inserted. | |
52 { | |
53 Cache::iterator found = cache.Get(kItem1Key); | |
54 EXPECT_TRUE(inserted_item == cache.begin()); | |
55 EXPECT_TRUE(found != cache.end()); | |
56 | |
57 found = cache.Peek(kItem1Key); | |
58 EXPECT_TRUE(found != cache.end()); | |
59 | |
60 EXPECT_EQ(kItem1Key, found->first); | |
61 EXPECT_EQ(item1.value, found->second.value); | |
62 } | |
63 | |
64 static const int kItem2Key = 7; | |
65 CachedItem item2(12); | |
66 cache.Put(kItem2Key, item2); | |
67 EXPECT_EQ(2U, cache.size()); | |
68 | |
69 // Check that item1 is the oldest since item2 was added afterwards. | |
70 { | |
71 Cache::reverse_iterator oldest = cache.rbegin(); | |
72 ASSERT_TRUE(oldest != cache.rend()); | |
73 EXPECT_EQ(kItem1Key, oldest->first); | |
74 EXPECT_EQ(item1.value, oldest->second.value); | |
75 } | |
76 | |
77 // Check that item1 is still accessible by key. | |
78 { | |
79 Cache::iterator test_item = cache.Get(kItem1Key); | |
80 ASSERT_TRUE(test_item != cache.end()); | |
81 EXPECT_EQ(kItem1Key, test_item->first); | |
82 EXPECT_EQ(item1.value, test_item->second.value); | |
83 } | |
84 | |
85 // Check that retrieving item1 pushed item2 to oldest. | |
86 { | |
87 Cache::reverse_iterator oldest = cache.rbegin(); | |
88 ASSERT_TRUE(oldest != cache.rend()); | |
89 EXPECT_EQ(kItem2Key, oldest->first); | |
90 EXPECT_EQ(item2.value, oldest->second.value); | |
91 } | |
92 | |
93 // Remove the oldest item and check that item1 is now the only member. | |
94 { | |
95 Cache::reverse_iterator next = cache.Erase(cache.rbegin()); | |
96 | |
97 EXPECT_EQ(1U, cache.size()); | |
98 | |
99 EXPECT_TRUE(next == cache.rbegin()); | |
100 EXPECT_EQ(kItem1Key, next->first); | |
101 EXPECT_EQ(item1.value, next->second.value); | |
102 | |
103 cache.Erase(cache.begin()); | |
104 EXPECT_EQ(0U, cache.size()); | |
105 } | |
106 | |
107 // Check that Clear() works properly. | |
108 cache.Put(kItem1Key, item1); | |
109 cache.Put(kItem2Key, item2); | |
110 EXPECT_EQ(2U, cache.size()); | |
111 cache.Clear(); | |
112 EXPECT_EQ(0U, cache.size()); | |
113 } | |
114 | |
115 TEST(MRUCacheTest, GetVsPeek) { | |
116 typedef MRUCache<int, CachedItem> Cache; | |
117 Cache cache(Cache::NO_AUTO_EVICT); | |
118 | |
119 static const int kItem1Key = 1; | |
120 CachedItem item1(10); | |
121 cache.Put(kItem1Key, item1); | |
122 | |
123 static const int kItem2Key = 2; | |
124 CachedItem item2(20); | |
125 cache.Put(kItem2Key, item2); | |
126 | |
127 // This should do nothing since the size is bigger than the number of items. | |
128 cache.ShrinkToSize(100); | |
129 | |
130 // Check that item1 starts out as oldest | |
131 { | |
132 Cache::reverse_iterator iter = cache.rbegin(); | |
133 ASSERT_TRUE(iter != cache.rend()); | |
134 EXPECT_EQ(kItem1Key, iter->first); | |
135 EXPECT_EQ(item1.value, iter->second.value); | |
136 } | |
137 | |
138 // Check that Peek doesn't change ordering | |
139 { | |
140 Cache::iterator peekiter = cache.Peek(kItem1Key); | |
141 ASSERT_TRUE(peekiter != cache.end()); | |
142 | |
143 Cache::reverse_iterator iter = cache.rbegin(); | |
144 ASSERT_TRUE(iter != cache.rend()); | |
145 EXPECT_EQ(kItem1Key, iter->first); | |
146 EXPECT_EQ(item1.value, iter->second.value); | |
147 } | |
148 } | |
149 | |
150 TEST(MRUCacheTest, KeyReplacement) { | |
151 typedef MRUCache<int, CachedItem> Cache; | |
152 Cache cache(Cache::NO_AUTO_EVICT); | |
153 | |
154 static const int kItem1Key = 1; | |
155 CachedItem item1(10); | |
156 cache.Put(kItem1Key, item1); | |
157 | |
158 static const int kItem2Key = 2; | |
159 CachedItem item2(20); | |
160 cache.Put(kItem2Key, item2); | |
161 | |
162 static const int kItem3Key = 3; | |
163 CachedItem item3(30); | |
164 cache.Put(kItem3Key, item3); | |
165 | |
166 static const int kItem4Key = 4; | |
167 CachedItem item4(40); | |
168 cache.Put(kItem4Key, item4); | |
169 | |
170 CachedItem item5(50); | |
171 cache.Put(kItem3Key, item5); | |
172 | |
173 EXPECT_EQ(4U, cache.size()); | |
174 for (int i = 0; i < 3; ++i) { | |
175 Cache::reverse_iterator iter = cache.rbegin(); | |
176 ASSERT_TRUE(iter != cache.rend()); | |
177 } | |
178 | |
179 // Make it so only the most important element is there. | |
180 cache.ShrinkToSize(1); | |
181 | |
182 Cache::iterator iter = cache.begin(); | |
183 EXPECT_EQ(kItem3Key, iter->first); | |
184 EXPECT_EQ(item5.value, iter->second.value); | |
185 } | |
186 | |
187 // Make sure that the owning version release its pointers properly. | |
188 TEST(MRUCacheTest, Owning) { | |
189 typedef OwningMRUCache<int, CachedItem*> Cache; | |
190 Cache cache(Cache::NO_AUTO_EVICT); | |
191 | |
192 int initial_count = cached_item_live_count; | |
193 | |
194 // First insert and item and then overwrite it. | |
195 static const int kItem1Key = 1; | |
196 cache.Put(kItem1Key, new CachedItem(20)); | |
197 cache.Put(kItem1Key, new CachedItem(22)); | |
198 | |
199 // There should still be one item, and one extra live item. | |
200 Cache::iterator iter = cache.Get(kItem1Key); | |
201 EXPECT_EQ(1U, cache.size()); | |
202 EXPECT_TRUE(iter != cache.end()); | |
203 EXPECT_EQ(initial_count + 1, cached_item_live_count); | |
204 | |
205 // Now remove it. | |
206 cache.Erase(cache.begin()); | |
207 EXPECT_EQ(initial_count, cached_item_live_count); | |
208 | |
209 // Now try another cache that goes out of scope to make sure its pointers | |
210 // go away. | |
211 { | |
212 Cache cache2(Cache::NO_AUTO_EVICT); | |
213 cache2.Put(1, new CachedItem(20)); | |
214 cache2.Put(2, new CachedItem(20)); | |
215 } | |
216 | |
217 // There should be no objects leaked. | |
218 EXPECT_EQ(initial_count, cached_item_live_count); | |
219 | |
220 // Check that Clear() also frees things correctly. | |
221 { | |
222 Cache cache2(Cache::NO_AUTO_EVICT); | |
223 cache2.Put(1, new CachedItem(20)); | |
224 cache2.Put(2, new CachedItem(20)); | |
225 EXPECT_EQ(initial_count + 2, cached_item_live_count); | |
226 cache2.Clear(); | |
227 EXPECT_EQ(initial_count, cached_item_live_count); | |
228 } | |
229 } | |
230 | |
231 TEST(MRUCacheTest, AutoEvict) { | |
232 typedef OwningMRUCache<int, CachedItem*> Cache; | |
233 static const Cache::size_type kMaxSize = 3; | |
234 | |
235 int initial_count = cached_item_live_count; | |
236 | |
237 { | |
238 Cache cache(kMaxSize); | |
239 | |
240 static const int kItem1Key = 1, kItem2Key = 2, kItem3Key = 3, kItem4Key = 4; | |
241 cache.Put(kItem1Key, new CachedItem(20)); | |
242 cache.Put(kItem2Key, new CachedItem(21)); | |
243 cache.Put(kItem3Key, new CachedItem(22)); | |
244 cache.Put(kItem4Key, new CachedItem(23)); | |
245 | |
246 // The cache should only have kMaxSize items in it even though we inserted | |
247 // more. | |
248 EXPECT_EQ(kMaxSize, cache.size()); | |
249 } | |
250 | |
251 // There should be no objects leaked. | |
252 EXPECT_EQ(initial_count, cached_item_live_count); | |
253 } | |
OLD | NEW |