1 /**
2 * Copyright 2003-2006 Greg Luck
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;
18
19 import net.sf.ehcache.store.DiskStore;
20 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
21 import net.sf.ehcache.distribution.JVMUtil;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.RandomAccessFile;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Random;
33
34 /**
35 * Test cases for the DiskStore.
36 *
37 * @author <a href="mailto:amurdoch@thoughtworks.com">Adam Murdoch</a>
38 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
39 * @version $Id: DiskStoreTest.java 51 2006-04-24 09:21:10Z gregluck $
40 * <p/>
41 * total time 149 old i/o
42 * total time 133, 131, 130 nio
43 */
44 public class DiskStoreTest extends AbstractCacheTest {
45 private static final Log LOG = LogFactory.getLog(DiskStoreTest.class.getName());
46 private static final int ELEMENT_ON_DISK_SIZE = 1255;
47
48 /**
49 * teardown
50 */
51 protected void tearDown() throws Exception {
52 super.tearDown();
53 deleteFile("persistentLongExpiryIntervalCache");
54 deleteFile("fileTest");
55 deleteFile("testPersistent");
56 }
57
58 /**
59 * Creates a store which is non-expiring so that we can check for
60 * size-related characteristics without elements being deleted under us.
61 */
62 private DiskStore createNonExpiringDiskStore() {
63 Cache cache = new Cache("testNonPersistent", 10000, true, true, 2, 1, false, 1);
64 cache.initialise();
65 DiskStore diskStore = cache.getDiskStore();
66 return diskStore;
67 }
68
69 private DiskStore createDiskStore() {
70 Cache cache = new Cache("testNonPersistent", 10000, true, false, 2, 1, false, 1);
71 cache.initialise();
72 DiskStore diskStore = cache.getDiskStore();
73 return diskStore;
74 }
75
76 private DiskStore createPersistentDiskStore(String cacheName) {
77 Cache cache = new Cache(cacheName, 10000, true, true, 5, 1, true, 600);
78 cache.initialise();
79 DiskStore diskStore = cache.getDiskStore();
80 return diskStore;
81 }
82
83 private DiskStore createPersistentDiskStoreFromCacheManager() {
84 Cache cache = manager.getCache("persistentLongExpiryIntervalCache");
85 return cache.getDiskStore();
86 }
87
88 /**
89 * Tests that a file is created with the right size after puts, and that the file is
90 * deleted on disposal
91 */
92 public void testNonPersistentStore() throws IOException, InterruptedException {
93 DiskStore diskStore = createNonExpiringDiskStore();
94 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
95
96 for (int i = 0; i < 100; i++) {
97 byte[] data = new byte[1024];
98 diskStore.put(new Element("key" + (i + 100), data));
99 waitForFlush(diskStore);
100 int predictedSize = ELEMENT_ON_DISK_SIZE * (i + 1);
101 long actualSize = diskStore.getDataFileSize();
102 assertEquals("On the " + i + " iteration: ", predictedSize, actualSize);
103 }
104
105 assertEquals(100, diskStore.getSize());
106 diskStore.dispose();
107 Thread.sleep(1);
108 assertFalse("File exists", dataFile.exists());
109 }
110
111 /**
112 * Tests that a file is created with the right size after puts, and that the file is not
113 * deleted on disposal
114 * <p/>
115 * This test uses a preconfigured cache from the test cache.xml. Note that teardown causes
116 * an exception because the disk store is being shut down twice.
117 */
118 public void testPersistentStore() throws IOException, InterruptedException, CacheException {
119
120 DiskStore diskStore = createPersistentDiskStoreFromCacheManager();
121 diskStore.removeAll();
122
123 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
124
125 for (int i = 0; i < 100; i++) {
126 byte[] data = new byte[1024];
127 diskStore.put(new Element("key" + (i + 100), data));
128 }
129 waitForFlush(diskStore);
130 assertEquals(100, diskStore.getSize());
131 diskStore.dispose();
132
133 assertTrue("File exists", dataFile.exists());
134 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
135 }
136
137 /**
138 * Tests that the expiry thread dies on dispose.
139 */
140 public void testExpiryThreadDiesOnDispose() throws IOException, InterruptedException {
141 Cache cache = new Cache("testNonPersistent", 10000, true, false, 5, 1, false, 100);
142 cache.initialise();
143 DiskStore diskStore = cache.getDiskStore();
144
145
146 for (int i = 0; i < 100; i++) {
147 byte[] data = new byte[1024];
148 diskStore.put(new Element("key" + (i + 100), data));
149 }
150 waitForFlush(diskStore);
151
152 diskStore.dispose();
153
154 Thread.sleep(100);
155 assertTrue(!diskStore.isExpiryThreadAlive());
156
157
158 }
159
160 /**
161 * Tests that we can save and load a persistent store in a repeatable way
162 */
163 public void testLoadPersistentStore() throws IOException, InterruptedException {
164
165 String cacheName = "testPersistent";
166 DiskStore diskStore = createPersistentDiskStore(cacheName);
167 diskStore.removeAll();
168
169
170 for (int i = 0; i < 100; i++) {
171 byte[] data = new byte[1024];
172 diskStore.put(new Element("key" + (i + 100), data));
173
174 waitForFlush(diskStore);
175 assertEquals("On the " + i + " iteration: ", ELEMENT_ON_DISK_SIZE * (i + 1), diskStore.getDataFileSize());
176 }
177 assertEquals(100, diskStore.getSize());
178 diskStore.dispose();
179 Thread.sleep(3000);
180
181 for (int i = 0; i < 10; i++) {
182 diskStore = createPersistentDiskStore(cacheName);
183 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
184 assertTrue("File exists", dataFile.exists());
185 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
186 assertEquals(100, diskStore.getSize());
187
188 diskStore.dispose();
189
190 assertTrue("File exists", dataFile.exists());
191 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
192 }
193 }
194
195 /**
196 * Tests that we can save and load a persistent store in a repeatable way,
197 * and delete and add data.
198 */
199 public void testLoadPersistentStoreWithDelete() throws IOException, InterruptedException {
200
201 String cacheName = "testPersistent";
202 DiskStore diskStore = createPersistentDiskStore(cacheName);
203 diskStore.removeAll();
204
205
206 for (int i = 0; i < 100; i++) {
207 byte[] data = new byte[1024];
208 diskStore.put(new Element("key" + (i + 100), data));
209 waitForFlush(diskStore);
210 assertEquals("On the " + i + " iteration: ", ELEMENT_ON_DISK_SIZE * (i + 1), diskStore.getDataFileSize());
211 }
212 assertEquals(100, diskStore.getSize());
213 diskStore.dispose();
214
215 diskStore = createPersistentDiskStore(cacheName);
216 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
217 assertTrue("File exists", dataFile.exists());
218 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
219 assertEquals(100, diskStore.getSize());
220
221 diskStore.remove("key100");
222 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
223 assertEquals(99, diskStore.getSize());
224
225 diskStore.dispose();
226
227 assertTrue("File exists", dataFile.exists());
228 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
229 }
230
231 /**
232 * Tests that we can load a store after the index has been corrupted
233 */
234 public void testLoadPersistentStoreAfterCorruption() throws IOException, InterruptedException {
235
236 String cacheName = "testPersistent";
237 DiskStore diskStore = createPersistentDiskStore(cacheName);
238 diskStore.removeAll();
239
240
241 for (int i = 0; i < 100; i++) {
242 byte[] data = new byte[1024];
243 diskStore.put(new Element("key" + (i + 100), data));
244 waitForFlush(diskStore);
245 assertEquals("On the " + i + " iteration: ", ELEMENT_ON_DISK_SIZE * (i + 1), diskStore.getDataFileSize());
246 }
247 assertEquals(100, diskStore.getSize());
248 diskStore.dispose();
249
250 File indexFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getIndexFileName());
251 FileOutputStream fout = new FileOutputStream(indexFile);
252
253 fout.write(new byte[]{'q', 'w', 'e', 'r', 't', 'y'});
254 fout.close();
255 diskStore = createPersistentDiskStore(cacheName);
256 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
257 assertTrue("File exists", dataFile.exists());
258
259
260 assertEquals("Data file was not recreated", 0, dataFile.length());
261 assertEquals(0, diskStore.getSize());
262 }
263
264
265 /**
266 * Tests that we can save and load a persistent store in a repeatable way,
267 * and delete and add data.
268 */
269 public void testFreeSpaceBehaviour() throws IOException, InterruptedException {
270
271 String cacheName = "testPersistent";
272 DiskStore diskStore = createPersistentDiskStore(cacheName);
273 diskStore.removeAll();
274
275 byte[] data = new byte[1024];
276 for (int i = 0; i < 100; i++) {
277 diskStore.put(new Element("key" + (i + 100), data));
278 waitForFlush(diskStore);
279 int predictedSize = ELEMENT_ON_DISK_SIZE * (i + 1);
280 long actualSize = diskStore.getDataFileSize();
281 assertEquals("On the " + i + " iteration: ", predictedSize, actualSize);
282 }
283
284 assertEquals(100, diskStore.getSize());
285 diskStore.dispose();
286
287 diskStore = createPersistentDiskStore(cacheName);
288 File dataFile = new File(diskStore.getDataFilePath() + File.separator + diskStore.getDataFileName());
289 assertTrue("File exists", dataFile.exists());
290 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
291 assertEquals(100, diskStore.getSize());
292
293 diskStore.remove("key100");
294 diskStore.remove("key101");
295 diskStore.remove("key102");
296 diskStore.remove("key103");
297 diskStore.remove("key104");
298
299 diskStore.put(new Element("key100", data));
300 diskStore.put(new Element("key101", data));
301 waitForFlush(diskStore);
302
303 assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
304 assertEquals(97, diskStore.getSize());
305
306 diskStore.put(new Element("key102", data));
307 diskStore.put(new Element("key103", data));
308 diskStore.put(new Element("key104", data));
309 diskStore.put(new Element("key201", data));
310 diskStore.put(new Element("key202", data));
311 waitForFlush(diskStore);
312 assertEquals(102 * ELEMENT_ON_DISK_SIZE, dataFile.length());
313 assertEquals(102, diskStore.getSize());
314 diskStore.dispose();
315 assertTrue("File exists", dataFile.exists());
316 assertEquals(102 * ELEMENT_ON_DISK_SIZE, dataFile.length());
317 }
318
319 /**
320 * Tests looking up an entry that does not exist.
321 */
322 public void testGetUnknown() throws Exception {
323 final DiskStore diskStore = createDiskStore();
324 final Element element = diskStore.get("key");
325 assertNull(element);
326 }
327
328 /**
329 * Tests adding an entry.
330 */
331 public void testPut() throws Exception {
332 final DiskStore diskStore = createDiskStore();
333
334
335 assertEquals(0, diskStore.getSize());
336 Element element = diskStore.get("key");
337 assertNull(element);
338
339
340 final String value = "value";
341 element = new Element("key", value);
342 diskStore.put(element);
343
344
345 assertEquals(1, diskStore.getSize());
346 element = diskStore.get("key");
347 assertNotNull(element);
348 assertEquals(value, element.getObjectValue());
349 }
350
351 /**
352 * Tests adding an entry and waiting for it to be written.
353 */
354 public void testPutSlow() throws Exception {
355 final DiskStore diskStore = createDiskStore();
356
357
358 assertEquals(0, diskStore.getSize());
359 Element element = diskStore.get("key");
360 assertNull(element);
361
362
363 final String value = "value";
364 element = new Element("key", value);
365 diskStore.put(element);
366
367
368 waitForFlush(diskStore);
369
370
371 assertEquals(1, diskStore.getSize());
372 element = diskStore.get("key");
373 assertNotNull(element);
374 assertEquals(value, element.getObjectValue());
375 }
376
377 /**
378 * Tests removing an entry.
379 */
380 public void testRemove() throws Exception {
381 final DiskStore diskStore = createDiskStore();
382
383
384 final String value = "value";
385 Element element = new Element("key", value);
386 diskStore.put(element);
387
388
389 assertEquals(1, diskStore.getSize());
390 element = diskStore.get("key");
391 assertNotNull(element);
392
393
394 diskStore.remove("key");
395
396
397 assertEquals(0, diskStore.getSize());
398 element = diskStore.get("key");
399 assertNull(element);
400 }
401
402 /**
403 * Tests removing an entry, after it has been written
404 */
405 public void testRemoveSlow() throws Exception {
406 final DiskStore diskStore = createDiskStore();
407
408
409 final String value = "value";
410 Element element = new Element("key", value);
411 diskStore.put(element);
412
413
414 waitForFlush(diskStore);
415
416
417 assertEquals(1, diskStore.getSize());
418 element = diskStore.get("key");
419 assertNotNull(element);
420
421
422 diskStore.remove("key");
423
424
425 assertEquals(0, diskStore.getSize());
426 element = diskStore.get("key");
427 assertNull(element);
428 }
429
430 /**
431 * Tests removing all the entries.
432 */
433 public void testRemoveAll() throws Exception {
434 final DiskStore diskStore = createDiskStore();
435
436
437 final String value = "value";
438 Element element = new Element("key", value);
439 diskStore.put(element);
440
441
442 element = diskStore.get("key");
443 assertNotNull(element);
444
445
446 diskStore.removeAll();
447
448
449 assertEquals(0, diskStore.getSize());
450 element = diskStore.get("key");
451 assertNull(element);
452 }
453
454 /**
455 * Tests removing all the entries, after they have been written to disk.
456 */
457 public void testRemoveAllSlow() throws Exception {
458 final DiskStore diskStore = createDiskStore();
459
460
461 final String value = "value";
462 Element element = new Element("key", value);
463 diskStore.put(element);
464
465
466 waitForFlush(diskStore);
467
468
469 element = diskStore.get("key");
470 assertNotNull(element);
471
472
473 diskStore.removeAll();
474
475
476 assertEquals(0, diskStore.getSize());
477 element = diskStore.get("key");
478 assertNull(element);
479 }
480
481 /**
482 * Tests bulk load.
483 */
484 public void testBulkLoad() throws Exception {
485 final DiskStore diskStore = createDiskStore();
486
487 final Random random = new Random();
488
489
490 for (int i = 0; i < 500; i++) {
491
492 final String key = "key" + i;
493 final String value = "This is a value" + random.nextInt(1000);
494
495
496 Element element = new Element(key, value);
497 diskStore.put(element);
498 element = diskStore.get(key);
499 assertNotNull(element);
500
501
502 Thread.sleep(2);
503
504
505 diskStore.remove(key);
506 element = diskStore.get(key);
507 assertNull(element);
508
509 element = new Element(key, value);
510 diskStore.put(element);
511 element = diskStore.get(key);
512 assertNotNull(element);
513
514
515 Thread.sleep(2);
516 }
517 }
518
519 /**
520 * Tests for element expiry.
521 */
522 public void testExpiry() throws Exception {
523
524 final DiskStore diskStore = createDiskStore();
525
526
527 Element element = new Element("key", "value");
528 diskStore.put(element);
529 assertEquals(1, diskStore.getSize());
530
531 assertNotNull(diskStore.get("key"));
532
533
534 waitForFlush(diskStore);
535
536
537 Thread.sleep(3000);
538
539 assertNull(diskStore.get("key"));
540
541 }
542
543 /**
544 * Waits for all spooled elements to be written to disk.
545 */
546 private static void waitForFlush(DiskStore diskStore) throws InterruptedException {
547 while (true) {
548 if (diskStore.isSpoolEmpty()) {
549
550 return;
551 } else {
552
553 Thread.sleep(5);
554 }
555 }
556 }
557
558 /**
559 * Multi-thread read-only test. Will fail on memory constrained VMs
560 */
561 public void testReadOnlyMultipleThreads() throws Exception {
562 final DiskStore diskStore = createNonExpiringDiskStore();
563
564
565 diskStore.put(new Element("key0", "value"));
566 diskStore.put(new Element("key1", "value"));
567
568
569 waitForFlush(diskStore);
570
571
572 final List executables = new ArrayList();
573 for (int i = 0; i < 10; i++) {
574 final String key = "key" + (i % 2);
575 final Executable executable = new Executable() {
576 public void execute() throws Exception {
577 final Element element = diskStore.get(key);
578 assertNotNull(element);
579 assertEquals("value", element.getObjectValue());
580 }
581 };
582 executables.add(executable);
583 }
584 runThreads(executables);
585 }
586
587 /**
588 * Multi-thread concurrent read remove test.
589 */
590 public void testReadRemoveMultipleThreads() throws Exception {
591 final Random random = new Random();
592 final DiskStore diskStore = createDiskStore();
593
594 diskStore.put(new Element("key", "value"));
595
596
597 final List executables = new ArrayList();
598 for (int i = 0; i < 5; i++) {
599 final Executable executable = new Executable() {
600 public void execute() throws Exception {
601 for (int i = 0; i < 100; i++) {
602 diskStore.put(new Element("key" + random.nextInt(100), "value"));
603 }
604 }
605 };
606 executables.add(executable);
607 }
608 for (int i = 0; i < 5; i++) {
609 final Executable executable = new Executable() {
610 public void execute() throws Exception {
611 for (int i = 0; i < 100; i++) {
612 diskStore.remove("key" + random.nextInt(100));
613 }
614 }
615 };
616 executables.add(executable);
617 }
618
619 runThreads(executables);
620 }
621
622 /**
623 * Runs a set of threads, for a fixed amount of time.
624 */
625 private static void runThreads(final List executables) throws Exception {
626
627 final long endTime = System.currentTimeMillis() + 3000;
628 final ArrayList errors = new ArrayList();
629
630
631 final Thread[] threads = new Thread[executables.size()];
632 for (int i = 0; i < threads.length; i++) {
633 final Executable executable = (Executable) executables.get(i);
634 threads[i] = new Thread() {
635 public void run() {
636 try {
637
638 while (System.currentTimeMillis() < endTime) {
639 executable.execute();
640 }
641 } catch (Throwable t) {
642
643 LOG.error(t.getMessage(), t);
644 errors.add(t);
645 }
646 }
647 };
648 threads[i].start();
649 }
650
651
652 for (int i = 0; i < threads.length; i++) {
653 threads[i].join();
654 }
655
656
657 if (errors.size() > 0) {
658 fail(errors.size() + " errors");
659 }
660 }
661
662 /**
663 * A runnable, that can throw an exception.
664 */
665 private interface Executable {
666 /**
667 * Executes this object.
668 */
669 void execute() throws Exception;
670 }
671
672 /**
673 * Tests how data is written to a random access file.
674 * <p/>
675 * It makes sure that bytes are immediately written to disk after a write.
676 */
677 public void testWriteToFile() throws IOException {
678
679 String dataFileName = "fileTest";
680 RandomAccessFile file = getRandomAccessFile(dataFileName);
681
682
683 byte[] buffer = new byte[1024];
684 for (int i = 0; i < 100; i++) {
685 file.write(buffer);
686 }
687
688 assertEquals(1024 * 100, file.length());
689
690 }
691
692 private RandomAccessFile getRandomAccessFile(String name) throws FileNotFoundException {
693 String diskPath = System.getProperty("java.io.tmpdir");
694 final File diskDir = new File(diskPath);
695 File dataFile = new File(diskDir, name + ".data");
696 return new RandomAccessFile(dataFile, "rw");
697 }
698
699 /**
700 * Test overflow to disk = true, using 100000 records.
701 * 15 seconds v1.38 DiskStore
702 * 2 seconds v1.42 DiskStore
703 * Adjusted for change to laptop
704 */
705 public void testOverflowToDiskWithLargeNumberofCacheEntries() throws Exception {
706
707
708 Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 1, null);
709 manager.addCache(cache);
710 int i = 0;
711 StopWatch stopWatch = new StopWatch();
712 for (; i < 100000; i++) {
713 cache.put(new Element("" + i,
714 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
715 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
716 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
717 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
718 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
719 }
720 }
721
722 /**
723 * Test overflow to disk = true, using 100000 records.
724 * 35 seconds v1.38 DiskStore
725 * 26 seconds v1.42 DiskStore
726 */
727 public void testOverflowToDiskWithLargeNumberofCacheEntriesAndGets() throws Exception {
728
729
730 Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 60, null);
731 manager.addCache(cache);
732 Random random = new Random();
733 StopWatch stopWatch = new StopWatch();
734 for (int i = 0; i < 100000; i++) {
735 cache.put(new Element("" + i,
736 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
737 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
738 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
739 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
740 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
741
742 cache.get("" + random.nextInt(100000));
743 }
744
745
746 long elapsed = stopWatch.getElapsedTime();
747 LOG.info("Elapsed time: " + elapsed / 1000);
748 assertEquals(100000, cache.getSize());
749
750
751 assertTrue(99000 <= cache.getDiskStore().getSize());
752 }
753
754
755 /**
756 * Runs out of memory at 5,099,999 elements with the standard 64MB VM size.
757 * <p/>
758 * The reason that it is not infinite is because of a small amount of memory used (about 12 bytes) used for
759 * the disk store index in this case.
760 */
761 public void testMaximumCacheEntriesIn64MBWithOverflowToDisk() throws Exception {
762
763 Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 1, null);
764 manager.addCache(cache);
765 StopWatch stopWatch = new StopWatch();
766 int i = 0;
767 int j = 0;
768 Integer index = null;
769 try {
770 for (; i < 100; i++) {
771 for (j = 0; j < 100000; j++) {
772 index = new Integer(((1000000 * i) + j));
773 cache.put(new Element(index,
774 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
775 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
776 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
777 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
778 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
779 }
780
781 int size = cache.getSize();
782 Thread.sleep(2000);
783 }
784 long elapsed = stopWatch.getElapsedTime();
785 LOG.info("Elapsed time: " + elapsed / 1000);
786 fail();
787 } catch (OutOfMemoryError e) {
788 LOG.info("Failed at " + index);
789 if (JVMUtil.isJDK15()) {
790 assertTrue(index.intValue() > 5000000);
791 } else {
792 assertTrue(index.intValue() > 4099000);
793 }
794 }
795 }
796
797 /**
798 * Perf test used by Venkat Subramani
799 * Get took 119s with Cache svn21
800 * Get took 42s
801 * The change was to stop adding DiskStore retrievals into the MemoryStore. This made sense when the only
802 * policy was LRU. In the new version an Elment, once evicted from the MemoryStore, stays in the DiskStore
803 * until expiry or removal. This avoids a lot of serialization overhead.
804 */
805 public void testLargePutGetPerformanceWithOverflowToDisk() throws Exception {
806
807 Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 10000, null);
808 manager.addCache(cache);
809 StopWatch stopWatch = new StopWatch();
810 int i = 0;
811 int j = 0;
812 Integer index = null;
813 for (; i < 5; i++) {
814 for (j = 0; j < 100000; j++) {
815 index = new Integer(((1000000 * i) + j));
816 cache.put(new Element(index,
817 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
818 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
819 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
820 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
821 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
822 }
823
824 Thread.sleep(2000);
825 }
826 long elapsed = stopWatch.getElapsedTime();
827 long putTime = ((elapsed / 1000) - 10);
828 LOG.info("Put Elapsed time: " + putTime);
829 assertTrue(putTime < 8);
830
831
832 Thread.sleep(2000);
833 Random random = new Random();
834 StopWatch getStopWatch = new StopWatch();
835 long getStart = stopWatch.getElapsedTime();
836
837 for (int k = 0; k < 1000000; k++) {
838 Integer key = new Integer(random.nextInt(500000));
839 cache.get(key);
840 }
841
842 long getElapsedTime = getStopWatch.getElapsedTime();
843 int time = (int) ((getElapsedTime - getStart) / 1000);
844 LOG.info("Get Elapsed time: " + time);
845
846 assertTrue(time < 200);
847 }
848 }