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