1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
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 package net.sf.ehcache.store;
18
19 import net.sf.ehcache.Element;
20 import net.sf.ehcache.MemoryStoreTester;
21 import org.junit.Before;
22 import org.junit.Ignore;
23 import org.junit.Test;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import static junit.framework.Assert.assertTrue;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertNull;
30
31
32 /***
33 * Test cases for the LruMemoryStore.
34 * <p/>
35 * There are no tests of expiry because this is handled by {@link net.sf.ehcache.Cache#get}
36 * <p/>
37 * <b>Performance:</b>
38 * v1.38 of DiskStore
39 * INFO: Time for benhmarkPutGetSurya: 7355
40 * INFO: Time for Bulk Load: 13
41 * INFO: Time for benhmarkPutGetRemove: 264
42 * INFO: Time for benhmarkPutGet: 154
43 * <p/>
44 * v 1.42 of DiskStore
45 * INFO: Time for Bulk Load: 12
46 * INFO: Time for benhmarkPutGetRemove: 256
47 * INFO: Time for benhmarkPutGet: 165
48 *
49 * @author Greg Luck
50 * @version $Id: LruMemoryStoreTest.html 13146 2011-08-01 17:12:39Z oletizi $
51 */
52 public class LruMemoryStoreTest extends MemoryStoreTester {
53
54 private static final Logger LOG = LoggerFactory.getLogger(LruMemoryStoreTest.class.getName());
55
56 /***
57 * setup test
58 */
59 @Override
60 @Before
61 public void setUp() throws Exception {
62
63 super.setUp();
64 createMemoryOnlyStore(MemoryStoreEvictionPolicy.LRU);
65 }
66
67
68 /***
69 * Test the LRU policy
70 */
71 @Test
72 public void testPolicy() throws Exception {
73 createMemoryOnlyStore(MemoryStoreEvictionPolicy.LRU, 5);
74
75
76 assertEquals(0, cache.getSize());
77
78
79 Element element = new Element("key1", "value1");
80 cache.put(element);
81 assertEquals(1, store.getSize());
82
83 element = new Element("key2", "value2");
84 cache.put(element);
85 assertEquals(2, store.getSize());
86
87 Thread.sleep(1020);
88 element = new Element("key3", "value3");
89 cache.put(element);
90 assertEquals(3, store.getSize());
91
92 element = new Element("key4", "value4");
93 cache.put(element);
94 assertEquals(4, store.getSize());
95
96 element = new Element("key5", "value5");
97 cache.put(element);
98 assertEquals(5, store.getSize());
99
100
101
102 cache.get("key1");
103 cache.get("key1");
104 Thread.sleep(1020);
105 cache.get("key3");
106 cache.get("key3");
107 cache.get("key3");
108 Thread.sleep(1020);
109 cache.get("key4");
110
111
112 element = new Element("key6", "value6");
113 cache.put(element);
114
115 Thread.sleep(1020);
116 cache.get("key6");
117
118
119 assertEquals(5, store.getSize());
120
121
122 assertNull(store.get("key2"));
123 cache.get("key2");
124
125
126 Thread.sleep(1020);
127 cache.get("key5");
128 cache.get("key5");
129
130
131 element = new Element("key7", "value7");
132 cache.put(element);
133 assertEquals(5, store.getSize());
134
135
136 assertNull(store.get("key1"));
137 }
138
139 /***
140 * Test the LRU policy
141 */
142 @Ignore
143 @Test
144 public void testProbabilisticEvictionPolicy() throws Exception {
145 createMemoryOnlyStore(MemoryStoreEvictionPolicy.LRU, 500);
146
147
148 assertEquals(0, cache.getSize());
149
150
151 Element element = new Element("key1", "value1");
152 for (int i = 0; i < 500; i++) {
153 cache.put(new Element("" + i, "value1"));
154 }
155
156 Thread.sleep(3010);
157
158
159 for (int i = 0; i < 500; i++) {
160 cache.get("" + i);
161 }
162
163
164
165
166
167
168
169 for (int i = 501; i < 750; i++) {
170 cache.put(new Element("" + i, "value1"));
171 }
172
173
174 int lastPutCount = 0;
175 for (int i = 501; i < 750; i++) {
176 if (cache.get("" + i) != null) {
177 lastPutCount++;
178 }
179 }
180 LOG.info("Last Put count: " + lastPutCount);
181
182 assertTrue("Ineffective eviction algorithm. Less than 230 of the last 249 put Elements remain: " + lastPutCount, lastPutCount >= 245);
183 }
184
185
186 /***
187 * Multi-thread read, put and removeAll test.
188 * This checks for memory leaks
189 * using the removeAll which was the known cause of memory leaks with MemoryStore in JCS
190 */
191 @Override
192 @Test
193 public void testMemoryLeak() throws Exception {
194 super.testMemoryLeak();
195 }
196
197
198 /***
199 * Specifically to verify the sampling algorithm.
200 * <p/>
201 * This test demonstrates a memory leak if we let the store simply get bigger on an eviction sampling miss.
202 * as is done in r960. e.g.
203 * Jun 9, 2009 10:47:30 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
204 * INFO: Store size is: 12538
205 * Jun 9, 2009 10:47:32 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
206 * INFO: Store size is: 13527
207 * Jun 9, 2009 10:47:34 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
208 * INFO: Store size is: 14475
209 * Jun 9, 2009 10:47:37 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
210 * INFO: Store size is: 15446
211 * Jun 9, 2009 10:47:39 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
212 * INFO: Store size is: 16424
213 * Jun 9, 2009 10:47:41 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
214 * INFO: Store size is: 17399
215 * Jun 9, 2009 10:47:43 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
216 * INFO: Store size is: 18353
217 * Jun 9, 2009 10:47:46 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
218 * INFO: Store size is: 19324
219 * Jun 9, 2009 10:47:48 AM net.sf.ehcache.store.LruMemoryStoreTest testMemoryLeakPutGetRemove
220 * INFO: Store size is: 20300
221 * <p/>
222 * Now fixed and this test consistently gives a size of 12000
223 */
224 @Test
225 public void testMemoryLeakPutGetRemove() throws Exception {
226
227
228 createMemoryOnlyStore(MemoryStoreEvictionPolicy.LRU);
229
230 final String key = "key";
231 String value = "value";
232
233 for (int j = 0; j < 1200000; j += 300000) {
234
235 for (int i = j; i < 300000 + j; i++) {
236 Element element = new Element(key + i, value);
237 store.put(element);
238 }
239 assertEquals(12000, store.getSize());
240 LOG.info("Store size is: " + store.getSize());
241 }
242 }
243
244 }