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