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,
098               byte[] columnFamily, 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 : this.tableName != null ?
118      CellComparatorImpl.getCellComparator(this.tableName) : CellComparator.getInstance();
119  }
120
121  /**
122   * @return true when on-disk blocks are compressed, and/or encrypted; false otherwise.
123   */
124  public boolean isCompressedOrEncrypted() {
125    Compression.Algorithm compressAlgo = getCompression();
126    boolean compressed =
127      compressAlgo != null
128        && compressAlgo != Compression.Algorithm.NONE;
129
130    Encryption.Context cryptoContext = getEncryptionContext();
131    boolean encrypted = cryptoContext != null
132      && cryptoContext != Encryption.Context.NONE;
133
134    return compressed || encrypted;
135  }
136
137  public Compression.Algorithm getCompression() {
138    return compressAlgo;
139  }
140
141  public boolean isUseHBaseChecksum() {
142    return usesHBaseChecksum;
143  }
144
145  public boolean isIncludesMvcc() {
146    return includesMvcc;
147  }
148
149  public void setIncludesMvcc(boolean includesMvcc) {
150    this.includesMvcc = includesMvcc;
151  }
152
153  public boolean isIncludesTags() {
154    return includesTags;
155  }
156
157  public void setIncludesTags(boolean includesTags) {
158    this.includesTags = includesTags;
159  }
160
161  public void setFileCreateTime(long fileCreateTime) {
162    this.fileCreateTime = fileCreateTime;
163  }
164
165  public boolean isCompressTags() {
166    return compressTags;
167  }
168
169  public void setCompressTags(boolean compressTags) {
170    this.compressTags = compressTags;
171  }
172
173  public ChecksumType getChecksumType() {
174    return checksumType;
175  }
176
177  public int getBytesPerChecksum() {
178    return bytesPerChecksum;
179  }
180
181  public int getBlocksize() {
182    return blocksize;
183  }
184
185  public long getFileCreateTime() {
186    return fileCreateTime;
187  }
188
189  public DataBlockEncoding getDataBlockEncoding() {
190    return encoding;
191  }
192
193  public Encryption.Context getEncryptionContext() {
194    return cryptoContext;
195  }
196
197  public void setEncryptionContext(Encryption.Context cryptoContext) {
198    this.cryptoContext = cryptoContext;
199  }
200
201  public String getHFileName() {
202    return this.hfileName;
203  }
204
205  public byte[] getColumnFamily() {
206    return this.columnFamily;
207  }
208
209  public byte[] getTableName() {
210    return this.tableName;
211  }
212
213  public CellComparator getCellComparator() {
214    return this.cellComparator;
215  }
216
217  /**
218   * HeapSize implementation. NOTE : The heap size should be altered when new state variable are
219   * added.
220   * @return heap size of the HFileContext
221   */
222  @Override
223  public long heapSize() {
224    long size = FIXED_OVERHEAD;
225    if (this.hfileName != null) {
226      size += ClassSize.STRING + this.hfileName.length();
227    }
228    if (this.columnFamily != null){
229      size += ClassSize.sizeOfByteArray(this.columnFamily.length);
230    }
231    if (this.tableName != null){
232      size += ClassSize.sizeOfByteArray(this.tableName.length);
233    }
234    return size;
235  }
236
237  @Override
238  public HFileContext clone() {
239    try {
240      return (HFileContext)(super.clone());
241    } catch (CloneNotSupportedException e) {
242      throw new AssertionError(); // Won't happen
243    }
244  }
245
246  @Override
247  public String toString() {
248    StringBuilder sb = new StringBuilder();
249    sb.append("[");
250    sb.append("usesHBaseChecksum="); sb.append(usesHBaseChecksum);
251    sb.append(", checksumType=");      sb.append(checksumType);
252    sb.append(", bytesPerChecksum=");  sb.append(bytesPerChecksum);
253    sb.append(", blocksize=");         sb.append(blocksize);
254    sb.append(", encoding=");          sb.append(encoding);
255    sb.append(", includesMvcc=");      sb.append(includesMvcc);
256    sb.append(", includesTags=");      sb.append(includesTags);
257    sb.append(", compressAlgo=");      sb.append(compressAlgo);
258    sb.append(", compressTags=");      sb.append(compressTags);
259    sb.append(", cryptoContext=[");   sb.append(cryptoContext);      sb.append("]");
260    if (hfileName != null) {
261      sb.append(", name=");
262      sb.append(hfileName);
263    }
264    if (tableName != null) {
265      sb.append(", tableName=");
266      sb.append(Bytes.toStringBinary(tableName));
267    }
268    if (columnFamily != null) {
269      sb.append(", columnFamily=");
270      sb.append(Bytes.toStringBinary(columnFamily));
271    }
272    sb.append(", cellComparator=");
273    sb.append(this.cellComparator);
274    sb.append("]");
275    return sb.toString();
276  }
277}