View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.io.hfile;
19  
20  import org.apache.hadoop.hbase.classification.InterfaceAudience;
21  import org.apache.hadoop.hbase.io.HeapSize;
22  import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
23  import org.apache.hadoop.hbase.util.Bytes;
24  import org.apache.hadoop.hbase.util.ClassSize;
25  
26  /**
27   * Cache Key for use with implementations of {@link BlockCache}
28   */
29  @InterfaceAudience.Private
30  public class BlockCacheKey implements HeapSize, java.io.Serializable {
31    private static final long serialVersionUID = -5199992013113130534L;
32    private final String hfileName;
33    private final long offset;
34    private final DataBlockEncoding encoding;
35    private final BlockType blockType;
36  
37    public BlockCacheKey(String file, long offset, DataBlockEncoding encoding,
38        BlockType blockType) {
39      this.hfileName = file;
40      this.offset = offset;
41      // We add encoding to the cache key only for data blocks. If the block type
42      // is unknown (this should never be the case in production), we just use
43      // the provided encoding, because it might be a data block.
44      this.encoding = (encoding != null && (blockType == null
45        || blockType.isData())) ? encoding : DataBlockEncoding.NONE;
46      this.blockType = blockType;
47    }
48  
49    /**
50     * Construct a new BlockCacheKey
51     * @param file The name of the HFile this block belongs to.
52     * @param offset Offset of the block into the file
53     */
54    public BlockCacheKey(String hfileName, long offset) {
55      this(hfileName, offset, DataBlockEncoding.NONE, BlockType.DATA);
56    }
57  
58    @Override
59    public int hashCode() {
60      return hfileName.hashCode() * 127 + (int) (offset ^ (offset >>> 32)) +
61          encoding.ordinal() * 17;
62    }
63  
64    @Override
65    public boolean equals(Object o) {
66      if (o instanceof BlockCacheKey) {
67        BlockCacheKey k = (BlockCacheKey) o;
68        return offset == k.offset && encoding == k.encoding
69            && (hfileName == null ? k.hfileName == null : hfileName
70                .equals(k.hfileName));
71      } else {
72        return false;
73      }
74    }
75  
76    @Override
77    public String toString() {
78      return hfileName + "_" + offset
79          + (encoding == DataBlockEncoding.NONE ? "" : "_" + encoding);
80    }
81  
82    public static final long FIXED_OVERHEAD = ClassSize.align(
83        ClassSize.OBJECT +
84        ClassSize.REFERENCE + // this.hfileName
85        ClassSize.REFERENCE + // this.blockType
86        ClassSize.REFERENCE + // this.encoding
87        Bytes.SIZEOF_LONG);   // this.offset
88  
89    /**
90     * Strings have two bytes per character due to default Java Unicode encoding
91     * (hence length times 2).
92     */
93    @Override
94    public long heapSize() {
95      return ClassSize.align(FIXED_OVERHEAD + 2 * hfileName.length());
96    }
97  
98    // can't avoid this unfortunately
99    /**
100    * @return The hfileName portion of this cache key
101    */
102   public String getHfileName() {
103     return hfileName;
104   }
105 
106   public DataBlockEncoding getDataBlockEncoding() {
107     return encoding;
108   }
109 
110   public long getOffset() {
111     return offset;
112   }
113 
114   public BlockType getBlockType() {
115     return blockType;
116   }
117 }