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.hbase.CellComparator;
021import org.apache.hadoop.hbase.HConstants;
022import org.apache.hadoop.hbase.InnerStoreCellComparator;
023import org.apache.hadoop.hbase.io.HeapSize;
024import org.apache.hadoop.hbase.io.compress.Compression;
025import org.apache.hadoop.hbase.io.crypto.Encryption;
026import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
027import org.apache.hadoop.hbase.io.encoding.IndexBlockEncoding;
028import org.apache.hadoop.hbase.util.Bytes;
029import org.apache.hadoop.hbase.util.ChecksumType;
030import org.apache.hadoop.hbase.util.ClassSize;
031import org.apache.yetus.audience.InterfaceAudience;
032
033/**
034 * Read-only HFile Context Information. Meta data that is used by HFileWriter/Readers and by
035 * HFileBlocks. Create one using the {@link HFileContextBuilder} (See HFileInfo and the HFile
036 * Trailer class).
037 * @see HFileContextBuilder
038 */
039@InterfaceAudience.Private
040public class HFileContext implements HeapSize, Cloneable {
041  public static final long FIXED_OVERHEAD = ClassSize.estimateBase(HFileContext.class, false);
042
043  private static final int DEFAULT_BYTES_PER_CHECKSUM = 16 * 1024;
044
045  /** Whether checksum is enabled or not **/
046  private boolean usesHBaseChecksum = true;
047  /** Whether mvcc is to be included in the Read/Write **/
048  private boolean includesMvcc = true;
049  /** Whether tags are to be included in the Read/Write **/
050  private boolean includesTags;
051  /** Compression algorithm used **/
052  private Compression.Algorithm compressAlgo = Compression.Algorithm.NONE;
053  /** Whether tags to be compressed or not **/
054  private boolean compressTags;
055  /** the checksum type **/
056  private ChecksumType checksumType = ChecksumType.getDefaultChecksumType();
057  /** the number of bytes per checksum value **/
058  private int bytesPerChecksum = DEFAULT_BYTES_PER_CHECKSUM;
059  /** Number of uncompressed bytes we allow per block. */
060  private int blockSize = HConstants.DEFAULT_BLOCKSIZE;
061  private DataBlockEncoding encoding = DataBlockEncoding.NONE;
062  private IndexBlockEncoding indexBlockEncoding = IndexBlockEncoding.NONE;
063  /** Encryption algorithm and key used */
064  private Encryption.Context cryptoContext = Encryption.Context.NONE;
065  private long fileCreateTime;
066  private String hfileName;
067  private byte[] columnFamily;
068  private byte[] tableName;
069  private CellComparator cellComparator;
070
071  // Empty constructor. Go with setters
072  public HFileContext() {
073  }
074
075  /**
076   * Copy constructor
077   */
078  public HFileContext(HFileContext context) {
079    this.usesHBaseChecksum = context.usesHBaseChecksum;
080    this.includesMvcc = context.includesMvcc;
081    this.includesTags = context.includesTags;
082    this.compressAlgo = context.compressAlgo;
083    this.compressTags = context.compressTags;
084    this.checksumType = context.checksumType;
085    this.bytesPerChecksum = context.bytesPerChecksum;
086    this.blockSize = context.blockSize;
087    this.encoding = context.encoding;
088    this.cryptoContext = context.cryptoContext;
089    this.fileCreateTime = context.fileCreateTime;
090    this.hfileName = context.hfileName;
091    this.columnFamily = context.columnFamily;
092    this.tableName = context.tableName;
093    this.cellComparator = context.cellComparator;
094    this.indexBlockEncoding = context.indexBlockEncoding;
095  }
096
097  HFileContext(boolean useHBaseChecksum, boolean includesMvcc, boolean includesTags,
098    Compression.Algorithm compressAlgo, boolean compressTags, ChecksumType checksumType,
099    int bytesPerChecksum, int blockSize, DataBlockEncoding encoding,
100    Encryption.Context cryptoContext, long fileCreateTime, String hfileName, byte[] columnFamily,
101    byte[] tableName, CellComparator cellComparator, IndexBlockEncoding indexBlockEncoding) {
102    this.usesHBaseChecksum = useHBaseChecksum;
103    this.includesMvcc = includesMvcc;
104    this.includesTags = includesTags;
105    this.compressAlgo = compressAlgo;
106    this.compressTags = compressTags;
107    this.checksumType = checksumType;
108    this.bytesPerChecksum = bytesPerChecksum;
109    this.blockSize = blockSize;
110    if (encoding != null) {
111      this.encoding = encoding;
112    }
113    if (indexBlockEncoding != null) {
114      this.indexBlockEncoding = indexBlockEncoding;
115    }
116    this.cryptoContext = cryptoContext;
117    this.fileCreateTime = fileCreateTime;
118    this.hfileName = hfileName;
119    this.columnFamily = columnFamily;
120    this.tableName = tableName;
121    // If no cellComparator specified, make a guess based off tablename. If hbase:meta, then should
122    // be the meta table comparator. Comparators are per table.
123    this.cellComparator = cellComparator != null ? cellComparator
124      : this.tableName != null
125        ? InnerStoreCellComparator.getInnerStoreCellComparator(this.tableName)
126      : InnerStoreCellComparator.INNER_STORE_COMPARATOR;
127  }
128
129  /** Returns true when on-disk blocks are compressed, and/or encrypted; false otherwise. */
130  public boolean isCompressedOrEncrypted() {
131    Compression.Algorithm compressAlgo = getCompression();
132    boolean compressed = compressAlgo != null && compressAlgo != Compression.Algorithm.NONE;
133
134    Encryption.Context cryptoContext = getEncryptionContext();
135    boolean encrypted = cryptoContext != null && cryptoContext != Encryption.Context.NONE;
136
137    return compressed || encrypted;
138  }
139
140  public Compression.Algorithm getCompression() {
141    return compressAlgo;
142  }
143
144  public boolean isUseHBaseChecksum() {
145    return usesHBaseChecksum;
146  }
147
148  public boolean isIncludesMvcc() {
149    return includesMvcc;
150  }
151
152  public void setIncludesMvcc(boolean includesMvcc) {
153    this.includesMvcc = includesMvcc;
154  }
155
156  public boolean isIncludesTags() {
157    return includesTags;
158  }
159
160  public void setIncludesTags(boolean includesTags) {
161    this.includesTags = includesTags;
162  }
163
164  public void setFileCreateTime(long fileCreateTime) {
165    this.fileCreateTime = fileCreateTime;
166  }
167
168  public boolean isCompressTags() {
169    return compressTags;
170  }
171
172  public void setCompressTags(boolean compressTags) {
173    this.compressTags = compressTags;
174  }
175
176  public ChecksumType getChecksumType() {
177    return checksumType;
178  }
179
180  public int getBytesPerChecksum() {
181    return bytesPerChecksum;
182  }
183
184  public int getBlocksize() {
185    return blockSize;
186  }
187
188  public long getFileCreateTime() {
189    return fileCreateTime;
190  }
191
192  public DataBlockEncoding getDataBlockEncoding() {
193    return encoding;
194  }
195
196  public IndexBlockEncoding getIndexBlockEncoding() {
197    return indexBlockEncoding;
198  }
199
200  public Encryption.Context getEncryptionContext() {
201    return cryptoContext;
202  }
203
204  public void setEncryptionContext(Encryption.Context cryptoContext) {
205    this.cryptoContext = cryptoContext;
206  }
207
208  public String getHFileName() {
209    return this.hfileName;
210  }
211
212  public byte[] getColumnFamily() {
213    return this.columnFamily;
214  }
215
216  public byte[] getTableName() {
217    return this.tableName;
218  }
219
220  public CellComparator getCellComparator() {
221    return this.cellComparator;
222  }
223
224  /**
225   * HeapSize implementation. NOTE : The heap size should be altered when new state variable are
226   * added.
227   * @return heap size of the HFileContext
228   */
229  @Override
230  public long heapSize() {
231    long size = FIXED_OVERHEAD;
232    if (this.hfileName != null) {
233      size += ClassSize.STRING + this.hfileName.length();
234    }
235    if (this.columnFamily != null) {
236      size += ClassSize.sizeOfByteArray(this.columnFamily.length);
237    }
238    if (this.tableName != null) {
239      size += ClassSize.sizeOfByteArray(this.tableName.length);
240    }
241    return size;
242  }
243
244  @Override
245  public HFileContext clone() {
246    try {
247      return (HFileContext) super.clone();
248    } catch (CloneNotSupportedException e) {
249      throw new AssertionError(); // Won't happen
250    }
251  }
252
253  @Override
254  public String toString() {
255    StringBuilder sb = new StringBuilder();
256    sb.append("[");
257    sb.append("usesHBaseChecksum=");
258    sb.append(usesHBaseChecksum);
259    sb.append(", checksumType=");
260    sb.append(checksumType);
261    sb.append(", bytesPerChecksum=");
262    sb.append(bytesPerChecksum);
263    sb.append(", blocksize=");
264    sb.append(blockSize);
265    sb.append(", encoding=");
266    sb.append(encoding);
267    sb.append(", indexBlockEncoding=");
268    sb.append(indexBlockEncoding);
269    sb.append(", includesMvcc=");
270    sb.append(includesMvcc);
271    sb.append(", includesTags=");
272    sb.append(includesTags);
273    sb.append(", compressAlgo=");
274    sb.append(compressAlgo);
275    sb.append(", compressTags=");
276    sb.append(compressTags);
277    sb.append(", cryptoContext=[");
278    sb.append(cryptoContext);
279    sb.append("]");
280    if (hfileName != null) {
281      sb.append(", name=");
282      sb.append(hfileName);
283    }
284    if (tableName != null) {
285      sb.append(", tableName=");
286      sb.append(Bytes.toStringBinary(tableName));
287    }
288    if (columnFamily != null) {
289      sb.append(", columnFamily=");
290      sb.append(Bytes.toStringBinary(columnFamily));
291    }
292    sb.append(", cellComparator=");
293    sb.append(this.cellComparator);
294    sb.append("]");
295    return sb.toString();
296  }
297}