View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with this
6    * work for additional information regarding copyright ownership. The ASF
7    * licenses this file to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance with the License.
9    * 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, WITHOUT
15   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16   * License for the specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.io.hfile;
20  
21  import java.io.IOException;
22  import java.util.List;
23  
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.hbase.io.HeapSize;
27  import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
28  import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache;
29  
30  /**
31   * CombinedBlockCache is an abstraction layer that combines
32   * {@link LruBlockCache} and {@link BucketCache}. The smaller lruCache is used
33   * to cache bloom blocks and index blocks , the larger bucketCache is used to
34   * cache data blocks. getBlock reads first from the smaller lruCache before
35   * looking for the block in the bucketCache. Metrics are the combined size and
36   * hits and misses of both caches.
37   * 
38   **/
39  @InterfaceAudience.Private
40  public class CombinedBlockCache implements BlockCache, HeapSize {
41  
42    private final LruBlockCache lruCache;
43    private final BucketCache bucketCache;
44    private final CombinedCacheStats combinedCacheStats;
45  
46    public CombinedBlockCache(LruBlockCache lruCache, BucketCache bucketCache) {
47      this.lruCache = lruCache;
48      this.bucketCache = bucketCache;
49      this.combinedCacheStats = new CombinedCacheStats(lruCache.getStats(),
50          bucketCache.getStats());
51    }
52  
53    @Override
54    public long heapSize() {
55      return lruCache.heapSize() + bucketCache.heapSize();
56    }
57  
58    @Override
59    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
60      boolean isMetaBlock = buf.getBlockType().getCategory() != BlockCategory.DATA;
61      if (isMetaBlock) {
62        lruCache.cacheBlock(cacheKey, buf, inMemory);
63      } else {
64        bucketCache.cacheBlock(cacheKey, buf, inMemory);
65      }
66    }
67  
68    @Override
69    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
70      cacheBlock(cacheKey, buf, false);
71    }
72  
73    @Override
74    public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching,
75        boolean repeat) {
76      if (lruCache.containsBlock(cacheKey)) {
77        return lruCache.getBlock(cacheKey, caching, repeat);
78      }
79      return bucketCache.getBlock(cacheKey, caching, repeat);
80    }
81  
82    @Override
83    public boolean evictBlock(BlockCacheKey cacheKey) {
84      return lruCache.evictBlock(cacheKey) || bucketCache.evictBlock(cacheKey);
85    }
86  
87    @Override
88    public int evictBlocksByHfileName(String hfileName) {
89      return lruCache.evictBlocksByHfileName(hfileName)
90          + bucketCache.evictBlocksByHfileName(hfileName);
91    }
92  
93    @Override
94    public CacheStats getStats() {
95      return this.combinedCacheStats;
96    }
97  
98    @Override
99    public void shutdown() {
100     lruCache.shutdown();
101     bucketCache.shutdown();
102   }
103 
104   @Override
105   public long size() {
106     return lruCache.size() + bucketCache.size();
107   }
108 
109   @Override
110   public long getFreeSize() {
111     return lruCache.getFreeSize() + bucketCache.getFreeSize();
112   }
113 
114   @Override
115   public long getCurrentSize() {
116     return lruCache.getCurrentSize() + bucketCache.getCurrentSize();
117   }
118 
119   @Override
120   public long getEvictedCount() {
121     return lruCache.getEvictedCount() + bucketCache.getEvictedCount();
122   }
123 
124   @Override
125   public long getBlockCount() {
126     return lruCache.getBlockCount() + bucketCache.getBlockCount();
127   }
128 
129   @Override
130   public List<BlockCacheColumnFamilySummary> getBlockCacheColumnFamilySummaries(
131       Configuration conf) throws IOException {
132     throw new UnsupportedOperationException();
133   }
134 
135   private static class CombinedCacheStats extends CacheStats {
136     private final CacheStats lruCacheStats;
137     private final CacheStats bucketCacheStats;
138 
139     CombinedCacheStats(CacheStats lbcStats, CacheStats fcStats) {
140       this.lruCacheStats = lbcStats;
141       this.bucketCacheStats = fcStats;
142     }
143 
144     @Override
145     public long getRequestCount() {
146       return lruCacheStats.getRequestCount()
147           + bucketCacheStats.getRequestCount();
148     }
149 
150     @Override
151     public long getRequestCachingCount() {
152       return lruCacheStats.getRequestCachingCount()
153           + bucketCacheStats.getRequestCachingCount();
154     }
155 
156     @Override
157     public long getMissCount() {
158       return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount();
159     }
160 
161     @Override
162     public long getMissCachingCount() {
163       return lruCacheStats.getMissCachingCount()
164           + bucketCacheStats.getMissCachingCount();
165     }
166 
167     @Override
168     public long getHitCount() {
169       return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount();
170     }
171 
172     @Override
173     public long getHitCachingCount() {
174       return lruCacheStats.getHitCachingCount()
175           + bucketCacheStats.getHitCachingCount();
176     }
177 
178     @Override
179     public long getEvictionCount() {
180       return lruCacheStats.getEvictionCount()
181           + bucketCacheStats.getEvictionCount();
182     }
183 
184     @Override
185     public long getEvictedCount() {
186       return lruCacheStats.getEvictedCount()
187           + bucketCacheStats.getEvictedCount();
188     }
189 
190     @Override
191     public double getHitRatioPastNPeriods() {
192       double ratio = ((double) (lruCacheStats.getSumHitCountsPastNPeriods() + bucketCacheStats
193           .getSumHitCountsPastNPeriods()) / (double) (lruCacheStats
194           .getSumRequestCountsPastNPeriods() + bucketCacheStats
195           .getSumRequestCountsPastNPeriods()));
196       return Double.isNaN(ratio) ? 0 : ratio;
197     }
198 
199     @Override
200     public double getHitCachingRatioPastNPeriods() {
201       double ratio = ((double) (lruCacheStats
202           .getSumHitCachingCountsPastNPeriods() + bucketCacheStats
203           .getSumHitCachingCountsPastNPeriods()) / (double) (lruCacheStats
204           .getSumRequestCachingCountsPastNPeriods() + bucketCacheStats
205           .getSumRequestCachingCountsPastNPeriods()));
206       return Double.isNaN(ratio) ? 0 : ratio;
207     }
208   }
209 }