~ubuntu-branches/ubuntu/quantal/ehcache/quantal

« back to all changes in this revision

Viewing changes to src/test/java/net/sf/ehcache/DiskStoreTest.java

  • Committer: Package Import Robot
  • Author(s): Miguel Landaeta
  • Date: 2012-03-01 19:15:46 UTC
  • mfrom: (1.1.6) (2.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20120301191546-rvlk8tomip0c2m9p
Tags: 2.5.0-1
* Team upload.
* New upstream release. (Closes: #661450).
* Bump Standards-Version to 3.9.3. No changes were required.
* Fix lintian warning with copyright file.
* Remove unnecessary dependencies on JRE for libehcache-java.
* Wrap list of dependencies and uploaders.
* Fix clean target by adding a mh_clean call, to allow twice in a row builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
package net.sf.ehcache;
18
18
 
 
19
import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
20
import static java.util.concurrent.TimeUnit.SECONDS;
 
21
import static net.sf.ehcache.util.RetryAssert.assertBy;
 
22
import static net.sf.ehcache.util.RetryAssert.sizeOnDiskOf;
19
23
import static org.junit.Assert.assertEquals;
20
24
import static org.junit.Assert.assertFalse;
21
25
import static org.junit.Assert.assertNotNull;
22
26
import static org.junit.Assert.assertNull;
23
27
import static org.junit.Assert.assertTrue;
24
 
import static org.junit.Assert.fail;
25
28
 
26
29
import java.io.ByteArrayOutputStream;
27
30
import java.io.File;
30
33
import java.io.IOException;
31
34
import java.io.ObjectOutputStream;
32
35
import java.io.RandomAccessFile;
 
36
import java.lang.reflect.Field;
33
37
import java.util.ArrayList;
34
38
import java.util.Date;
35
39
import java.util.List;
36
40
import java.util.Random;
37
 
 
38
 
import org.slf4j.Logger;
39
 
import org.slf4j.LoggerFactory;
 
41
import java.util.concurrent.Callable;
40
42
 
41
43
import net.sf.ehcache.config.CacheConfiguration;
 
44
import net.sf.ehcache.config.Configuration;
 
45
import net.sf.ehcache.config.ConfigurationFactory;
42
46
import net.sf.ehcache.config.DiskStoreConfiguration;
 
47
import net.sf.ehcache.config.MemoryUnit;
 
48
import net.sf.ehcache.store.FrontEndCacheTier;
43
49
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
44
50
import net.sf.ehcache.store.Primitive;
45
51
import net.sf.ehcache.store.Store;
46
 
import net.sf.ehcache.store.compound.CompoundStore;
47
 
import net.sf.ehcache.store.compound.impl.DiskPersistentStore;
48
 
import net.sf.ehcache.store.compound.impl.OverflowToDiskStore;
 
52
import net.sf.ehcache.store.disk.DiskStore;
 
53
import net.sf.ehcache.util.PropertyUtil;
 
54
import net.sf.ehcache.util.RetryAssert;
49
55
 
 
56
import org.hamcrest.core.Is;
50
57
import org.junit.After;
51
 
import org.junit.Ignore;
 
58
import org.junit.BeforeClass;
52
59
import org.junit.Test;
53
 
 
54
 
import static java.util.concurrent.TimeUnit.MILLISECONDS;
55
 
import static java.util.concurrent.TimeUnit.SECONDS;
 
60
import org.slf4j.Logger;
 
61
import org.slf4j.LoggerFactory;
56
62
 
57
63
/**
58
64
 * Test cases for the DiskStore.
59
65
 *
60
66
 * @author <a href="mailto:amurdoch@thoughtworks.com">Adam Murdoch</a>
61
67
 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
62
 
 * @version $Id: DiskStoreTest.java 2268 2010-04-16 19:50:30Z cdennis $
 
68
 * @version $Id: DiskStoreTest.java 4828 2011-10-10 18:42:59Z cdennis $
63
69
 *          <p/>
64
70
 *          total time 149 old i/o
65
71
 *          total time 133, 131, 130 nio
70
76
    private static final int ELEMENT_ON_DISK_SIZE = 1270;
71
77
    private CacheManager manager2;
72
78
 
 
79
    @BeforeClass
 
80
    public static void enableHeapDump() {
 
81
        setHeapDumpOnOutOfMemoryError(true);
 
82
    }
 
83
 
73
84
    /**
74
85
     * teardown
75
86
     */
92
103
     * size-related characteristics without elements being deleted under us.
93
104
     */
94
105
    private Store createNonExpiringDiskStore() {
95
 
        Cache cache = new Cache("test/NonPersistent", 1, true, true, 2, 1, false, 1);
 
106
        Cache cache = new Cache("test/NonPersistent", 1, true, false, 2, 1, false, 1);
96
107
        manager.addCache(cache);
97
108
        return cache.getStore();
98
109
    }
99
110
 
 
111
    private Cache createDiskCache() {
 
112
        Cache cache = new Cache(new CacheConfiguration().name("test/NonPersistent").maxEntriesLocalHeap(1).overflowToDisk(true)
 
113
                .eternal(false).timeToLiveSeconds(2).timeToIdleSeconds(1).diskPersistent(false).diskExpiryThreadIntervalSeconds(1)
 
114
                .diskSpoolBufferSizeMB(10));
 
115
        manager.addCache(cache);
 
116
        return cache;
 
117
    }
 
118
 
100
119
    private Store createDiskStore() {
101
 
        Cache cache = new Cache("test/NonPersistent", 1, true, false, 2, 1, false, 1);
102
 
        manager.addCache(cache);
103
 
        return cache.getStore();
 
120
        return createDiskCache().getStore();
104
121
    }
105
122
 
106
123
    private Store createPersistentDiskStore(String cacheName) {
107
 
        Cache cache = new Cache(cacheName, 10000, true, true, 5, 1, true, 600);
 
124
        Cache cache = new Cache(cacheName, 10000, true, false, 5, 1, true, 600);
108
125
        manager.addCache(cache);
109
126
        return cache.getStore();
110
127
    }
111
128
 
112
129
    private Store createAutoPersistentDiskStore(String cacheName) {
113
 
        Cache cache = new Cache(cacheName, 10000, true, true, 5, 1, true, 600);
114
 
        manager2 = new CacheManager();
 
130
        Cache cache = new Cache(cacheName, 10000, true, false, 5, 1, true, 600);
 
131
        Configuration config = ConfigurationFactory.parseConfiguration().name("cm2");
 
132
        manager2 = new CacheManager(config);
115
133
        //manager.setDiskStorePath(System.getProperty("java.io.tmpdir") + File.separator + DiskStore.generateUniqueDirectory());
116
134
        manager2.addCache(cache);
117
135
        return cache.getStore();
124
142
 
125
143
    private Store createCapacityLimitedDiskStore() {
126
144
        Cache cache = new Cache("test/CapacityLimited", 1, MemoryStoreEvictionPolicy.LRU, true, null, true,
127
 
                 0, 0, false, 600, null, null, 50);
 
145
                0, 0, false, 600, null, null, 50);
128
146
        manager.addCache(cache);
129
147
        return cache.getStore();
130
148
    }
131
149
 
132
 
    private Store createStripedDiskStore(int stripes) {
133
 
        CacheConfiguration config = new CacheConfiguration("test/NonPersistentStriped_" + stripes, 10000).overflowToDisk(true).eternal(false)
134
 
                .timeToLiveSeconds(2).timeToIdleSeconds(1).diskPersistent(false).diskExpiryThreadIntervalSeconds(1).diskAccessStripes(stripes);
 
150
    private Cache createStripedDiskCache(int stripes) {
 
151
        CacheConfiguration config = new CacheConfiguration("test/NonPersistentStriped_" + stripes, 10000).overflowToDisk(true)
 
152
                .eternal(false).timeToLiveSeconds(2).timeToIdleSeconds(1).diskPersistent(false).diskExpiryThreadIntervalSeconds(1)
 
153
                .diskAccessStripes(stripes).diskSpoolBufferSizeMB(10);
135
154
        Cache cache = new Cache(config);
136
155
        manager.addCache(cache);
137
 
        return cache.getStore();
 
156
        return cache;
138
157
    }
139
 
    
 
158
 
140
159
    /**
141
160
     * Test to help debug DiskStore test
142
161
     */
150
169
     * deleted on disposal
151
170
     */
152
171
    @Test
153
 
    public void testNonPersistentStore() throws IOException, InterruptedException {
154
 
        Store diskStore = createNonExpiringDiskStore();
155
 
        File dataFile = ((OverflowToDiskStore) diskStore).getDataFile();
 
172
    public void testNonPersistentStore() throws Exception {
 
173
        DiskStore diskStore = getDiskStore(createNonExpiringDiskStore());
 
174
        File dataFile = diskStore.getDataFile();
156
175
 
157
176
        //100 + 1 for the in-memory capacity
158
177
        for (int i = 0; i < 101; i++) {
160
179
            diskStore.put(new Element("key" + (i + 100), data));
161
180
        }
162
181
        waitShorter();
163
 
        assertEquals(ELEMENT_ON_DISK_SIZE * 100, diskStore.getOnDiskSizeInBytes());
 
182
        assertEquals(ELEMENT_ON_DISK_SIZE * 101, diskStore.getOnDiskSizeInBytes());
164
183
 
165
 
        assertEquals(100, diskStore.getOnDiskSize());
 
184
        assertEquals(101, diskStore.getOnDiskSize());
166
185
        assertEquals(101, diskStore.getSize());
167
186
        diskStore.dispose();
168
187
        Thread.sleep(1);
175
194
     */
176
195
    @Test
177
196
    public void testDeleteAutoGenerated() {
178
 
        manager2 = new CacheManager();
 
197
        Configuration config = ConfigurationFactory.parseConfiguration().name("cm2");
 
198
        manager2 = new CacheManager(config);
179
199
        String diskPath = manager2.getDiskStorePath();
180
200
        File dataDirectory = new File(diskPath);
181
201
        assertTrue(dataDirectory.exists());
191
211
     * Tests that the Disk Store can be changed
192
212
     */
193
213
    @Test
194
 
    public void testSetDiskStorePath() throws IOException, InterruptedException {
195
 
        Cache cache = new Cache("testChangePath", 10000, true, true, 5, 1, true, 600);
196
 
        manager2 = new CacheManager();
 
214
    public void testSetDiskStorePath() throws Exception {
 
215
        Configuration config = ConfigurationFactory.parseConfiguration().name("cm2");
 
216
        Cache cache = new Cache("testChangePath", 10000, true, false, 5, 1, true, 600);
 
217
        manager2 = new CacheManager(config);
197
218
        cache.setDiskStorePath(System.getProperty("java.io.tmpdir") + File.separator + "changedDiskStorePath");
198
219
        manager2.addCache(cache);
199
 
        DiskPersistentStore diskStore = (DiskPersistentStore) cache.getStore();
 
220
        DiskStore diskStore = getDiskStore(cache.getStore());
200
221
        File dataFile = diskStore.getDataFile();
201
222
        assertTrue("File exists", dataFile.exists());
 
223
        manager2.shutdown();
202
224
    }
203
225
 
204
226
    /**
209
231
     * an exception because the disk store is being shut down twice.
210
232
     */
211
233
    @Test
212
 
    public void testPersistentStore() throws IOException, InterruptedException, CacheException {
 
234
    public void testPersistentStore() throws Exception {
213
235
        //initialise
214
 
        Store store = createPersistentDiskStoreFromCacheManager();
 
236
        DiskStore store = getDiskStore(createPersistentDiskStoreFromCacheManager());
215
237
        store.removeAll();
216
238
 
217
 
        File dataFile = ((DiskPersistentStore) store).getDataFile();
 
239
        File dataFile = store.getDataFile();
218
240
 
219
241
        for (int i = 0; i < 100; i++) {
220
242
            byte[] data = new byte[1024];
234
256
    @Test
235
257
    public void testPersistentStoreFromCacheManager() throws IOException, InterruptedException, CacheException {
236
258
        //initialise with an instance CacheManager so that the following line actually does something
237
 
        CacheManager manager = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml");
 
259
        Configuration config = ConfigurationFactory.parseConfiguration(new File(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml"))
 
260
                .name("cm2");
 
261
        CacheManager manager = new CacheManager(config);
238
262
        Ehcache cache = manager.getCache("persistentLongExpiryIntervalCache");
239
263
 
240
264
        LOG.info("DiskStore path: {}", manager.getDiskStorePath());
247
271
 
248
272
        manager.shutdown();
249
273
 
250
 
        manager = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml");
 
274
        manager = new CacheManager(config);
251
275
        cache = manager.getCache("persistentLongExpiryIntervalCache");
252
276
        assertEquals(100, cache.getSize());
253
277
 
264
288
    @Test
265
289
    public void testPersistentNonOverflowToDiskStoreFromCacheManager() throws IOException, InterruptedException, CacheException {
266
290
        //initialise with an instance CacheManager so that the following line actually does something
267
 
        CacheManager manager = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml");
268
 
        Ehcache cache = manager.getCache("persistentLongExpiryIntervalNonOverflowCache");
269
 
 
270
 
        for (int i = 0; i < 100; i++) {
271
 
            byte[] data = new byte[1024];
272
 
            cache.put(new Element("key" + (i + 100), data));
273
 
        }
274
 
        assertEquals(100, cache.getSize());
275
 
 
276
 
        manager.shutdown();
277
 
 
278
 
        manager = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml");
279
 
        cache = manager.getCache("persistentLongExpiryIntervalNonOverflowCache");
280
 
 
281
 
        //Now check that the DiskStore is involved in Cache methods it needs to be involved in.
282
 
        assertEquals(100, cache.getSize());
283
 
        assertEquals(100, cache.getDiskStoreSize());
284
 
        assertEquals(100, cache.getKeysNoDuplicateCheck().size());
285
 
        assertEquals(100, cache.getKeys().size());
286
 
        assertEquals(100, cache.getKeysWithExpiryCheck().size());
287
 
 
288
 
        //now check some of the Cache methods work
289
 
        assertNotNull(cache.get("key100"));
290
 
        assertNotNull(cache.getQuiet("key100"));
291
 
        cache.remove("key100");
292
 
        assertNull(cache.get("key100"));
293
 
        assertNull(cache.getQuiet("key100"));
294
 
        cache.removeAll();
295
 
        assertEquals(0, cache.getSize());
296
 
        assertEquals(0, cache.getDiskStoreSize());
297
 
 
298
 
        manager.shutdown();
 
291
        {
 
292
            Configuration config = ConfigurationFactory.parseConfiguration(new File(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml"))
 
293
            .name("cm2");
 
294
            CacheManager manager = new CacheManager(config);
 
295
            final Ehcache cache = manager.getCache("persistentLongExpiryIntervalNonOverflowCache");
 
296
 
 
297
            for (int i = 0; i < 100; i++) {
 
298
                byte[] data = new byte[1024];
 
299
                cache.put(new Element("key" + (i + 100), data));
 
300
            }
 
301
            assertEquals(100, cache.getSize());
 
302
 
 
303
            manager.shutdown();
 
304
        }
 
305
 
 
306
        {
 
307
            Configuration config = ConfigurationFactory.parseConfiguration(new File(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-disk.xml"))
 
308
            .name("cm2");
 
309
            CacheManager manager = new CacheManager(config);
 
310
            final Ehcache cache = manager.getCache("persistentLongExpiryIntervalNonOverflowCache");
 
311
 
 
312
            //Now check that the DiskStore is involved in Cache methods it needs to be involved in.
 
313
            RetryAssert.assertBy(500, MILLISECONDS, new Callable<Integer>() {
 
314
                public Integer call() throws Exception {
 
315
                    return cache.getSize();
 
316
                }
 
317
            }, Is.is(100));
 
318
 
 
319
            assertEquals(100, cache.getDiskStoreSize());
 
320
            assertEquals(100, cache.getKeysNoDuplicateCheck().size());
 
321
            assertEquals(100, cache.getKeys().size());
 
322
            assertEquals(100, cache.getKeysWithExpiryCheck().size());
 
323
 
 
324
            //now check some of the Cache methods work
 
325
            assertNotNull(cache.get("key100"));
 
326
            assertNotNull(cache.getQuiet("key100"));
 
327
            cache.remove("key100");
 
328
            assertNull(cache.get("key100"));
 
329
            assertNull(cache.getQuiet("key100"));
 
330
            cache.removeAll();
 
331
            assertEquals(0, cache.getSize());
 
332
            assertEquals(0, cache.getDiskStoreSize());
 
333
 
 
334
            manager.shutdown();
 
335
        }
299
336
    }
300
337
 
301
338
    /**
302
339
     * Tests that we can save and load a persistent store in a repeatable way
303
340
     */
304
341
    @Test
305
 
    public void testLoadPersistentStore() throws IOException, InterruptedException {
 
342
    public void testLoadPersistentStore() throws Exception {
306
343
        //initialise
307
344
        String cacheName = "testLoadPersistent";
308
345
        Store store = createPersistentDiskStore(cacheName);
322
359
        Thread.sleep(3000);
323
360
        //check that we can create and dispose several times with no problems and no lost data
324
361
        for (int i = 0; i < 10; i++) {
325
 
            store = createPersistentDiskStore(cacheName);
326
 
            File dataFile = ((DiskPersistentStore) store).getDataFile();
 
362
            store = getDiskStore(createPersistentDiskStore(cacheName));
 
363
            File dataFile = ((DiskStore) store).getDataFile();
327
364
            assertTrue("File exists", dataFile.exists());
328
365
            assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
329
366
            assertEquals(100, store.getSize());
339
376
     * Any disk store with an auto generated random directory should not be able to be loaded.
340
377
     */
341
378
    @Test
342
 
    public void testCannotLoadPersistentStoreWithAutoDir() throws IOException, InterruptedException {
 
379
    public void testCannotLoadPersistentStoreWithAutoDir() throws Exception {
343
380
        //initialise
344
381
        String cacheName = "testPersistent";
345
382
        Store diskStore = createAutoPersistentDiskStore(cacheName);
356
393
        manager2.removeCache(cacheName);
357
394
        Thread.sleep(1000);
358
395
 
359
 
        Cache cache = new Cache(cacheName, 10000, true, true, 5, 1, true, 600);
 
396
        Cache cache = new Cache(cacheName, 10000, true, false, 5, 1, true, 600);
360
397
        manager2.addCache(cache);
361
398
 
362
 
        File dataFile = ((DiskPersistentStore) diskStore).getDataFile();
 
399
        File dataFile = getDiskStore(diskStore).getDataFile();
363
400
        assertTrue("File exists", dataFile.exists());
364
401
        assertEquals(0, dataFile.length());
365
402
        assertEquals(0, cache.getSize());
373
410
     * and delete and add data.
374
411
     */
375
412
    @Test
376
 
    public void testLoadPersistentStoreWithDelete() throws IOException, InterruptedException {
 
413
    public void testLoadPersistentStoreWithDelete() throws Exception {
377
414
        //initialise
378
415
        String cacheName = "testPersistentWithDelete";
379
416
        Store diskStore = createPersistentDiskStore(cacheName);
389
426
        assertEquals(100, diskStore.getSize());
390
427
        manager.removeCache(cacheName);
391
428
 
392
 
        diskStore = createPersistentDiskStore(cacheName);
393
 
        File dataFile = ((DiskPersistentStore) diskStore).getDataFile();
 
429
        diskStore = getDiskStore(createPersistentDiskStore(cacheName));
 
430
        File dataFile = ((DiskStore) diskStore).getDataFile();
394
431
        assertTrue("File exists", dataFile.exists());
395
432
        assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
396
433
        assertEquals(100, diskStore.getSize());
408
445
 
409
446
        diskStore.put(new Element("key100", new byte[1024]));
410
447
        diskStore.flush();
411
 
        waitShorter();        
 
448
        waitShorter();
412
449
        assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
413
450
        assertEquals(100, diskStore.getSize());
414
451
    }
417
454
     * Tests that we can load a store after the index has been corrupted
418
455
     */
419
456
    @Test
420
 
    public void testLoadPersistentStoreAfterCorruption() throws IOException, InterruptedException {
 
457
    public void testLoadPersistentStoreAfterCorruption() throws Exception {
421
458
        //initialise
422
459
        String cacheName = "testPersistent";
423
 
        Store diskStore = createPersistentDiskStore(cacheName);
 
460
        DiskStore diskStore = getDiskStore(createPersistentDiskStore(cacheName));
424
461
        diskStore.removeAll();
425
462
 
426
463
 
428
465
            byte[] data = new byte[1024];
429
466
            diskStore.put(new Element("key" + (i + 100), data));
430
467
        }
431
 
        waitShorter();
432
 
        assertEquals(ELEMENT_ON_DISK_SIZE * 100, diskStore.getOnDiskSizeInBytes());
433
468
        assertEquals(100, diskStore.getSize());
434
469
        manager.removeCache(cacheName);
435
470
 
436
 
        File indexFile = ((DiskPersistentStore) diskStore).getIndexFile();
 
471
        File dataFile = diskStore.getDataFile();
 
472
        assertTrue(dataFile.length() >= 100 * ELEMENT_ON_DISK_SIZE);
 
473
 
 
474
        File indexFile = diskStore.getIndexFile();
437
475
        FileOutputStream fout = new FileOutputStream(indexFile);
438
476
        //corrupt the index file
439
477
        fout.write(new byte[]{'q', 'w', 'e', 'r', 't', 'y'});
440
478
        fout.close();
441
 
        diskStore = createPersistentDiskStore(cacheName);
442
 
        File dataFile = ((DiskPersistentStore) diskStore).getDataFile();
 
479
 
 
480
        diskStore = getDiskStore(createPersistentDiskStore(cacheName));
443
481
        assertTrue("File exists", dataFile.exists());
444
482
 
445
483
        //Make sure the data file got recreated since the index was corrupt
452
490
     * and delete and add data.
453
491
     */
454
492
    @Test
455
 
    public void testFreeSpaceBehaviour() throws IOException, InterruptedException {
 
493
    public void testFreeSpaceBehaviour() throws Exception {
456
494
        //initialise
457
495
        String cacheName = "testPersistent";
458
496
        Store diskStore = createPersistentDiskStore(cacheName);
468
506
        manager.removeCache(cacheName);
469
507
 
470
508
        diskStore = createPersistentDiskStore(cacheName);
471
 
        File dataFile = ((DiskPersistentStore) diskStore).getDataFile();
 
509
        File dataFile = getDiskStore(diskStore).getDataFile();
472
510
        assertTrue("File exists", dataFile.exists());
473
511
        assertEquals(100 * ELEMENT_ON_DISK_SIZE, dataFile.length());
474
512
        assertEquals(100, diskStore.getSize());
542
580
        diskStore.put(new Element("key1", value));
543
581
        diskStore.put(new Element("key2", value));
544
582
 
 
583
        Thread.sleep(1000);
 
584
 
545
585
        // Get the element
546
586
        assertEquals(2, diskStore.getSize());
547
 
        assertEquals(1, diskStore.getOnDiskSize());
548
 
        
 
587
        assertEquals(2, diskStore.getOnDiskSize());
 
588
 
549
589
        Element element1 = diskStore.get("key1");
550
590
        Element element2 = diskStore.get("key2");
551
591
        assertNotNull(element1);
563
603
        Cache cache = new Cache("testNonPersistent", 1, MemoryStoreEvictionPolicy.LFU, true,
564
604
                null, false, 2000, 1000, false, 1, null, null, 10);
565
605
        manager.addCache(cache);
566
 
        Store store = cache.getStore();
 
606
        final Store store = cache.getStore();
567
607
 
568
608
        Element element;
569
609
 
570
610
        assertEquals(0, store.getSize());
571
611
 
572
 
        for (int i = 0; i < 11; i++) {
573
 
            element = new Element("key" + i, "value" + i);
574
 
            cache.put(element);
 
612
        for (int i = 0; i < 10; i++) {
 
613
            cache.put(new Element("key" + i, "value" + i));
 
614
            assertBy(1, SECONDS, sizeOnDiskOf(store), Is.is(i + 1));
575
615
            if (i > 0) {
576
616
                cache.get("key" + i);
577
617
                cache.get("key" + i);
581
621
        }
582
622
 
583
623
        //allow to move through spool
584
 
        Thread.sleep(220);
585
 
        assertEquals(10, store.getOnDiskSize());
 
624
        assertBy(1, SECONDS, sizeOnDiskOf(store), Is.is(10));
586
625
 
587
626
        element = new Element("keyNew", "valueNew");
588
627
        store.put(element);
601
640
        //wait for spool to empty
602
641
        waitLonger();
603
642
 
604
 
        assertEquals(10, store.getOnDiskSize());
 
643
        assertBy(1, SECONDS, sizeOnDiskOf(store), Is.is(10));
605
644
    }
606
645
 
607
646
    /**
650
689
     */
651
690
    @Test
652
691
    public void testPutSlow() throws Exception {
653
 
        final CompoundStore diskStore = (CompoundStore) createDiskStore();
 
692
        final DiskStore diskStore = getDiskStore(createDiskStore());
654
693
 
655
694
        // Make sure the element is not found
656
695
        assertEquals(0, diskStore.getSize());
665
704
        waitShorter();
666
705
 
667
706
        // Get the element
668
 
        assertEquals(1, diskStore.getOnDiskSize());
 
707
        assertEquals(2, diskStore.getOnDiskSize());
669
708
        assertEquals(2, diskStore.getSize());
670
 
        
671
 
        Object o1 = diskStore.unretrievedGet("key1");
672
 
        Object o2 = diskStore.unretrievedGet("key2");
673
 
        if (o1 instanceof Element) {
674
 
            assertEquals("DiskMarker", o2.getClass().getSimpleName());
675
 
        } else if (o2 instanceof Element) {
676
 
            assertEquals("DiskMarker", o1.getClass().getSimpleName());
677
 
        } else {
678
 
            fail("One of the elements should be in memory");
679
 
        }
680
 
        
 
709
 
681
710
        Element element1 = diskStore.get("key1");
682
711
        Element element2 = diskStore.get("key2");
683
712
        assertNotNull(element1);
691
720
     */
692
721
    @Test
693
722
    public void testRemove() throws Exception {
694
 
        final Store diskStore = createDiskStore();
 
723
        final DiskStore diskStore = getDiskStore(createDiskStore());
695
724
 
696
725
        // Add the entry
697
726
        final String value = "value";
698
727
        diskStore.put(new Element("key1", value));
699
728
        diskStore.put(new Element("key2", value));
700
729
 
 
730
        Thread.sleep(1000);
 
731
 
701
732
        // Check the entry is there
702
 
        assertEquals(1, diskStore.getOnDiskSize());
 
733
        assertEquals(2, diskStore.getOnDiskSize());
703
734
        assertEquals(2, diskStore.getSize());
704
 
        
 
735
 
705
736
        assertNotNull(diskStore.get("key1"));
706
737
        assertNotNull(diskStore.get("key2"));
707
738
 
709
740
        diskStore.remove("key1");
710
741
        diskStore.remove("key2");
711
742
 
 
743
        waitShorter();
 
744
 
712
745
        // Check the entry is not there
713
746
        assertEquals(0, diskStore.getOnDiskSize());
714
747
        assertEquals(0, diskStore.getSize());
716
749
        assertNull(diskStore.get("key2"));
717
750
    }
718
751
 
 
752
    @Test
 
753
    public void testPersistentChangingPoolSizeBetweenRestarts() throws Exception {
 
754
        String diskStorePath = System.getProperty("java.io.tmpdir") + File.separatorChar + "testPersistentChangingPoolSizeBetweenRestarts";
 
755
        manager = new CacheManager(
 
756
                new Configuration()
 
757
                        .diskStore(new DiskStoreConfiguration().path(diskStorePath)).name("cm2")
 
758
 
 
759
        );
 
760
 
 
761
        manager.addCache(new Cache(
 
762
                new CacheConfiguration("persistentCache", 0)
 
763
                        .overflowToDisk(true)
 
764
                        .diskPersistent(true)
 
765
                )
 
766
        );
 
767
        Cache cache = manager.getCache("persistentCache");
 
768
 
 
769
        for (int i = 0; i < 500; i++) {
 
770
            cache.put(new Element(i, new byte[1024]));
 
771
        }
 
772
 
 
773
        assertEquals(500, cache.getSize());
 
774
 
 
775
        manager.shutdown();
 
776
 
 
777
        manager = new CacheManager(
 
778
                new Configuration()
 
779
                        .diskStore(new DiskStoreConfiguration().path(diskStorePath)
 
780
                ).name("cm2")
 
781
        );
 
782
 
 
783
        manager.addCache(new Cache(
 
784
                new CacheConfiguration("persistentCache", 0)
 
785
                        .overflowToDisk(true)
 
786
                        .diskPersistent(true)
 
787
                        .maxBytesLocalDisk(100, MemoryUnit.KILOBYTES)
 
788
                )
 
789
        );
 
790
        cache = manager.getCache("persistentCache");
 
791
 
 
792
        assertTrue(cache.getSize() <= 100);
 
793
 
 
794
        manager.shutdown();
 
795
    }
 
796
 
 
797
 
719
798
    /**
720
799
     * Tests removing an entry, after it has been written
721
800
     */
722
801
    @Test
723
802
    public void testRemoveSlow() throws Exception {
724
 
        final CompoundStore diskStore = (CompoundStore) createDiskStore();
 
803
        final DiskStore diskStore = getDiskStore(createDiskStore());
725
804
 
726
805
        // Add the entry
727
806
        final String value = "value";
732
811
        waitShorter();
733
812
 
734
813
        // Check the entry is there
735
 
        assertEquals(1, diskStore.getOnDiskSize());
 
814
        assertEquals(2, diskStore.getOnDiskSize());
736
815
        assertEquals(2, diskStore.getSize());
737
 
        Object o1 = diskStore.unretrievedGet("key1");
738
 
        Object o2 = diskStore.unretrievedGet("key2");
739
 
        if (o1 instanceof Element) {
740
 
            assertEquals("DiskMarker", o2.getClass().getSimpleName());
741
 
        } else if (o2 instanceof Element) {
742
 
            assertEquals("DiskMarker", o1.getClass().getSimpleName());
743
 
        } else {
744
 
            fail("One of the elements should be in memory");
745
 
        }
746
 
        
 
816
 
747
817
        // Remove it
748
818
        diskStore.remove("key1");
749
819
        diskStore.remove("key2");
760
830
     */
761
831
    @Test
762
832
    public void testRemoveAll() throws Exception {
763
 
        final Store diskStore = createDiskStore();
 
833
        final DiskStore diskStore = getDiskStore(createDiskStore());
764
834
 
765
835
        // Add the entry
766
836
        final String value = "value";
786
856
     */
787
857
    @Test
788
858
    public void testRemoveAllSlow() throws Exception {
789
 
        final CompoundStore diskStore = (CompoundStore) createDiskStore();
 
859
        final DiskStore diskStore = getDiskStore(createDiskStore());
790
860
 
791
861
        // Add the entry
792
862
        final String value = "value";
796
866
        // Wait
797
867
        waitShorter();
798
868
 
799
 
        // Check the entry is there
800
 
        Object o1 = diskStore.unretrievedGet("key1");
801
 
        Object o2 = diskStore.unretrievedGet("key2");
802
 
        if (o1 instanceof Element) {
803
 
            assertEquals("DiskMarker", o2.getClass().getSimpleName());
804
 
        } else if (o2 instanceof Element) {
805
 
            assertEquals("DiskMarker", o1.getClass().getSimpleName());
806
 
        } else {
807
 
            fail("One of the elements should be in memory");
808
 
        }
809
 
 
810
869
        // Remove it
811
870
        diskStore.removeAll();
812
871
 
862
921
    @Test
863
922
    public void testExpiry() throws Exception {
864
923
        // Create a diskStore with a cranked up expiry thread
865
 
        final Store diskStore = createDiskStore();
 
924
        final DiskStore diskStore = getDiskStore(createDiskStore());
866
925
 
867
926
        // Add an element that will expire.
868
927
        diskStore.put(new Element("key1", "value", false, 1, 1));
869
928
        diskStore.put(new Element("key2", "value", false, 1, 1));
870
 
        assertNotNull(diskStore.get("key1"));
871
 
        assertNotNull(diskStore.get("key2"));
 
929
 
 
930
        //allow disk writer to finish
 
931
        Thread.sleep(200);
 
932
 
872
933
        assertEquals(2, diskStore.getSize());
873
 
        assertEquals(1, diskStore.getOnDiskSize());
 
934
        assertEquals(2, diskStore.getOnDiskSize());
874
935
 
875
936
        // Wait a couple of seconds
876
937
        Thread.sleep(3000);
878
939
        Element e1 = diskStore.get("key1");
879
940
        Element e2 = diskStore.get("key2");
880
941
 
881
 
        if (e1 != null) {
882
 
            assertNull(e2);
883
 
        } else if (e2 != null) {
884
 
            assertNull(e1);
885
 
        } else {
886
 
            fail("One of the Elements should have been in memory - and hence not be expired");
887
 
        }
 
942
        assertNull(e2);
 
943
        assertNull(e1);
888
944
    }
889
945
 
890
946
    /**
914
970
                diskStore.put(element);
915
971
            }
916
972
            waitLonger();
917
 
            int predictedSize = (ELEMENT_ON_DISK_SIZE + 68) * 100;
 
973
            int predictedSize = (ELEMENT_ON_DISK_SIZE + 82) * 100;
918
974
            long actualSize = diskStore.getOnDiskSizeInBytes();
919
975
            LOG.info("Predicted Size: " + predictedSize + " Actual Size: " + actualSize);
920
 
            assertEquals(predictedSize, actualSize);
 
976
            assertTrue(actualSize <= predictedSize);
921
977
            LOG.info("Memory Use: " + measureMemoryUse());
922
978
        }
923
979
    }
926
982
     * Waits for all spooled elements to be written to disk.
927
983
     */
928
984
    private static void waitShorter() throws InterruptedException {
929
 
        Thread.sleep((long) (300 + 100 * StopWatch.getSpeedAdjustmentFactor()));
 
985
        Thread.sleep((long) (300 + 100 * getSpeedAdjustmentFactor()));
 
986
    }
 
987
 
 
988
    private static float getSpeedAdjustmentFactor() {
 
989
        final String speedAdjustmentFactorString = PropertyUtil.extractAndLogProperty("net.sf.ehcache.speedAdjustmentFactor", System.getProperties());
 
990
        if (speedAdjustmentFactorString != null) {
 
991
            return Float.parseFloat(speedAdjustmentFactorString);
 
992
        } else {
 
993
            return 1;
 
994
        }
930
995
    }
931
996
 
932
997
 
934
999
     * Waits for all spooled elements to be written to disk.
935
1000
     */
936
1001
    private static void waitLonger() throws InterruptedException {
937
 
        Thread.sleep((long) (300 + 500 * StopWatch.getSpeedAdjustmentFactor()));
 
1002
        Thread.sleep((long) (300 + 500 * getSpeedAdjustmentFactor()));
938
1003
    }
939
1004
 
940
1005
 
976
1041
    @Test
977
1042
    public void testReadRemoveMultipleThreads() throws Exception {
978
1043
        final Random random = new Random();
979
 
        final Store diskStore = createDiskStore();
 
1044
        final Cache diskCache = createDiskCache();
980
1045
 
981
 
        diskStore.put(new Element("key", "value"));
 
1046
        diskCache.put(new Element("key", "value"));
982
1047
 
983
1048
        // Run a set of threads that get, put and remove an entry
984
1049
        final List executables = new ArrayList();
986
1051
            final Executable executable = new Executable() {
987
1052
                public void execute() throws Exception {
988
1053
                    for (int i = 0; i < 100; i++) {
989
 
                        diskStore.put(new Element("key" + random.nextInt(100), "value"));
 
1054
                        diskCache.put(new Element("key" + random.nextInt(100), "value"));
990
1055
                    }
991
1056
                }
992
1057
            };
996
1061
            final Executable executable = new Executable() {
997
1062
                public void execute() throws Exception {
998
1063
                    for (int i = 0; i < 100; i++) {
999
 
                        diskStore.remove("key" + random.nextInt(100));
 
1064
                        diskCache.remove("key" + random.nextInt(100));
1000
1065
                    }
1001
1066
                }
1002
1067
            };
1010
1075
    public void testReadRemoveMultipleThreadsMultipleStripes() throws Exception {
1011
1076
        for (int stripes = 0; stripes < 10; stripes++) {
1012
1077
            final Random random = new Random();
1013
 
            final Store diskStore = createStripedDiskStore(stripes);
1014
 
    
1015
 
            diskStore.put(new Element("key", "value"));
1016
 
    
1017
 
            // Run a set of threads that get, put and remove an entry
1018
 
            final List executables = new ArrayList();
1019
 
            for (int i = 0; i < 5; i++) {
1020
 
                final Executable executable = new Executable() {
1021
 
                    public void execute() throws Exception {
1022
 
                        for (int i = 0; i < 100; i++) {
1023
 
                            diskStore.put(new Element("key" + random.nextInt(100), "value"));
1024
 
                        }
1025
 
                    }
1026
 
                };
1027
 
                executables.add(executable);
1028
 
            }
1029
 
            for (int i = 0; i < 5; i++) {
1030
 
                final Executable executable = new Executable() {
1031
 
                    public void execute() throws Exception {
1032
 
                        for (int i = 0; i < 100; i++) {
1033
 
                            diskStore.remove("key" + random.nextInt(100));
1034
 
                        }
1035
 
                    }
1036
 
                };
1037
 
                executables.add(executable);
1038
 
            }
1039
 
    
1040
 
            runThreads(executables);
 
1078
            final Cache cache = createStripedDiskCache(stripes);
 
1079
            try {
 
1080
                cache.put(new Element("key", "value"));
 
1081
 
 
1082
                // Run a set of threads that get, put and remove an entry
 
1083
                final List executables = new ArrayList();
 
1084
                for (int i = 0; i < 5; i++) {
 
1085
                    final Executable executable = new Executable() {
 
1086
                        public void execute() throws Exception {
 
1087
                            for (int i = 0; i < 100; i++) {
 
1088
                                cache.put(new Element("key" + random.nextInt(100), "value"));
 
1089
                            }
 
1090
                        }
 
1091
                    };
 
1092
                    executables.add(executable);
 
1093
                }
 
1094
                for (int i = 0; i < 5; i++) {
 
1095
                    final Executable executable = new Executable() {
 
1096
                        public void execute() throws Exception {
 
1097
                            for (int i = 0; i < 100; i++) {
 
1098
                                cache.remove("key" + random.nextInt(100));
 
1099
                            }
 
1100
                        }
 
1101
                    };
 
1102
                    executables.add(executable);
 
1103
                }
 
1104
 
 
1105
                runThreads(executables);
 
1106
            } finally {
 
1107
                manager.removeCache(cache.getName());
 
1108
            }
1041
1109
        }
1042
1110
    }
1043
 
    
 
1111
 
1044
1112
    /**
1045
1113
     * Tests how data is written to a random access file.
1046
1114
     * <p/>
1069
1137
        return new RandomAccessFile(dataFile, "rw");
1070
1138
    }
1071
1139
 
1072
 
    /**
1073
 
     * Test overflow to disk = true, using 100000 records.
1074
 
     * 15 seconds v1.38 DiskStore
1075
 
     * 2 seconds v1.42 DiskStore
1076
 
     * Adjusted for change to laptop
1077
 
     */
1078
 
    @Test
1079
 
    public void testOverflowToDiskWithLargeNumberofCacheEntries() throws Exception {
1080
 
 
1081
 
        //Set size so the second element overflows to disk.
1082
 
        //Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 1, null);
1083
 
        Cache cache = new Cache(new CacheConfiguration("test", 1000)
1084
 
                .memoryStoreEvictionPolicy("LRU")
1085
 
                .eternal(true)
1086
 
                .overflowToDisk(true)
1087
 
                .timeToLiveSeconds(1)
1088
 
                .diskAccessStripes(1)
1089
 
                .diskExpiryThreadIntervalSeconds(60));
1090
 
        manager.addCache(cache);
1091
 
        int i = 0;
1092
 
        StopWatch stopWatch = new StopWatch();
1093
 
        for (; i < 100000; i++) {
1094
 
            cache.put(new Element("" + i,
1095
 
                    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1096
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1097
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1098
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1099
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
1100
 
        }
1101
 
        long time = stopWatch.getElapsedTime();
1102
 
        LOG.info("time: " + time);
1103
 
        assertTrue(4 < time);
1104
 
    }
1105
 
 
1106
1140
 
1107
1141
    /**
1108
1142
     * This test is designed to be used with a profiler to explore the ways in which DiskStore
1112
1146
    public void testOutOfMemoryErrorOnOverflowToDisk() throws Exception {
1113
1147
 
1114
1148
        //Set size so the second element overflows to disk.
1115
 
        Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 1, null);
 
1149
        Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, false, 500, 500, false, 1, null);
1116
1150
        manager.addCache(cache);
1117
1151
        int i = 0;
1118
1152
 
1127
1161
    }
1128
1162
 
1129
1163
    /**
1130
 
     * Test overflow to disk = true, using 100000 records.
1131
 
     * 35 seconds v1.38 DiskStore
1132
 
     * 26 seconds v1.42 DiskStore
1133
 
     */
1134
 
    @Test
1135
 
    public void testOverflowToDiskWithLargeNumberofCacheEntriesAndGets() throws Exception {
1136
 
 
1137
 
        //Set size so the second element overflows to disk.
1138
 
        //Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 60, null);
1139
 
        Cache cache = new Cache(new CacheConfiguration("test", 1000)
1140
 
                .memoryStoreEvictionPolicy("LRU")
1141
 
                .eternal(true)
1142
 
                .overflowToDisk(true)
1143
 
                .timeToLiveSeconds(1)
1144
 
                .diskAccessStripes(5)
1145
 
                .diskExpiryThreadIntervalSeconds(60));
1146
 
        manager.addCache(cache);
1147
 
        Random random = new Random();
1148
 
        StopWatch stopWatch = new StopWatch();
1149
 
        for (int i = 0; i < 100000; i++) {
1150
 
            cache.put(new Element("" + i,
1151
 
                    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1152
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1153
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1154
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1155
 
                            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
1156
 
 
1157
 
            cache.get("" + random.nextInt(100000));
1158
 
        }
1159
 
 
1160
 
 
1161
 
        long elapsed = stopWatch.getElapsedTime();
1162
 
        LOG.info("Elapsed time: " + elapsed / 1000);
1163
 
        Thread.sleep(500);
1164
 
        assertEquals(100000, cache.getSize());
1165
 
        assertTrue(23 < elapsed);
1166
 
        //Some entries may be in the Memory Store and Disk Store. cache.getSize removes dupes. a look at the
1167
 
        //disk store size directly does not.
1168
 
        assertTrue(99000 <= cache.getDiskStoreSize());
1169
 
    }
1170
 
 
1171
 
    /**
1172
 
     * Runs out of memory at 5,099,999 elements with the standard 64MB VM size on 32 bit architectures.
1173
 
     * Around 3,099,999 for AMD64. Why? See abstract citation below from
1174
 
     * http://www3.interscience.wiley.com/cgi-bin/abstract/111082816/ABSTRACT?CRETRY=1&SRETRY=0
1175
 
     * <pre>
1176
 
     * By running the PowerPC machine in both 32-bit and 64-bit mode we are able to compare 32-bit and 64-bit VMs.
1177
 
     * We conclude that the space an object takes in the heap in 64-bit mode is 39.3% larger on average than in
1178
 
     * 32-bit mode. We identify three reasons for this: (i) the larger pointer size, (ii) the increased header
1179
 
     * and (iii) the increased alignment. The minimally required heap size is 51.1% larger on average in 64-bit
1180
 
     * than in 32-bit mode. From our experimental setup using hardware performance monitors, we observe that 64-bit
1181
 
     * computing typically results in a significantly larger number of data cache misses at all levels of the memory
1182
 
     * hierarchy. In addition, we observe that when a sufficiently large heap is available, the IBM JDK 1.4.0 VM is
1183
 
     * 1.7% slower on average in 64-bit mode than in 32-bit mode. Copyright © 2005 John Wiley & Sons, Ltd.
1184
 
     * </pre>
1185
 
     * The reason that it is not infinite is because of a small amount of memory used (about 12 bytes) used for
1186
 
     * the disk store index in this case.
1187
 
     * <p/>
1188
 
     * Slow tests
1189
 
     */
1190
 
    @Test
1191
 
    @Ignore
1192
 
    public void testMaximumCacheEntriesIn64MBWithOverflowToDisk() throws Exception {
1193
 
 
1194
 
        Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 1, null);
1195
 
        manager.addCache(cache);
1196
 
        StopWatch stopWatch = new StopWatch();
1197
 
        int i = 0;
1198
 
        int j = 0;
1199
 
        Integer index = null;
1200
 
        try {
1201
 
            for (; i < 100; i++) {
1202
 
                for (j = 0; j < 100000; j++) {
1203
 
                    index = Integer.valueOf(((1000000 * i) + j));
1204
 
                    cache.put(new Element(index,
1205
 
                            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1206
 
                                    + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1207
 
                                    + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1208
 
                                    + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1209
 
                                    + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
1210
 
                }
1211
 
                //wait to write entries
1212
 
                int size = cache.getSize();
1213
 
                Thread.sleep(2000);
1214
 
            }
1215
 
            long elapsed = stopWatch.getElapsedTime();
1216
 
            LOG.info("Elapsed time: " + elapsed / 1000);
1217
 
            fail();
1218
 
        } catch (OutOfMemoryError e) {
1219
 
            LOG.info("All heap consumed after " + index + " entries created.");
1220
 
            int expectedMax = 3090000;
1221
 
            assertTrue("Achieved " + index.intValue() + " which was less than the expected value of " + expectedMax,
1222
 
                    index.intValue() >= expectedMax);
1223
 
        }
1224
 
    }
1225
 
 
1226
 
    /**
1227
 
     * Perf test used by Venkat Subramani
1228
 
     * Get took 119s with Cache svn21
1229
 
     * Get took 42s
1230
 
     * The change was to stop adding DiskStore retrievals into the MemoryStore. This made sense when the only
1231
 
     * policy was LRU. In the new version an Element, once evicted from the MemoryStore, stays in the DiskStore
1232
 
     * until expiry or removal. This avoids a lot of serialization overhead.
1233
 
     * <p/>
1234
 
     * Slow tests
1235
 
     * 235 with get. 91 for 1.2.3. 169 with remove.
1236
 
     *
1237
 
     * put 14, get 32
1238
 
     * put 13, get 19
1239
 
     *
1240
 
     */
1241
 
    //@Test
1242
 
    public void testLargePutGetPerformanceWithOverflowToDisk() throws Exception {
1243
 
 
1244
 
        Cache cache = new Cache("test", 1000, MemoryStoreEvictionPolicy.LRU, true, null, true, 500, 500, false, 10000, null);
1245
 
        manager.addCache(cache);
1246
 
        StopWatch stopWatch = new StopWatch();
1247
 
        int i = 0;
1248
 
        int j = 0;
1249
 
        Integer index;
1250
 
        for (; i < 5; i++) {
1251
 
            for (j = 0; j < 100000; j++) {
1252
 
                index = Integer.valueOf(((1000000 * i) + j));
1253
 
                cache.put(new Element(index,
1254
 
                        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1255
 
                                + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1256
 
                                + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1257
 
                                + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1258
 
                                + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
1259
 
            }
1260
 
        }
1261
 
        long elapsed = stopWatch.getElapsedTime();
1262
 
        long putTime = ((elapsed / 1000) - 10);
1263
 
        LOG.info("Put Elapsed time: " + putTime);
1264
 
        assertTrue(putTime < 20);
1265
 
 
1266
 
        //wait for Disk Store to finish spooling
1267
 
        while (cache.getStore().bufferFull()) {
1268
 
            Thread.sleep(2000);
1269
 
        }
1270
 
        Random random = new Random();
1271
 
        StopWatch getStopWatch = new StopWatch();
1272
 
        long getStart = stopWatch.getElapsedTime();
1273
 
 
1274
 
        for (int k = 0; k < 1000000; k++) {
1275
 
            Integer key = Integer.valueOf(random.nextInt(500000));
1276
 
            cache.get(key);
1277
 
        }
1278
 
 
1279
 
        long getElapsedTime = getStopWatch.getElapsedTime();
1280
 
        int time = (int) ((getElapsedTime - getStart) / 1000);
1281
 
        LOG.info("Get Elapsed time: " + time);
1282
 
 
1283
 
        assertTrue(time < 180);
1284
 
 
1285
 
 
1286
 
    }
1287
 
 
1288
 
    /**
1289
1164
     * Java is not consistent with trailing file separators, believe it or not!
1290
1165
     * http://www.rationalpi.com/blog/replyToComment.action?entry=1146628709626&comment=1155660875090
1291
1166
     * Can we fix c:\temp\\greg?
1295
1170
 
1296
1171
        String originalPath = "c:" + File.separator + "temp" + File.separator + File.separator + "greg";
1297
1172
        //Fix dup separator
1298
 
        String translatedPath = DiskStoreConfiguration.replaceToken(File.separator + File.separator,
1299
 
                File.separator, originalPath);
 
1173
        String translatedPath = new DiskStoreConfiguration().path(originalPath).getPath();
1300
1174
        assertEquals("c:" + File.separator + "temp" + File.separator + "greg", translatedPath);
1301
1175
        //Ignore single separators
1302
 
        translatedPath = DiskStoreConfiguration.replaceToken(File.separator + File.separator, File.separator, originalPath);
 
1176
        translatedPath = new DiskStoreConfiguration().path(translatedPath).getPath();
1303
1177
        assertEquals("c:" + File.separator + "temp" + File.separator + "greg", translatedPath);
1304
1178
 
1305
1179
        Thread.sleep(500);
1306
1180
    }
1307
1181
 
1308
1182
    @Test
1309
 
    public void testShrinkingAndGrowingDiskStore() throws InterruptedException {
1310
 
        OverflowToDiskStore store = (OverflowToDiskStore) createCapacityLimitedDiskStore();
 
1183
    public void testShrinkingAndGrowingDiskStore() throws Exception {
 
1184
        Store diskBackedMemoryStore = createCapacityLimitedDiskStore();
 
1185
        DiskStore store = getDiskStore(diskBackedMemoryStore);
 
1186
 
1311
1187
        int i = 0;
1312
1188
        store.put(new Element(Integer.valueOf(i++), new byte[100]));
1313
1189
        while (true) {
1324
1200
 
1325
1201
        LOG.info("Wait For Spool Thread To Finish");
1326
1202
        SECONDS.sleep(2);
1327
 
        
 
1203
 
1328
1204
        final int initialSize = store.getOnDiskSize();
1329
1205
        final int shrinkSize = initialSize / 2;
1330
 
        store.diskCapacityChanged(initialSize, shrinkSize);
 
1206
        store.changeDiskCapacity(shrinkSize);
1331
1207
        LOG.info("Resized : " + initialSize + " ==> " + shrinkSize);
1332
1208
 
1333
1209
        LOG.info("Wait For Spool Thread To Finish");
1334
1210
        SECONDS.sleep(2);
1335
1211
 
1336
 
        for (;; i++) {
 
1212
        for (; ; i++) {
1337
1213
            int beforeSize = store.getOnDiskSize();
1338
1214
            store.put(new Element(Integer.valueOf(i), new byte[100]));
1339
1215
            MILLISECONDS.sleep(500);
1347
1223
 
1348
1224
        LOG.info("Wait For Spool Thread To Finish");
1349
1225
        SECONDS.sleep(2);
1350
 
        
 
1226
 
1351
1227
        {
1352
1228
            int size = store.getOnDiskSize();
1353
1229
            assertTrue(size < (shrinkSize * 1.1));
1354
1230
            assertTrue(size > (shrinkSize * 0.9));
1355
1231
        }
1356
 
        
 
1232
 
1357
1233
        final int growSize = initialSize * 2;
1358
 
        store.diskCapacityChanged(shrinkSize, growSize);
 
1234
        store.changeDiskCapacity(growSize);
1359
1235
        LOG.info("Resized : " + shrinkSize + " ==> " + growSize);
1360
 
        
 
1236
 
1361
1237
        LOG.info("Wait For Spool Thread To Finish");
1362
1238
        SECONDS.sleep(2);
1363
1239
 
1364
 
        for (;; i++) {
 
1240
        for (; ; i++) {
1365
1241
            int beforeSize = store.getOnDiskSize();
1366
1242
            store.put(new Element(Integer.valueOf(i), new byte[100]));
1367
1243
            MILLISECONDS.sleep(500);
1382
1258
            assertTrue(size > (growSize * 0.9));
1383
1259
        }
1384
1260
    }
 
1261
 
 
1262
    private DiskStore getDiskStore(Store diskBackedMemoryStore) throws NoSuchFieldException, IllegalAccessException {
 
1263
        Field f = FrontEndCacheTier.class.getDeclaredField("authority");
 
1264
        f.setAccessible(true);
 
1265
        return (DiskStore) f.get(diskBackedMemoryStore);
 
1266
    }
 
1267
 
 
1268
    @Test
 
1269
    public void testDiskPersistentExpiryThreadBehavior() {
 
1270
        CacheManager cacheManager = CacheManager.getInstance();
 
1271
        try {
 
1272
            CacheConfiguration configuration = new CacheConfiguration("testCache", 20);
 
1273
            configuration.setOverflowToDisk(true);
 
1274
            configuration.setTimeToIdleSeconds(10);
 
1275
            configuration.setDiskPersistent(true);
 
1276
            configuration.setDiskExpiryThreadIntervalSeconds(1);
 
1277
 
 
1278
            Cache cache = new Cache(configuration);
 
1279
            try {
 
1280
                cacheManager.addCache(cache);
 
1281
 
 
1282
                cache.put(new Element("1", "A value"));
 
1283
 
 
1284
                for (int i = 0; i < 20; i++) {
 
1285
                    if (cache.get("1") == null) {
 
1286
                        throw new AssertionError();
 
1287
                    }
 
1288
 
 
1289
                    try {
 
1290
                        Thread.sleep(1 * 1000);
 
1291
                    } catch (InterruptedException e) {
 
1292
                        //
 
1293
                    }
 
1294
                }
 
1295
            } finally {
 
1296
                cache.removeAll();
 
1297
            }
 
1298
        } finally {
 
1299
            cacheManager.shutdown();
 
1300
        }
 
1301
    }
1385
1302
}