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.util.Iterator;
22  
23  import org.apache.hadoop.hbase.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.io.HeapSize;
25  import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
26  import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache;
27  
28  
29  /**
30   * CombinedBlockCache is an abstraction layer that combines
31   * {@link LruBlockCache} and {@link BucketCache}. The smaller lruCache is used
32   * to cache bloom blocks and index blocks.  The larger l2Cache is used to
33   * cache data blocks. {@link #getBlock(BlockCacheKey, boolean, boolean, boolean)} reads
34   * first from the smaller lruCache before looking for the block in the l2Cache.  Blocks evicted
35   * from lruCache are put into the bucket cache. 
36   * Metrics are the combined size and hits and misses of both caches.
37   * 
38   */
39  @InterfaceAudience.Private
40  public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
41    protected final LruBlockCache lruCache;
42    protected final BlockCache l2Cache;
43    protected final CombinedCacheStats combinedCacheStats;
44  
45    public CombinedBlockCache(LruBlockCache lruCache, BlockCache l2Cache) {
46      this.lruCache = lruCache;
47      this.l2Cache = l2Cache;
48      this.combinedCacheStats = new CombinedCacheStats(lruCache.getStats(),
49          l2Cache.getStats());
50    }
51  
52    @Override
53    public long heapSize() {
54      long l2size = 0;
55      if (l2Cache instanceof HeapSize) {
56        l2size = ((HeapSize) l2Cache).heapSize();
57      }
58      return lruCache.heapSize() + l2size;
59    }
60  
61    @Override
62    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory,
63        final boolean cacheDataInL1) {
64      boolean metaBlock = buf.getBlockType().getCategory() != BlockCategory.DATA;
65      if (metaBlock || cacheDataInL1) {
66        lruCache.cacheBlock(cacheKey, buf, inMemory, cacheDataInL1);
67      } else {
68        l2Cache.cacheBlock(cacheKey, buf, inMemory, false);
69      }
70    }
71  
72    @Override
73    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
74      cacheBlock(cacheKey, buf, false, false);
75    }
76  
77    @Override
78    public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching,
79        boolean repeat, boolean updateCacheMetrics) {
80      // TODO: is there a hole here, or just awkwardness since in the lruCache getBlock
81      // we end up calling l2Cache.getBlock.
82      return lruCache.containsBlock(cacheKey)?
83          lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics):
84          l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics);
85    }
86  
87    @Override
88    public boolean evictBlock(BlockCacheKey cacheKey) {
89      return lruCache.evictBlock(cacheKey) || l2Cache.evictBlock(cacheKey);
90    }
91  
92    @Override
93    public int evictBlocksByHfileName(String hfileName) {
94      return lruCache.evictBlocksByHfileName(hfileName)
95          + l2Cache.evictBlocksByHfileName(hfileName);
96    }
97  
98    @Override
99    public CacheStats getStats() {
100     return this.combinedCacheStats;
101   }
102 
103   @Override
104   public void shutdown() {
105     lruCache.shutdown();
106     l2Cache.shutdown();
107   }
108 
109   @Override
110   public long size() {
111     return lruCache.size() + l2Cache.size();
112   }
113 
114   @Override
115   public long getFreeSize() {
116     return lruCache.getFreeSize() + l2Cache.getFreeSize();
117   }
118 
119   @Override
120   public long getCurrentSize() {
121     return lruCache.getCurrentSize() + l2Cache.getCurrentSize();
122   }
123 
124   @Override
125   public long getBlockCount() {
126     return lruCache.getBlockCount() + l2Cache.getBlockCount();
127   }
128 
129   public static class CombinedCacheStats extends CacheStats {
130     private final CacheStats lruCacheStats;
131     private final CacheStats bucketCacheStats;
132 
133     CombinedCacheStats(CacheStats lbcStats, CacheStats fcStats) {
134       super("CombinedBlockCache");
135       this.lruCacheStats = lbcStats;
136       this.bucketCacheStats = fcStats;
137     }
138 
139     @Override
140     public long getDataMissCount() {
141       return lruCacheStats.getDataMissCount() + bucketCacheStats.getDataMissCount();
142     }
143 
144     @Override
145     public long getLeafIndexMissCount() {
146       return lruCacheStats.getLeafIndexMissCount() + bucketCacheStats.getLeafIndexMissCount();
147     }
148 
149     @Override
150     public long getBloomChunkMissCount() {
151       return lruCacheStats.getBloomChunkMissCount() + bucketCacheStats.getBloomChunkMissCount();
152     }
153 
154     @Override
155     public long getMetaMissCount() {
156       return lruCacheStats.getMetaMissCount() + bucketCacheStats.getMetaMissCount();
157     }
158 
159     @Override
160     public long getRootIndexMissCount() {
161       return lruCacheStats.getRootIndexMissCount() + bucketCacheStats.getRootIndexMissCount();
162     }
163 
164     @Override
165     public long getIntermediateIndexMissCount() {
166       return lruCacheStats.getIntermediateIndexMissCount() +
167           bucketCacheStats.getIntermediateIndexMissCount();
168     }
169 
170     @Override
171     public long getFileInfoMissCount() {
172       return lruCacheStats.getFileInfoMissCount() + bucketCacheStats.getFileInfoMissCount();
173     }
174 
175     @Override
176     public long getGeneralBloomMetaMissCount() {
177       return lruCacheStats.getGeneralBloomMetaMissCount() +
178           bucketCacheStats.getGeneralBloomMetaMissCount();
179     }
180 
181     @Override
182     public long getDeleteFamilyBloomMissCount() {
183       return lruCacheStats.getDeleteFamilyBloomMissCount() +
184           bucketCacheStats.getDeleteFamilyBloomMissCount();
185     }
186 
187     @Override
188     public long getTrailerMissCount() {
189       return lruCacheStats.getTrailerMissCount() + bucketCacheStats.getTrailerMissCount();
190     }
191 
192     @Override
193     public long getDataHitCount() {
194       return lruCacheStats.getDataHitCount() + bucketCacheStats.getDataHitCount();
195     }
196 
197     @Override
198     public long getLeafIndexHitCount() {
199       return lruCacheStats.getLeafIndexHitCount() + bucketCacheStats.getLeafIndexHitCount();
200     }
201 
202     @Override
203     public long getBloomChunkHitCount() {
204       return lruCacheStats.getBloomChunkHitCount() + bucketCacheStats.getBloomChunkHitCount();
205     }
206 
207     @Override
208     public long getMetaHitCount() {
209       return lruCacheStats.getMetaHitCount() + bucketCacheStats.getMetaHitCount();
210     }
211 
212     @Override
213     public long getRootIndexHitCount() {
214       return lruCacheStats.getRootIndexHitCount() + bucketCacheStats.getRootIndexHitCount();
215     }
216 
217     @Override
218     public long getIntermediateIndexHitCount() {
219       return lruCacheStats.getIntermediateIndexHitCount() +
220           bucketCacheStats.getIntermediateIndexHitCount();
221     }
222 
223     @Override
224     public long getFileInfoHitCount() {
225       return lruCacheStats.getFileInfoHitCount() + bucketCacheStats.getFileInfoHitCount();
226     }
227 
228     @Override
229     public long getGeneralBloomMetaHitCount() {
230       return lruCacheStats.getGeneralBloomMetaHitCount() +
231           bucketCacheStats.getGeneralBloomMetaHitCount();
232     }
233 
234     @Override
235     public long getDeleteFamilyBloomHitCount() {
236       return lruCacheStats.getDeleteFamilyBloomHitCount() +
237           bucketCacheStats.getDeleteFamilyBloomHitCount();
238     }
239 
240     @Override
241     public long getTrailerHitCount() {
242       return lruCacheStats.getTrailerHitCount() + bucketCacheStats.getTrailerHitCount();
243     }
244 
245     @Override
246     public long getRequestCount() {
247       return lruCacheStats.getRequestCount()
248           + bucketCacheStats.getRequestCount();
249     }
250 
251     @Override
252     public long getRequestCachingCount() {
253       return lruCacheStats.getRequestCachingCount()
254           + bucketCacheStats.getRequestCachingCount();
255     }
256 
257     @Override
258     public long getMissCount() {
259       return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount();
260     }
261 
262     @Override
263     public long getPrimaryMissCount() {
264       return lruCacheStats.getPrimaryMissCount() + bucketCacheStats.getPrimaryMissCount();
265     }
266 
267     @Override
268     public long getMissCachingCount() {
269       return lruCacheStats.getMissCachingCount()
270           + bucketCacheStats.getMissCachingCount();
271     }
272 
273     @Override
274     public long getHitCount() {
275       return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount();
276     }
277 
278     @Override
279     public long getPrimaryHitCount() {
280       return lruCacheStats.getPrimaryHitCount() + bucketCacheStats.getPrimaryHitCount();
281     }
282     @Override
283     public long getHitCachingCount() {
284       return lruCacheStats.getHitCachingCount()
285           + bucketCacheStats.getHitCachingCount();
286     }
287 
288     @Override
289     public long getEvictionCount() {
290       return lruCacheStats.getEvictionCount()
291           + bucketCacheStats.getEvictionCount();
292     }
293 
294     @Override
295     public long getEvictedCount() {
296       return lruCacheStats.getEvictedCount()
297           + bucketCacheStats.getEvictedCount();
298     }
299 
300     @Override
301     public long getPrimaryEvictedCount() {
302       return lruCacheStats.getPrimaryEvictedCount()
303           + bucketCacheStats.getPrimaryEvictedCount();
304     }
305 
306     @Override
307     public void rollMetricsPeriod() {
308       lruCacheStats.rollMetricsPeriod();
309       bucketCacheStats.rollMetricsPeriod();
310     }
311     
312     @Override
313     public long getFailedInserts() {
314       return lruCacheStats.getFailedInserts() + bucketCacheStats.getFailedInserts();
315     }
316 
317     @Override
318     public long getSumHitCountsPastNPeriods() {
319       return lruCacheStats.getSumHitCountsPastNPeriods()
320           + bucketCacheStats.getSumHitCountsPastNPeriods();
321     }
322     
323     @Override
324     public long getSumRequestCountsPastNPeriods() {
325       return lruCacheStats.getSumRequestCountsPastNPeriods()
326           + bucketCacheStats.getSumRequestCountsPastNPeriods();
327     }
328     
329     @Override
330     public long getSumHitCachingCountsPastNPeriods() {
331       return lruCacheStats.getSumHitCachingCountsPastNPeriods()
332           + bucketCacheStats.getSumHitCachingCountsPastNPeriods();
333     }
334 
335     @Override
336     public long getSumRequestCachingCountsPastNPeriods() {
337       return lruCacheStats.getSumRequestCachingCountsPastNPeriods()
338           + bucketCacheStats.getSumRequestCachingCountsPastNPeriods();
339     }
340   }
341 
342   @Override
343   public Iterator<CachedBlock> iterator() {
344     return new BlockCachesIterator(getBlockCaches());
345   }
346 
347   @Override
348   public BlockCache[] getBlockCaches() {
349     return new BlockCache [] {this.lruCache, this.l2Cache};
350   }
351 
352   @Override
353   public void setMaxSize(long size) {
354     this.lruCache.setMaxSize(size);
355   }
356 }