View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.io.hfile.slab;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.testclassification.MediumTests;
26  import org.apache.hadoop.hbase.io.hfile.CacheTestUtils;
27  import org.apache.hadoop.hbase.io.hfile.slab.SlabCache.SlabStats;
28  import org.junit.After;
29  import org.junit.Before;
30  import org.junit.Test;
31  import org.junit.experimental.categories.Category;
32  
33  /**
34   * Basic test of SlabCache. Puts and gets.
35   * <p>
36   *
37   * Tests will ensure that blocks that are uncached are identical to the ones
38   * being cached, and that the cache never exceeds its capacity. Note that its
39   * fine if the cache evicts before it reaches max capacity - Guava Mapmaker may
40   * choose to evict at any time.
41   *
42   */
43  // Starts 50 threads, high variability of execution time => Medium
44  @Category(MediumTests.class)
45  public class TestSlabCache {
46    static final int CACHE_SIZE = 1000000;
47    static final int NUM_BLOCKS = 101;
48    static final int BLOCK_SIZE = CACHE_SIZE / NUM_BLOCKS;
49    static final int NUM_THREADS = 50;
50    static final int NUM_QUERIES = 10000;
51    SlabCache cache;
52  
53    @Before
54    public void setup() {
55      cache = new SlabCache(CACHE_SIZE + BLOCK_SIZE * 2, BLOCK_SIZE);
56      cache.addSlabByConf(new Configuration());
57    }
58  
59    @After
60    public void tearDown() {
61      cache.shutdown();
62    }
63  
64    @Test
65    public void testElementPlacement() {
66      assertEquals(cache.getHigherBlock(BLOCK_SIZE).getKey().intValue(),
67          (BLOCK_SIZE * 11 / 10));
68      assertEquals(cache.getHigherBlock((BLOCK_SIZE * 2)).getKey()
69          .intValue(), (BLOCK_SIZE * 21 / 10));
70    }
71  
72   @Test
73    public void testCacheSimple() throws Exception {
74      CacheTestUtils.testCacheSimple(cache, BLOCK_SIZE, NUM_QUERIES);
75    }
76  
77    @Test
78    public void testCacheMultiThreaded() throws Exception {
79      CacheTestUtils.testCacheMultiThreaded(cache, BLOCK_SIZE, NUM_THREADS,
80          NUM_QUERIES, 0.80);
81    }
82  
83    @Test
84    public void testCacheMultiThreadedSingleKey() throws Exception {
85      CacheTestUtils.hammerSingleKey(cache, BLOCK_SIZE, NUM_THREADS, NUM_QUERIES);
86    }
87  
88    @Test
89    public void testCacheMultiThreadedEviction() throws Exception {
90      CacheTestUtils.hammerEviction(cache, BLOCK_SIZE, 10, NUM_QUERIES);
91    }
92  
93    @Test
94    /*Just checks if ranges overlap*/
95    public void testStatsArithmetic(){
96      SlabStats test = cache.requestStats;
97      for(int i = 0; i < test.NUMDIVISIONS; i++){
98        assertTrue("Upper for index " + i + " is " + test.getUpperBound(i) +
99            " lower " + test.getLowerBound(i + 1),
100           test.getUpperBound(i) <= test.getLowerBound(i + 1));
101     }
102   }
103 
104   @Test
105   public void testHeapSizeChanges(){
106     CacheTestUtils.testHeapSizeChanges(cache, BLOCK_SIZE);
107   }
108 
109 }
110