001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.io.hfile;
019
020import java.util.Iterator;
021import java.util.Map;
022import java.util.Optional;
023import org.apache.hadoop.fs.Path;
024import org.apache.hadoop.hbase.util.Pair;
025import org.apache.yetus.audience.InterfaceAudience;
026
027/**
028 * Block cache interface. Anything that implements the {@link Cacheable} interface can be put in the
029 * cache.
030 */
031@InterfaceAudience.Private
032public interface BlockCache extends Iterable<CachedBlock> {
033  /**
034   * Add block to cache.
035   * @param cacheKey The block's cache key.
036   * @param buf      The block contents wrapped in a ByteBuffer.
037   * @param inMemory Whether block should be treated as in-memory
038   */
039  void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory);
040
041  /**
042   * Add block to cache.
043   * @param cacheKey      The block's cache key.
044   * @param buf           The block contents wrapped in a ByteBuffer.
045   * @param inMemory      Whether block should be treated as in-memory
046   * @param waitWhenCache Whether to wait for the cache to be flushed mainly when BucketCache is
047   *                      configured.
048   */
049  default void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory,
050    boolean waitWhenCache) {
051    cacheBlock(cacheKey, buf, inMemory);
052  }
053
054  /**
055   * Add block to cache (defaults to not in-memory).
056   * @param cacheKey The block's cache key.
057   * @param buf      The object to cache.
058   */
059  void cacheBlock(BlockCacheKey cacheKey, Cacheable buf);
060
061  /**
062   * Fetch block from cache.
063   * @param cacheKey           Block to fetch.
064   * @param caching            Whether this request has caching enabled (used for stats)
065   * @param repeat             Whether this is a repeat lookup for the same block (used to avoid
066   *                           double counting cache misses when doing double-check locking)
067   * @param updateCacheMetrics Whether to update cache metrics or not
068   * @return Block or null if block is not in 2 cache.
069   */
070  Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat,
071    boolean updateCacheMetrics);
072
073  /**
074   * Evict block from cache.
075   * @param cacheKey Block to evict
076   * @return true if block existed and was evicted, false if not
077   */
078  boolean evictBlock(BlockCacheKey cacheKey);
079
080  /**
081   * Evicts all blocks for the given HFile.
082   * @return the number of blocks evicted
083   */
084  int evictBlocksByHfileName(String hfileName);
085
086  /**
087   * Get the statistics for this block cache.
088   */
089  CacheStats getStats();
090
091  /**
092   * Shutdown the cache.
093   */
094  void shutdown();
095
096  /**
097   * Returns the total size of the block cache, in bytes.
098   * @return size of cache, in bytes
099   */
100  long size();
101
102  /**
103   * Returns the Max size of the block cache, in bytes.
104   * @return size of cache, in bytes
105   */
106  long getMaxSize();
107
108  /**
109   * Returns the free size of the block cache, in bytes.
110   * @return free space in cache, in bytes
111   */
112  long getFreeSize();
113
114  /**
115   * Returns the occupied size of the block cache, in bytes.
116   * @return occupied space in cache, in bytes
117   */
118  long getCurrentSize();
119
120  /**
121   * Returns the occupied size of data blocks, in bytes.
122   * @return occupied space in cache, in bytes
123   */
124  long getCurrentDataSize();
125
126  /**
127   * Returns the number of blocks currently cached in the block cache.
128   * @return number of blocks in the cache
129   */
130  long getBlockCount();
131
132  /**
133   * Returns the number of data blocks currently cached in the block cache.
134   * @return number of blocks in the cache
135   */
136  long getDataBlockCount();
137
138  /** Returns Iterator over the blocks in the cache. */
139  @Override
140  Iterator<CachedBlock> iterator();
141
142  /** Returns The list of sub blockcaches that make up this one; returns null if no sub caches. */
143  BlockCache[] getBlockCaches();
144
145  /**
146   * Check if block type is meta or index block
147   * @param blockType block type of a given HFile block
148   * @return true if block type is non-data block
149   */
150  default boolean isMetaBlock(BlockType blockType) {
151    return blockType != null && blockType.getCategory() != BlockType.BlockCategory.DATA;
152  }
153
154  /**
155   * Notifies the cache implementation that the given file has been fully cached (all its blocks
156   * made into the cache).
157   * @param fileName the file that has been completely cached.
158   */
159  default void notifyFileCachingCompleted(Path fileName, int totalBlockCount, int dataBlockCount,
160    long size) {
161    // noop
162  }
163
164  /**
165   * Notifies the cache implementation that the given file had a block evicted
166   * @param fileName the file had a block evicted.
167   */
168  default void notifyFileBlockEvicted(String fileName) {
169    // noop
170  }
171
172  /**
173   * Checks whether there's enough space left in the cache to accommodate the passed block. This
174   * method may not be overridden by all implementing classes. In such cases, the returned Optional
175   * will be empty. For subclasses implementing this logic, the returned Optional would contain the
176   * boolean value reflecting if the passed block fits into the remaining cache space available.
177   * @param block the block we want to check if fits into the cache.
178   * @return empty optional if this method is not supported, otherwise the returned optional
179   *         contains the boolean value informing if the block fits into the cache available space.
180   */
181  default Optional<Boolean> blockFitsIntoTheCache(HFileBlock block) {
182    return Optional.empty();
183  }
184
185  /**
186   * Checks whether blocks for the passed file should be cached or not. This method may not be
187   * overridden by all implementing classes. In such cases, the returned Optional will be empty. For
188   * subclasses implementing this logic, the returned Optional would contain the boolean value
189   * reflecting if the passed file should indeed be cached.
190   * @param fileName to check if it should be cached.
191   * @return empty optional if this method is not supported, otherwise the returned optional
192   *         contains the boolean value informing if the file should be cached.
193   */
194  default Optional<Boolean> shouldCacheFile(String fileName) {
195    return Optional.empty();
196  }
197
198  /**
199   * Checks whether the block for the passed key is already cached. This method may not be
200   * overridden by all implementing classes. In such cases, the returned Optional will be empty. For
201   * subclasses implementing this logic, the returned Optional would contain the boolean value
202   * reflecting if the block for the passed key is already cached or not.
203   * @param key for the block we want to check if it's already in the cache.
204   * @return empty optional if this method is not supported, otherwise the returned optional
205   *         contains the boolean value informing if the block is already cached.
206   */
207  default Optional<Boolean> isAlreadyCached(BlockCacheKey key) {
208    return Optional.empty();
209  }
210
211  /**
212   * Returns an Optional containing the size of the block related to the passed key. If the block is
213   * not in the cache, returned optional will be empty. Also, this method may not be overridden by
214   * all implementing classes. In such cases, the returned Optional will be empty.
215   * @param key for the block we want to check if it's already in the cache.
216   * @return empty optional if this method is not supported, otherwise the returned optional
217   *         contains the boolean value informing if the block is already cached.
218   */
219  default Optional<Integer> getBlockSize(BlockCacheKey key) {
220    return Optional.empty();
221  }
222
223  /**
224   * Returns an Optional containing the map of files that have been fully cached (all its blocks are
225   * present in the cache. This method may not be overridden by all implementing classes. In such
226   * cases, the returned Optional will be empty.
227   * @return empty optional if this method is not supported, otherwise the returned optional
228   *         contains a map of all files that have been fully cached.
229   */
230  default Optional<Map<String, Pair<String, Long>>> getFullyCachedFiles() {
231    return Optional.empty();
232  }
233}