1 package net.sf.ehcache.pool;
2
3 import java.io.IOException;
4
5 import java.util.Random;
6
7 import junit.framework.Assert;
8
9 import net.sf.ehcache.CacheManager;
10 import net.sf.ehcache.Ehcache;
11 import net.sf.ehcache.Element;
12 import net.sf.ehcache.config.CacheConfiguration;
13 import net.sf.ehcache.config.Configuration;
14 import net.sf.ehcache.config.MemoryUnit;
15
16 import org.junit.Test;
17
18 public class TwinCachesTest {
19
20 @Test
21 public void testParallelLoadTwinCaches() {
22 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(16, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
23
24 Ehcache one = manager.addCacheIfAbsent("one");
25 Ehcache two = manager.addCacheIfAbsent("two");
26
27 int terminal = 0;
28 for (int i = 0; true; i++) {
29 int sizeOne = one.getSize();
30 int sizeTwo = two.getSize();
31 one.put(new Element(Integer.toString(i), new byte[1024]));
32 two.put(new Element(Integer.toString(i), new byte[1024]));
33 if (sizeOne >= one.getSize() || sizeTwo >= two.getSize()) {
34 terminal = i;
35 break;
36 }
37 }
38
39 for (int i = terminal + 1; i < terminal + 100; i++) {
40 one.put(new Element(Integer.toString(i), new byte[1024]));
41 two.put(new Element(Integer.toString(i), new byte[1024]));
42 }
43
44 float ratio = 0.5f;
45
46 long total = one.getSize() + two.getSize();
47
48 System.err.println("[1] Ratio : " + ratio);
49 System.err.println("[1] Measured : " + (((float) one.getSize()) / total) + " [" + one.getSize() + "]");
50 System.err.println("[2] Ratio : " + (1 - ratio));
51 System.err.println("[2] Measured : " + (((float) two.getSize()) / total) + " [" + two.getSize() + "]");
52
53 Assert.assertEquals(ratio, ((float) one.getSize()) / total, 0.1f);
54 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / total, 0.1f);
55 }
56
57 @Test
58 public void testSerialLoadTwinCaches() {
59 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(16, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
60
61 Ehcache one = manager.addCacheIfAbsent("one");
62 Ehcache two = manager.addCacheIfAbsent("two");
63
64 int terminal = 0;
65 for (int i = 0; true; i++) {
66 int sizeOne = one.getSize();
67 one.put(new Element(Integer.toString(i), new byte[1024]));
68 if (sizeOne >= one.getSize()) {
69 terminal = i + 1;
70 break;
71 }
72 }
73
74 for (int i = 0; i < terminal; i++) {
75 two.put(new Element(Integer.toString(i), new byte[1024]));
76 }
77
78 for (int i = terminal; i < terminal + 100; i++) {
79 one.put(new Element(Integer.toString(i), new byte[1024]));
80 two.put(new Element(Integer.toString(i), new byte[1024]));
81 }
82
83 float ratio = 0.5f;
84
85 long total = one.getSize() + two.getSize();
86
87 System.err.println("[1] Ratio : " + ratio);
88 System.err.println("[1] Measured : " + (((float) one.getSize()) / total) + " [" + one.getSize() + "]");
89 System.err.println("[2] Ratio : " + (1 - ratio));
90 System.err.println("[2] Measured : " + (((float) two.getSize()) / total) + " [" + two.getSize() + "]");
91
92 Assert.assertEquals(ratio, ((float) one.getSize()) / total, 0.1f);
93 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / total, 0.1f);
94 }
95
96 @Test
97 public void testRandomAccessTwinCaches() {
98 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(1, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
99
100 Ehcache one = manager.addCacheIfAbsent("one");
101 Ehcache two = manager.addCacheIfAbsent("two");
102
103 long seed = System.nanoTime();
104 System.err.println("TwinCachesTest.testRandomAccessTwinCaches seed=" + seed);
105 Random rndm = new Random(seed);
106 float ratio = rndm.nextFloat();
107
108 final int MAX = 1024 * 16;
109 for (int i = 0; i < 20 * MAX; i++) {
110 Ehcache chosen = (rndm.nextFloat() < ratio) ? one : two;
111
112 int key = getRandomKey(rndm, MAX);
113 Element e = chosen.get(key);
114 if (e == null) {
115 chosen.put(new Element(key, new byte[128]));
116 }
117 }
118
119 long total = one.getSize() + two.getSize();
120
121 System.err.println("[1] Ratio : " + ratio);
122 System.err.println("[1] Measured : " + (((float) one.getSize()) / total) + " [" + one.getSize() + "]");
123 System.err.println("[2] Ratio : " + (1 - ratio));
124 System.err.println("[2] Measured : " + (((float) two.getSize()) / total) + " [" + two.getSize() + "]");
125
126 Assert.assertEquals(ratio, ((float) one.getSize()) / total, 0.1f);
127 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / total, 0.1f);
128 }
129
130 @Test
131 public void testRandomAccessTripletCaches() {
132 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(1, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
133
134 Ehcache one = manager.addCacheIfAbsent("one");
135 Ehcache two = manager.addCacheIfAbsent("two");
136 Ehcache three = manager.addCacheIfAbsent("three");
137
138 long seed = System.nanoTime();
139 System.err.println("TwinCachesTest.testRandomAccessTripletCaches seed=" + seed);
140 Random rndm = new Random(seed);
141 float ratioOne = rndm.nextFloat();
142 float ratioTwo = (rndm.nextFloat() * (1 - ratioOne)) + ratioOne;
143 final int MAX = 1024 * 16;
144 for (int i = 0; i < 20 * MAX; i++) {
145 Ehcache chosen;
146 float choice = rndm.nextFloat();
147 if (choice < ratioOne) {
148 chosen = one;
149 } else if (choice < ratioTwo) {
150 chosen = two;
151 } else {
152 chosen = three;
153 }
154
155 int key = getRandomKey(rndm, MAX);
156 Element e = chosen.get(key);
157 if (e == null) {
158 chosen.put(new Element(key, new byte[128]));
159 }
160 }
161
162 long total = one.getSize() + two.getSize() + three.getSize();
163
164 System.err.println("[1] Ratio : " + ratioOne);
165 System.err.println("[1] Measured : " + (((float) one.getSize()) / total) + " [" + one.getSize() + "]");
166 System.err.println("[2] Ratio : " + (ratioTwo - ratioOne));
167 System.err.println("[2] Measured : " + (((float) two.getSize()) / total) + " [" + two.getSize() + "]");
168 System.err.println("[3] Ratio : " + (1 - ratioTwo));
169 System.err.println("[3] Measured : " + (((float) three.getSize()) / total) + " [" + three.getSize() + "]");
170
171 Assert.assertEquals(ratioOne, ((float) one.getSize()) / total, 0.1f);
172 Assert.assertEquals(ratioTwo - ratioOne, ((float) two.getSize()) / total, 0.1f);
173 Assert.assertEquals(1 - ratioTwo, ((float) three.getSize()) / total, 0.1f);
174 }
175
176 @Test
177 public void testIntroducedRandomAccessTwinCache() throws IOException {
178 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(2, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
179
180 Ehcache one = manager.addCacheIfAbsent("one");
181
182 long seed = System.nanoTime();
183 System.err.println("TwinCachesTest.testIntroducedRandomAccessTwinCache seed=" + seed);
184 Random rndm = new Random(seed);
185 float ratio = rndm.nextFloat();
186
187 final int MAX = 1024 * 32;
188
189 for (int key = 0; key < MAX; key++) {
190 int size = one.getSize();
191 one.put(new Element(key, new byte[128]));
192 if (size >= one.getSize()) {
193 break;
194 }
195 }
196
197 Ehcache two = manager.addCacheIfAbsent("two");
198
199 for (int i = 0; i < 20 * MAX; i++) {
200 Ehcache chosen = (rndm.nextFloat() < ratio) ? one : two;
201
202 int key = getRandomKey(rndm, MAX);
203 Element e = chosen.get(key);
204 if (e == null) {
205 chosen.put(new Element(key, new byte[128]));
206 }
207 }
208
209 long total = one.getSize() + two.getSize();
210
211 System.err.println("[1] Ratio : " + ratio);
212 System.err.println("[1] Measured : " + (((float) one.getSize()) / total) + " [" + one.getSize() + "]");
213 System.err.println("[2] Ratio : " + (1 - ratio));
214 System.err.println("[2] Measured : " + (((float) two.getSize()) / total) + " [" + two.getSize() + "]");
215
216 Assert.assertEquals(ratio, ((float) one.getSize()) / total, 0.1f);
217 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / total, 0.1f);
218 }
219
220 @Test
221 public void testIntroducedRandomAccessTripletCache() throws IOException {
222 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(2, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
223
224 Ehcache one = manager.addCacheIfAbsent("one");
225
226 final int MAX = 1024 * 32;
227
228 for (int key = 0; key < MAX; key++) {
229 int size = one.getSize();
230 one.put(new Element(key, new byte[128]));
231 if (size >= one.getSize()) {
232 break;
233 }
234 }
235
236 long seed = System.nanoTime();
237 System.err.println("TwinCachesTest.testIntroducedRandomAccessTripletCache seed=" + seed);
238 Random rndm = new Random(seed);
239 float ratio = rndm.nextFloat();
240
241 Ehcache two = manager.addCacheIfAbsent("two");
242
243 for (int i = 0; i < 20 * MAX; i++) {
244 Ehcache chosen = (rndm.nextFloat() < ratio) ? one : two;
245
246 int key = getRandomKey(rndm, MAX);
247 Element e = chosen.get(key);
248 if (e == null) {
249 chosen.put(new Element(key, new byte[128]));
250 }
251 }
252
253 long totalTwo = one.getSize() + two.getSize();
254
255 System.err.println("[1] Ratio : " + ratio);
256 System.err.println("[1] Measured : " + (((float) one.getSize()) / totalTwo) + " [" + one.getSize() + "]");
257 System.err.println("[2] Ratio : " + (1 - ratio));
258 System.err.println("[2] Measured : " + (((float) two.getSize()) / totalTwo) + " [" + two.getSize() + "]");
259
260 Assert.assertEquals(ratio, ((float) one.getSize()) / totalTwo, 0.1f);
261 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / totalTwo, 0.1f);
262
263 float ratioOne = rndm.nextFloat();
264 float ratioTwo = (rndm.nextFloat() * (1 - ratioOne)) + ratioOne;
265
266 Ehcache three = manager.addCacheIfAbsent("three");
267
268 for (int i = 0; i < 20 * MAX; i++) {
269 Ehcache chosen;
270 float choice = rndm.nextFloat();
271 if (choice < ratioOne) {
272 chosen = one;
273 } else if (choice < ratioTwo) {
274 chosen = two;
275 } else {
276 chosen = three;
277 }
278
279 int key = getRandomKey(rndm, MAX);
280 Element e = chosen.get(key);
281 if (e == null) {
282 chosen.put(new Element(key, new byte[128]));
283 }
284 }
285
286 long totalThree = one.getSize() + two.getSize() + three.getSize();
287
288 System.err.println("[1] Ratio : " + ratioOne);
289 System.err.println("[1] Measured : " + (((float) one.getSize()) / totalThree) + " [" + one.getSize() + "]");
290 System.err.println("[2] Ratio : " + (ratioTwo - ratioOne));
291 System.err.println("[2] Measured : " + (((float) two.getSize()) / totalThree) + " [" + two.getSize() + "]");
292 System.err.println("[3] Ratio : " + (1 - ratioTwo));
293 System.err.println("[3] Measured : " + (((float) three.getSize()) / totalThree) + " [" + three.getSize() + "]");
294
295 Assert.assertEquals(ratioOne, ((float) one.getSize()) / totalThree, 0.1f);
296 Assert.assertEquals(ratioTwo - ratioOne, ((float) two.getSize()) / totalThree, 0.1f);
297 Assert.assertEquals(1 - ratioTwo, ((float) three.getSize()) / totalThree, 0.1f);
298 }
299
300 @Test
301 public void testIntroducedRandomAccessDoubledCache() throws IOException {
302 CacheManager manager = new CacheManager(new Configuration().maxBytesLocalHeap(2, MemoryUnit.MEGABYTES).defaultCache(new CacheConfiguration("default", 0).eternal(true)));
303
304 Ehcache one = manager.addCacheIfAbsent("one");
305
306 long seed = System.nanoTime();
307 System.err.println("TwinCachesTest.testIntroducedRandomAccessDoubledCache seed=" + seed);
308 Random rndm = new Random(seed);
309 float ratio = rndm.nextFloat();
310
311 final int MAX = 1024 * 32;
312
313 for (int key = 0; key < MAX; key++) {
314 int size = one.getSize();
315 one.put(new Element(key, new byte[128]));
316 if (size >= one.getSize()) {
317 break;
318 }
319 }
320
321 Ehcache two = manager.addCacheIfAbsent("two");
322
323 for (int i = 0; i < 20 * MAX; i++) {
324 if (rndm.nextFloat() < ratio) {
325 int key = getRandomKey(rndm, MAX);
326 Element e = one.get(key);
327 if (e == null) {
328 one.put(new Element(key, new byte[128]));
329 }
330 } else {
331 int key = getRandomKey(rndm, MAX);
332 Element e = two.get(key);
333 if (e == null) {
334 two.put(new Element(key, new byte[256]));
335 }
336 }
337 }
338
339 long totalCount = one.getSize() + two.getSize();
340
341 System.err.println("[1] Count Ratio : " + ratio);
342 System.err.println("[1] Count Measured : " + (((float) one.getSize()) / totalCount) + " [" + one.getSize() + "]");
343 System.err.println("[2] Count Ratio : " + (1 - ratio));
344 System.err.println("[2] Count Measured : " + (((float) two.getSize()) / totalCount) + " [" + two.getSize() + "]");
345
346 Assert.assertEquals(ratio, ((float) one.getSize()) / totalCount, 0.1f);
347 Assert.assertEquals(1f - ratio, ((float) two.getSize()) / totalCount, 0.1f);
348
349 long totalBytes = one.calculateInMemorySize() + two.calculateInMemorySize();
350 float bytesRatio = (ratio * 128f) / ((ratio * 128f) + ((1 - ratio) * 256f));
351
352 System.err.println("[1] Bytes Ratio : " + bytesRatio);
353 System.err.println("[1] Bytes Measured : " + (((float) one.calculateInMemorySize()) / totalBytes) + " ["
354 + one.calculateInMemorySize() + "]");
355 System.err.println("[2] Bytes Ratio : " + (1 - bytesRatio));
356 System.err.println("[2] Bytes Measured : " + (((float) two.calculateInMemorySize()) / totalBytes) + " ["
357 + two.calculateInMemorySize() + "]");
358
359 Assert.assertEquals(bytesRatio, ((float) one.calculateInMemorySize()) / totalBytes, 0.1f);
360 Assert.assertEquals(1f - bytesRatio, ((float) two.calculateInMemorySize()) / totalBytes, 0.1f);
361 }
362
363 private static int getRandomKey(Random rndm, int max) {
364 int key;
365 do {
366 key = (int) (((rndm.nextGaussian() + 10.0f) / 20.0f) * max);
367 } while (key < 0 || key >= max);
368 return key;
369 }
370 }