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 org.apache.hadoop.fs.Path; 021import org.apache.hadoop.hbase.io.HeapSize; 022import org.apache.hadoop.hbase.io.hfile.bucket.FilePathStringPool; 023import org.apache.hadoop.hbase.util.ClassSize; 024import org.apache.hadoop.hbase.util.HFileArchiveUtil; 025import org.apache.yetus.audience.InterfaceAudience; 026 027/** 028 * Cache Key for use with implementations of {@link BlockCache} 029 */ 030@InterfaceAudience.Private 031public class BlockCacheKey implements HeapSize, java.io.Serializable { 032 private static final long serialVersionUID = -5199992013113130535L; // Changed due to format 033 // change 034 035 // New compressed format using integer file ID (when codec is available) 036 private final int hfileNameId; 037 038 private transient final FilePathStringPool stringPool; 039 040 private final int regionId; 041 042 private final int cfId; 043 044 private final long offset; 045 046 private BlockType blockType; 047 048 private final boolean isPrimaryReplicaBlock; 049 050 private final boolean archived; 051 052 /** 053 * Constructs a new BlockCacheKey with the file name and offset only. To be used for cache lookups 054 * only, DO NOT use this for creating keys when inserting into the cache. Use either the 055 * overriding constructors with the path parameter or the region and cf parameters, otherwise, 056 * region cache metrics won't be recorded properly. 057 * @param hfileName The name of the HFile this block belongs to. 058 * @param offset Offset of the block into the file 059 */ 060 public BlockCacheKey(String hfileName, long offset) { 061 this(hfileName, null, null, offset, true, BlockType.DATA, false); 062 } 063 064 /** 065 * Constructs a new BlockCacheKey with the file name, offset, replica and type only. To be used 066 * for cache lookups only, DO NOT use this for creating keys when inserting into the cache. Use 067 * either the overriding constructors with the path parameter or the region and cf parameters, 068 * otherwise, region cache metrics won't be recorded properly. 069 * @param hfileName The name of the HFile this block belongs to. 070 * @param offset Offset of the block into the file 071 * @param isPrimaryReplica Whether this is from primary replica 072 * @param blockType Type of block 073 */ 074 public BlockCacheKey(String hfileName, long offset, boolean isPrimaryReplica, 075 BlockType blockType) { 076 this(hfileName, null, null, offset, isPrimaryReplica, blockType, false); 077 } 078 079 /** 080 * Construct a new BlockCacheKey, with file, column family and region information. This should be 081 * used when inserting keys into the cache, so that region cache metrics are recorded properly. 082 * @param hfileName The name of the HFile this block belongs to. 083 * @param cfName The column family name 084 * @param regionName The region name 085 * @param offset Offset of the block into the file 086 * @param isPrimaryReplica Whether this is from primary replica 087 * @param blockType Type of block 088 */ 089 public BlockCacheKey(String hfileName, String cfName, String regionName, long offset, 090 boolean isPrimaryReplica, BlockType blockType, boolean archived) { 091 this.isPrimaryReplicaBlock = isPrimaryReplica; 092 this.offset = offset; 093 this.blockType = blockType; 094 this.stringPool = FilePathStringPool.getInstance(); 095 // Use string pool for file, region and cf values 096 this.hfileNameId = stringPool.encode(hfileName); 097 this.regionId = (regionName != null) ? stringPool.encode(regionName) : -1; 098 this.cfId = (cfName != null) ? stringPool.encode(cfName) : -1; 099 this.archived = archived; 100 } 101 102 /** 103 * Construct a new BlockCacheKey using a file path. File, column family and region information 104 * will be extracted from the passed path. This should be used when inserting keys into the cache, 105 * so that region cache metrics are recorded properly. 106 * @param hfilePath The path to the HFile 107 * @param offset Offset of the block into the file 108 * @param isPrimaryReplica Whether this is from primary replica 109 * @param blockType Type of block 110 */ 111 public BlockCacheKey(Path hfilePath, long offset, boolean isPrimaryReplica, BlockType blockType) { 112 this(hfilePath.getName(), hfilePath.getParent().getName(), 113 hfilePath.getParent().getParent().getName(), offset, isPrimaryReplica, blockType, 114 HFileArchiveUtil.isHFileArchived(hfilePath)); 115 } 116 117 @Override 118 public int hashCode() { 119 return hfileNameId * 127 + (int) (offset ^ (offset >>> 32)); 120 } 121 122 @Override 123 public boolean equals(Object o) { 124 if (o instanceof BlockCacheKey) { 125 BlockCacheKey k = (BlockCacheKey) o; 126 if (offset != k.offset) { 127 return false; 128 } 129 return getHfileName().equals(k.getHfileName()); 130 } 131 return false; 132 } 133 134 @Override 135 public String toString() { 136 return getHfileName() + '_' + this.offset; 137 } 138 139 public static final long FIXED_OVERHEAD = ClassSize.estimateBase(BlockCacheKey.class, false); 140 141 /** 142 * With the compressed format using integer file IDs, the heap size is significantly reduced. We 143 * now only store a 4-byte integer instead of the full file name string. 144 */ 145 @Override 146 public long heapSize() { 147 return ClassSize.align(FIXED_OVERHEAD); 148 } 149 150 /** 151 * Returns the hfileName portion of this cache key. 152 * @return The file name 153 */ 154 public String getHfileName() { 155 return stringPool.decode(hfileNameId); 156 } 157 158 /** 159 * Returns the region name portion of this cache key. 160 * @return The region name 161 */ 162 public String getRegionName() { 163 return stringPool.decode(regionId); 164 } 165 166 /** 167 * Returns the column family name portion of this cache key. 168 * @return The column family name 169 */ 170 public String getCfName() { 171 return stringPool.decode(cfId); 172 } 173 174 public boolean isPrimary() { 175 return isPrimaryReplicaBlock; 176 } 177 178 public long getOffset() { 179 return offset; 180 } 181 182 public BlockType getBlockType() { 183 return blockType; 184 } 185 186 public void setBlockType(BlockType blockType) { 187 this.blockType = blockType; 188 } 189 190 public boolean isArchived() { 191 return archived; 192 } 193 194}