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