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