1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.io.hfile;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.nio.ByteBuffer;
25 import java.util.Random;
26
27 import org.apache.hadoop.hbase.SmallTests;
28 import org.apache.hadoop.hbase.io.HeapSize;
29 import org.apache.hadoop.hbase.io.hfile.LruBlockCache.EvictionThread;
30 import org.apache.hadoop.hbase.util.ClassSize;
31 import org.junit.Test;
32 import org.junit.experimental.categories.Category;
33
34
35
36
37
38
39
40
41 @Category(SmallTests.class)
42 public class TestLruBlockCache {
43
44
45 @Test
46 public void testBackgroundEvictionThread() throws Exception {
47 long maxSize = 100000;
48 int numBlocks = 9;
49 long blockSize = calculateBlockSizeDefault(maxSize, numBlocks);
50 assertTrue("calculateBlockSize appears broken.", blockSize * numBlocks <= maxSize);
51
52 LruBlockCache cache = new LruBlockCache(maxSize,blockSize);
53 EvictionThread evictionThread = cache.getEvictionThread();
54 assertTrue(evictionThread != null);
55
56 CachedItem[] blocks = generateFixedBlocks(numBlocks + 1, blockSize, "block");
57
58
59 while (!evictionThread.isEnteringRun()) {
60 Thread.sleep(1);
61 }
62
63
64 for (CachedItem block : blocks) {
65 cache.cacheBlock(block.cacheKey, block);
66 }
67
68
69 int n = 0;
70 while(cache.getStats().getEvictionCount() == 0) {
71 Thread.sleep(200);
72 assertTrue("Eviction never happened.", n++ < 20);
73 }
74
75
76
77
78
79
80
81
82 n = 0;
83 for (long prevCnt = 0
84 curCnt = cache.getBlockCount();
85 prevCnt != curCnt; prevCnt = curCnt, curCnt = cache.getBlockCount()) {
86 Thread.sleep(200);
87 assertTrue("Cache never stabilized.", n++ < 20);
88 }
89
90 long evictionCount = cache.getStats().getEvictionCount();
91 assertTrue(evictionCount >= 1);
92 System.out.println("Background Evictions run: " + evictionCount);
93 }
94
95 @Test
96 public void testCacheSimple() throws Exception {
97
98 long maxSize = 1000000;
99 long blockSize = calculateBlockSizeDefault(maxSize, 101);
100
101 LruBlockCache cache = new LruBlockCache(maxSize, blockSize);
102
103 CachedItem [] blocks = generateRandomBlocks(100, blockSize);
104
105 long expectedCacheSize = cache.heapSize();
106
107
108 for (CachedItem block : blocks) {
109 assertTrue(cache.getBlock(block.cacheKey, true, false, true) == null);
110 }
111
112
113 for (CachedItem block : blocks) {
114 cache.cacheBlock(block.cacheKey, block);
115 expectedCacheSize += block.cacheBlockHeapSize();
116 }
117
118
119 assertEquals(expectedCacheSize, cache.heapSize());
120
121
122 for (CachedItem block : blocks) {
123 HeapSize buf = cache.getBlock(block.cacheKey, true, false, true);
124 assertTrue(buf != null);
125 assertEquals(buf.heapSize(), block.heapSize());
126 }
127
128
129 assertEquals(expectedCacheSize, cache.heapSize());
130
131
132 for (CachedItem block : blocks) {
133 HeapSize buf = cache.getBlock(block.cacheKey, true, false, true);
134 assertTrue(buf != null);
135 assertEquals(buf.heapSize(), block.heapSize());
136 }
137
138
139 assertEquals(0, cache.getStats().getEvictionCount());
140 Thread t = new LruBlockCache.StatisticsThread(cache);
141 t.start();
142 t.join();
143 }
144
145 @Test
146 public void testCacheEvictionSimple() throws Exception {
147
148 long maxSize = 100000;
149 long blockSize = calculateBlockSizeDefault(maxSize, 10);
150
151 LruBlockCache cache = new LruBlockCache(maxSize,blockSize,false);
152
153 CachedItem [] blocks = generateFixedBlocks(10, blockSize, "block");
154
155 long expectedCacheSize = cache.heapSize();
156
157
158 for (CachedItem block : blocks) {
159 cache.cacheBlock(block.cacheKey, block);
160 expectedCacheSize += block.cacheBlockHeapSize();
161 }
162
163
164 assertEquals(1, cache.getStats().getEvictionCount());
165
166
167 assertTrue(expectedCacheSize >
168 (maxSize * LruBlockCache.DEFAULT_ACCEPTABLE_FACTOR));
169
170
171 assertTrue(cache.heapSize() < maxSize);
172
173
174 assertTrue(cache.heapSize() <
175 (maxSize * LruBlockCache.DEFAULT_ACCEPTABLE_FACTOR));
176
177
178 assertTrue(cache.getBlock(blocks[0].cacheKey, true, false, true) == null);
179 for(int i=1;i<blocks.length;i++) {
180 assertEquals(cache.getBlock(blocks[i].cacheKey, true, false, true),
181 blocks[i]);
182 }
183 }
184
185 @Test
186 public void testCacheEvictionTwoPriorities() throws Exception {
187
188 long maxSize = 100000;
189 long blockSize = calculateBlockSizeDefault(maxSize, 10);
190
191 LruBlockCache cache = new LruBlockCache(maxSize,blockSize,false);
192
193 CachedItem [] singleBlocks = generateFixedBlocks(5, 10000, "single");
194 CachedItem [] multiBlocks = generateFixedBlocks(5, 10000, "multi");
195
196 long expectedCacheSize = cache.heapSize();
197
198
199 for (CachedItem block : multiBlocks) {
200 cache.cacheBlock(block.cacheKey, block);
201 expectedCacheSize += block.cacheBlockHeapSize();
202 assertEquals(cache.getBlock(block.cacheKey, true, false, true), block);
203 }
204
205
206 for (CachedItem block : singleBlocks) {
207 cache.cacheBlock(block.cacheKey, block);
208 expectedCacheSize += block.heapSize();
209 }
210
211
212 assertEquals(cache.getStats().getEvictionCount(), 1);
213
214
215 assertEquals(cache.getStats().getEvictedCount(), 2);
216
217
218 assertTrue(expectedCacheSize >
219 (maxSize * LruBlockCache.DEFAULT_ACCEPTABLE_FACTOR));
220
221
222 assertTrue(cache.heapSize() <= maxSize);
223
224
225 assertTrue(cache.heapSize() <=
226 (maxSize * LruBlockCache.DEFAULT_ACCEPTABLE_FACTOR));
227
228
229
230
231
232 assertTrue(cache.getBlock(singleBlocks[0].cacheKey, true, false, true) == null);
233 assertTrue(cache.getBlock(multiBlocks[0].cacheKey, true, false, true) == null);
234
235
236 for(int i=1;i<4;i++) {
237 assertEquals(cache.getBlock(singleBlocks[i].cacheKey, true, false, true),
238 singleBlocks[i]);
239 assertEquals(cache.getBlock(multiBlocks[i].cacheKey, true, false, true),
240 multiBlocks[i]);
241 }
242 }
243
244 @Test
245 public void testCacheEvictionThreePriorities() throws Exception {
246
247 long maxSize = 100000;
248 long blockSize = calculateBlockSize(maxSize, 10);
249
250 LruBlockCache cache = new LruBlockCache(maxSize, blockSize, false,
251 (int)Math.ceil(1.2*maxSize/blockSize),
252 LruBlockCache.DEFAULT_LOAD_FACTOR,
253 LruBlockCache.DEFAULT_CONCURRENCY_LEVEL,
254 0.98f,
255 0.99f,
256 0.33f,
257 0.33f,
258 0.34f,
259 false);
260
261 CachedItem [] singleBlocks = generateFixedBlocks(5, blockSize, "single");
262 CachedItem [] multiBlocks = generateFixedBlocks(5, blockSize, "multi");
263 CachedItem [] memoryBlocks = generateFixedBlocks(5, blockSize, "memory");
264
265 long expectedCacheSize = cache.heapSize();
266
267
268 for(int i=0;i<3;i++) {
269
270
271 cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
272 expectedCacheSize += singleBlocks[i].cacheBlockHeapSize();
273
274
275 cache.cacheBlock(multiBlocks[i].cacheKey, multiBlocks[i]);
276 expectedCacheSize += multiBlocks[i].cacheBlockHeapSize();
277 cache.getBlock(multiBlocks[i].cacheKey, true, false, true);
278
279
280 cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true);
281 expectedCacheSize += memoryBlocks[i].cacheBlockHeapSize();
282
283 }
284
285
286 assertEquals(0, cache.getStats().getEvictionCount());
287
288
289 assertEquals(expectedCacheSize, cache.heapSize());
290
291
292 cache.cacheBlock(singleBlocks[3].cacheKey, singleBlocks[3]);
293
294
295 assertEquals(1, cache.getStats().getEvictionCount());
296 assertEquals(1, cache.getStats().getEvictedCount());
297
298
299 assertEquals(null, cache.getBlock(singleBlocks[0].cacheKey, true, false, true));
300
301
302 cache.getBlock(singleBlocks[1].cacheKey, true, false, true);
303
304
305 cache.cacheBlock(singleBlocks[4].cacheKey, singleBlocks[4]);
306
307
308 assertEquals(2, cache.getStats().getEvictionCount());
309 assertEquals(2, cache.getStats().getEvictedCount());
310
311
312 assertEquals(null, cache.getBlock(multiBlocks[0].cacheKey, true, false, true));
313
314
315 cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true);
316
317
318 assertEquals(3, cache.getStats().getEvictionCount());
319 assertEquals(3, cache.getStats().getEvictedCount());
320
321
322 assertEquals(null, cache.getBlock(memoryBlocks[0].cacheKey, true, false, true));
323
324
325 CachedItem [] bigBlocks = generateFixedBlocks(3, blockSize*3, "big");
326 cache.cacheBlock(bigBlocks[0].cacheKey, bigBlocks[0]);
327
328
329 assertEquals(4, cache.getStats().getEvictionCount());
330 assertEquals(6, cache.getStats().getEvictedCount());
331
332
333 assertEquals(null, cache.getBlock(singleBlocks[2].cacheKey, true, false, true));
334 assertEquals(null, cache.getBlock(singleBlocks[3].cacheKey, true, false, true));
335 assertEquals(null, cache.getBlock(singleBlocks[4].cacheKey, true, false, true));
336
337
338 cache.getBlock(bigBlocks[0].cacheKey, true, false, true);
339
340
341 cache.cacheBlock(bigBlocks[1].cacheKey, bigBlocks[1]);
342
343
344 assertEquals(5, cache.getStats().getEvictionCount());
345 assertEquals(9, cache.getStats().getEvictedCount());
346
347
348 assertEquals(null, cache.getBlock(singleBlocks[1].cacheKey, true, false, true));
349 assertEquals(null, cache.getBlock(multiBlocks[1].cacheKey, true, false, true));
350 assertEquals(null, cache.getBlock(multiBlocks[2].cacheKey, true, false, true));
351
352
353 cache.cacheBlock(bigBlocks[2].cacheKey, bigBlocks[2], true);
354
355
356 assertEquals(6, cache.getStats().getEvictionCount());
357 assertEquals(12, cache.getStats().getEvictedCount());
358
359
360 assertEquals(null, cache.getBlock(memoryBlocks[1].cacheKey, true, false, true));
361 assertEquals(null, cache.getBlock(memoryBlocks[2].cacheKey, true, false, true));
362 assertEquals(null, cache.getBlock(memoryBlocks[3].cacheKey, true, false, true));
363 }
364
365 @Test
366 public void testCacheEvictionInMemoryForceMode() throws Exception {
367 long maxSize = 100000;
368 long blockSize = calculateBlockSize(maxSize, 10);
369
370 LruBlockCache cache = new LruBlockCache(maxSize, blockSize, false,
371 (int)Math.ceil(1.2*maxSize/blockSize),
372 LruBlockCache.DEFAULT_LOAD_FACTOR,
373 LruBlockCache.DEFAULT_CONCURRENCY_LEVEL,
374 0.98f,
375 0.99f,
376 0.2f,
377 0.3f,
378 0.5f,
379 true);
380
381 CachedItem [] singleBlocks = generateFixedBlocks(10, blockSize, "single");
382 CachedItem [] multiBlocks = generateFixedBlocks(10, blockSize, "multi");
383 CachedItem [] memoryBlocks = generateFixedBlocks(10, blockSize, "memory");
384
385 long expectedCacheSize = cache.heapSize();
386
387
388 for(int i = 0; i < 4; i++) {
389
390 cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
391 expectedCacheSize += singleBlocks[i].cacheBlockHeapSize();
392
393 cache.cacheBlock(multiBlocks[i].cacheKey, multiBlocks[i]);
394 expectedCacheSize += multiBlocks[i].cacheBlockHeapSize();
395 cache.getBlock(multiBlocks[i].cacheKey, true, false, true);
396 }
397
398 cache.cacheBlock(singleBlocks[4].cacheKey, singleBlocks[4]);
399 expectedCacheSize += singleBlocks[4].cacheBlockHeapSize();
400
401 assertEquals(0, cache.getStats().getEvictionCount());
402
403 assertEquals(expectedCacheSize, cache.heapSize());
404
405
406 cache.cacheBlock(memoryBlocks[0].cacheKey, memoryBlocks[0], true);
407
408 assertEquals(1, cache.getStats().getEvictionCount());
409 assertEquals(1, cache.getStats().getEvictedCount());
410
411 assertEquals(null, cache.getBlock(singleBlocks[0].cacheKey, true, false, true));
412
413
414 cache.cacheBlock(memoryBlocks[1].cacheKey, memoryBlocks[1], true);
415
416 assertEquals(2, cache.getStats().getEvictionCount());
417 assertEquals(2, cache.getStats().getEvictedCount());
418
419 assertEquals(null, cache.getBlock(singleBlocks[1].cacheKey, true, false, true));
420
421
422 cache.cacheBlock(memoryBlocks[2].cacheKey, memoryBlocks[2], true);
423 cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true);
424 cache.cacheBlock(memoryBlocks[4].cacheKey, memoryBlocks[4], true);
425 cache.cacheBlock(memoryBlocks[5].cacheKey, memoryBlocks[5], true);
426
427 assertEquals(6, cache.getStats().getEvictionCount());
428 assertEquals(6, cache.getStats().getEvictedCount());
429
430 assertEquals(null, cache.getBlock(singleBlocks[2].cacheKey, true, false, true));
431 assertEquals(null, cache.getBlock(singleBlocks[3].cacheKey, true, false, true));
432 assertEquals(null, cache.getBlock(multiBlocks[0].cacheKey, true, false, true));
433 assertEquals(null, cache.getBlock(multiBlocks[1].cacheKey, true, false, true));
434
435
436
437 cache.cacheBlock(memoryBlocks[6].cacheKey, memoryBlocks[6], true);
438 cache.cacheBlock(memoryBlocks[7].cacheKey, memoryBlocks[7], true);
439 cache.cacheBlock(memoryBlocks[8].cacheKey, memoryBlocks[8], true);
440
441 assertEquals(9, cache.getStats().getEvictionCount());
442 assertEquals(9, cache.getStats().getEvictedCount());
443
444 assertEquals(null, cache.getBlock(singleBlocks[4].cacheKey, true, false, true));
445 assertEquals(null, cache.getBlock(multiBlocks[2].cacheKey, true, false, true));
446 assertEquals(null, cache.getBlock(multiBlocks[3].cacheKey, true, false, true));
447
448
449
450 cache.cacheBlock(memoryBlocks[9].cacheKey, memoryBlocks[9], true);
451
452 assertEquals(10, cache.getStats().getEvictionCount());
453 assertEquals(10, cache.getStats().getEvictedCount());
454
455 assertEquals(null, cache.getBlock(memoryBlocks[0].cacheKey, true, false, true));
456
457
458
459
460 cache.cacheBlock(singleBlocks[9].cacheKey, singleBlocks[9]);
461
462 assertEquals(11, cache.getStats().getEvictionCount());
463 assertEquals(11, cache.getStats().getEvictedCount());
464
465 assertEquals(null, cache.getBlock(singleBlocks[9].cacheKey, true, false, true));
466 }
467
468
469 @Test
470 public void testScanResistance() throws Exception {
471
472 long maxSize = 100000;
473 long blockSize = calculateBlockSize(maxSize, 10);
474
475 LruBlockCache cache = new LruBlockCache(maxSize, blockSize, false,
476 (int)Math.ceil(1.2*maxSize/blockSize),
477 LruBlockCache.DEFAULT_LOAD_FACTOR,
478 LruBlockCache.DEFAULT_CONCURRENCY_LEVEL,
479 0.66f,
480 0.99f,
481 0.33f,
482 0.33f,
483 0.34f,
484 false);
485
486 CachedItem [] singleBlocks = generateFixedBlocks(20, blockSize, "single");
487 CachedItem [] multiBlocks = generateFixedBlocks(5, blockSize, "multi");
488
489
490 for (CachedItem block : multiBlocks) {
491 cache.cacheBlock(block.cacheKey, block);
492 cache.getBlock(block.cacheKey, true, false, true);
493 }
494
495
496 for(int i=0;i<5;i++) {
497 cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
498 }
499
500
501 assertEquals(1, cache.getStats().getEvictionCount());
502
503
504 assertEquals(4, cache.getStats().getEvictedCount());
505
506
507 assertEquals(null, cache.getBlock(singleBlocks[0].cacheKey, true, false, true));
508 assertEquals(null, cache.getBlock(singleBlocks[1].cacheKey, true, false, true));
509 assertEquals(null, cache.getBlock(multiBlocks[0].cacheKey, true, false, true));
510 assertEquals(null, cache.getBlock(multiBlocks[1].cacheKey, true, false, true));
511
512
513
514
515
516
517
518
519 for(int i=5;i<18;i++) {
520 cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
521 }
522
523
524 assertEquals(4, cache.getStats().getEvictionCount());
525 assertEquals(16, cache.getStats().getEvictedCount());
526
527
528 assertEquals(7, cache.getBlockCount());
529
530 }
531
532
533 @Test
534 public void testResizeBlockCache() throws Exception {
535
536 long maxSize = 300000;
537 long blockSize = calculateBlockSize(maxSize, 31);
538
539 LruBlockCache cache = new LruBlockCache(maxSize, blockSize, false,
540 (int)Math.ceil(1.2*maxSize/blockSize),
541 LruBlockCache.DEFAULT_LOAD_FACTOR,
542 LruBlockCache.DEFAULT_CONCURRENCY_LEVEL,
543 0.98f,
544 0.99f,
545 0.33f,
546 0.33f,
547 0.34f,
548 false);
549
550 CachedItem [] singleBlocks = generateFixedBlocks(10, blockSize, "single");
551 CachedItem [] multiBlocks = generateFixedBlocks(10, blockSize, "multi");
552 CachedItem [] memoryBlocks = generateFixedBlocks(10, blockSize, "memory");
553
554
555 for(int i=0;i<10;i++) {
556
557
558 cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
559
560
561 cache.cacheBlock(multiBlocks[i].cacheKey, multiBlocks[i]);
562 cache.getBlock(multiBlocks[i].cacheKey, true, false, true);
563
564
565 cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true);
566 }
567
568
569 assertEquals(0, cache.getStats().getEvictionCount());
570
571
572 cache.setMaxSize((long)(maxSize * 0.5f));
573
574
575 assertEquals(1, cache.getStats().getEvictionCount());
576
577
578 assertEquals(15, cache.getStats().getEvictedCount());
579
580
581 for(int i=0;i<5;i++) {
582 assertEquals(null, cache.getBlock(singleBlocks[i].cacheKey, true, false, true));
583 assertEquals(null, cache.getBlock(multiBlocks[i].cacheKey, true, false, true));
584 assertEquals(null, cache.getBlock(memoryBlocks[i].cacheKey, true, false, true));
585 }
586
587
588 for(int i=5;i<10;i++) {
589 assertEquals(singleBlocks[i], cache.getBlock(singleBlocks[i].cacheKey, true, false, true));
590 assertEquals(multiBlocks[i], cache.getBlock(multiBlocks[i].cacheKey, true, false, true));
591 assertEquals(memoryBlocks[i], cache.getBlock(memoryBlocks[i].cacheKey, true, false, true));
592 }
593 }
594
595
596 @Test
597 public void testPastNPeriodsMetrics() throws Exception {
598 double delta = 0.01;
599
600
601 CacheStats stats = new CacheStats(3);
602
603
604 stats.rollMetricsPeriod();
605 assertEquals(0.0, stats.getHitRatioPastNPeriods(), delta);
606 assertEquals(0.0, stats.getHitCachingRatioPastNPeriods(), delta);
607
608
609
610 stats.hit(false);
611 stats.hit(true);
612 stats.miss(false);
613 stats.miss(false);
614 stats.rollMetricsPeriod();
615 assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta);
616 assertEquals(1.0, stats.getHitCachingRatioPastNPeriods(), delta);
617
618
619
620 stats.miss(true);
621 stats.miss(false);
622 stats.miss(false);
623 stats.miss(false);
624 stats.rollMetricsPeriod();
625 assertEquals(0.25, stats.getHitRatioPastNPeriods(), delta);
626 assertEquals(0.5, stats.getHitCachingRatioPastNPeriods(), delta);
627
628
629
630 stats.hit(false);
631 stats.hit(true);
632 stats.hit(false);
633 stats.hit(true);
634 stats.rollMetricsPeriod();
635 assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta);
636 assertEquals(0.75, stats.getHitCachingRatioPastNPeriods(), delta);
637
638
639
640 stats.miss(true);
641 stats.miss(true);
642 stats.rollMetricsPeriod();
643 assertEquals(0.4, stats.getHitRatioPastNPeriods(), delta);
644 assertEquals(0.4, stats.getHitCachingRatioPastNPeriods(), delta);
645
646
647
648 stats.miss(true);
649 stats.miss(true);
650 stats.hit(false);
651 stats.hit(false);
652 stats.rollMetricsPeriod();
653 assertEquals(0.6, stats.getHitRatioPastNPeriods(), delta);
654 assertEquals((double)1/3, stats.getHitCachingRatioPastNPeriods(), delta);
655
656
657
658 stats.rollMetricsPeriod();
659 assertEquals((double)1/3, stats.getHitRatioPastNPeriods(), delta);
660 assertEquals(0.0, stats.getHitCachingRatioPastNPeriods(), delta);
661
662
663
664 stats.rollMetricsPeriod();
665 assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta);
666 assertEquals(0.0, stats.getHitCachingRatioPastNPeriods(), delta);
667
668
669
670 stats.rollMetricsPeriod();
671 assertEquals(0.0, stats.getHitRatioPastNPeriods(), delta);
672 assertEquals(0.0, stats.getHitCachingRatioPastNPeriods(), delta);
673
674
675
676 stats.miss(true);
677 stats.miss(false);
678 stats.hit(true);
679 stats.hit(false);
680 stats.rollMetricsPeriod();
681 assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta);
682 assertEquals(0.5, stats.getHitCachingRatioPastNPeriods(), delta);
683 }
684
685 private CachedItem [] generateFixedBlocks(int numBlocks, int size, String pfx) {
686 CachedItem [] blocks = new CachedItem[numBlocks];
687 for(int i=0;i<numBlocks;i++) {
688 blocks[i] = new CachedItem(pfx + i, size);
689 }
690 return blocks;
691 }
692
693 private CachedItem [] generateFixedBlocks(int numBlocks, long size, String pfx) {
694 return generateFixedBlocks(numBlocks, (int)size, pfx);
695 }
696
697 private CachedItem [] generateRandomBlocks(int numBlocks, long maxSize) {
698 CachedItem [] blocks = new CachedItem[numBlocks];
699 Random r = new Random();
700 for(int i=0;i<numBlocks;i++) {
701 blocks[i] = new CachedItem("block" + i, r.nextInt((int)maxSize)+1);
702 }
703 return blocks;
704 }
705
706 private long calculateBlockSize(long maxSize, int numBlocks) {
707 long roughBlockSize = maxSize / numBlocks;
708 int numEntries = (int)Math.ceil((1.2)*maxSize/roughBlockSize);
709 long totalOverhead = LruBlockCache.CACHE_FIXED_OVERHEAD +
710 ClassSize.CONCURRENT_HASHMAP +
711 (numEntries * ClassSize.CONCURRENT_HASHMAP_ENTRY) +
712 (LruBlockCache.DEFAULT_CONCURRENCY_LEVEL * ClassSize.CONCURRENT_HASHMAP_SEGMENT);
713 long negateBlockSize = (long)(totalOverhead/numEntries);
714 negateBlockSize += LruCachedBlock.PER_BLOCK_OVERHEAD;
715 return ClassSize.align((long)Math.floor((roughBlockSize - negateBlockSize)*0.99f));
716 }
717
718 private long calculateBlockSizeDefault(long maxSize, int numBlocks) {
719 long roughBlockSize = maxSize / numBlocks;
720 int numEntries = (int)Math.ceil((1.2)*maxSize/roughBlockSize);
721 long totalOverhead = LruBlockCache.CACHE_FIXED_OVERHEAD +
722 ClassSize.CONCURRENT_HASHMAP +
723 (numEntries * ClassSize.CONCURRENT_HASHMAP_ENTRY) +
724 (LruBlockCache.DEFAULT_CONCURRENCY_LEVEL * ClassSize.CONCURRENT_HASHMAP_SEGMENT);
725 long negateBlockSize = totalOverhead / numEntries;
726 negateBlockSize += LruCachedBlock.PER_BLOCK_OVERHEAD;
727 return ClassSize.align((long)Math.floor((roughBlockSize - negateBlockSize)*
728 LruBlockCache.DEFAULT_ACCEPTABLE_FACTOR));
729 }
730
731 private static class CachedItem implements Cacheable {
732 BlockCacheKey cacheKey;
733 int size;
734
735 CachedItem(String blockName, int size) {
736 this.cacheKey = new BlockCacheKey(blockName, 0);
737 this.size = size;
738 }
739
740
741 @Override
742 public long heapSize() {
743 return ClassSize.align(size);
744 }
745
746
747 public long cacheBlockHeapSize() {
748 return LruCachedBlock.PER_BLOCK_OVERHEAD
749 + ClassSize.align(cacheKey.heapSize())
750 + ClassSize.align(size);
751 }
752
753 @Override
754 public int getSerializedLength() {
755 return 0;
756 }
757
758 @Override
759 public CacheableDeserializer<Cacheable> getDeserializer() {
760 return null;
761 }
762
763 @Override
764 public void serialize(ByteBuffer destination) {
765 }
766
767 @Override
768 public BlockType getBlockType() {
769 return BlockType.DATA;
770 }
771
772 }
773
774 }
775