View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with this
4    * work for additional information regarding copyright ownership. The ASF
5    * licenses this file to you under the Apache License, Version 2.0 (the
6    * "License"); you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14   * License for the specific language governing permissions and limitations
15   * under the License.
16   */
17  package org.apache.hadoop.hbase.io.hfile;
18  
19  import java.io.DataOutputStream;
20  import java.io.IOException;
21  
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.Cell;
24  import org.apache.hadoop.hbase.KeyValue;
25  import org.apache.hadoop.hbase.io.encoding.DataBlockEncoder;
26  import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
27  import org.apache.hadoop.hbase.io.encoding.HFileBlockDecodingContext;
28  import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultDecodingContext;
29  import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultEncodingContext;
30  import org.apache.hadoop.hbase.io.encoding.HFileBlockEncodingContext;
31  import org.apache.hadoop.hbase.io.hfile.HFile.FileInfo;
32  import org.apache.hadoop.hbase.util.Bytes;
33  
34  /**
35   * Do different kinds of data block encoding according to column family
36   * options.
37   */
38  @InterfaceAudience.Private
39  public class HFileDataBlockEncoderImpl implements HFileDataBlockEncoder {
40    private final DataBlockEncoding encoding;
41  
42    /**
43     * Do data block encoding with specified options.
44     * @param encoding What kind of data block encoding will be used.
45     */
46    public HFileDataBlockEncoderImpl(DataBlockEncoding encoding) {
47      this.encoding = encoding != null ? encoding : DataBlockEncoding.NONE;
48    }
49  
50    public static HFileDataBlockEncoder createFromFileInfo(
51        FileInfo fileInfo) throws IOException {
52      DataBlockEncoding encoding = DataBlockEncoding.NONE;
53      byte[] dataBlockEncodingType = fileInfo.get(DATA_BLOCK_ENCODING);
54      if (dataBlockEncodingType != null) {
55        String dataBlockEncodingStr = Bytes.toString(dataBlockEncodingType);
56        try {
57          encoding = DataBlockEncoding.valueOf(dataBlockEncodingStr);
58        } catch (IllegalArgumentException ex) {
59          throw new IOException("Invalid data block encoding type in file info: "
60            + dataBlockEncodingStr, ex);
61        }
62      }
63  
64      if (encoding == DataBlockEncoding.NONE) {
65        return NoOpDataBlockEncoder.INSTANCE;
66      }
67      return new HFileDataBlockEncoderImpl(encoding);
68    }
69  
70    @Override
71    public void saveMetadata(HFile.Writer writer) throws IOException {
72      writer.appendFileInfo(DATA_BLOCK_ENCODING, encoding.getNameInBytes());
73    }
74  
75    @Override
76    public DataBlockEncoding getDataBlockEncoding() {
77      return encoding;
78    }
79  
80    public boolean useEncodedScanner(boolean isCompaction) {
81      if (isCompaction && encoding == DataBlockEncoding.NONE) {
82        return false;
83      }
84      return encoding != DataBlockEncoding.NONE;
85    }
86  
87    @Override
88    public DataBlockEncoding getEffectiveEncodingInCache(boolean isCompaction) {
89      if (!useEncodedScanner(isCompaction)) {
90        return DataBlockEncoding.NONE;
91      }
92      return encoding;
93    }
94  
95    @Override
96    public int encode(Cell cell, HFileBlockEncodingContext encodingCtx, DataOutputStream out)
97        throws IOException {
98      return this.encoding.getEncoder().encode(cell, encodingCtx, out);
99    }
100 
101   @Override
102   public boolean useEncodedScanner() {
103     return encoding != DataBlockEncoding.NONE;
104   }
105 
106 
107   @Override
108   public String toString() {
109     return getClass().getSimpleName() + "(encoding=" + encoding + ")";
110   }
111 
112   @Override
113   public HFileBlockEncodingContext newDataBlockEncodingContext(
114       byte[] dummyHeader, HFileContext fileContext) {
115     DataBlockEncoder encoder = encoding.getEncoder();
116     if (encoder != null) {
117       return encoder.newDataBlockEncodingContext(encoding, dummyHeader, fileContext);
118     }
119     return new HFileBlockDefaultEncodingContext(null, dummyHeader, fileContext);
120   }
121 
122   @Override
123   public HFileBlockDecodingContext newDataBlockDecodingContext(HFileContext fileContext) {
124     DataBlockEncoder encoder = encoding.getEncoder();
125     if (encoder != null) {
126       return encoder.newDataBlockDecodingContext(fileContext);
127     }
128     return new HFileBlockDefaultDecodingContext(fileContext);
129   }
130 
131   @Override
132   public void startBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out)
133       throws IOException {
134     if (this.encoding != null && this.encoding != DataBlockEncoding.NONE) {
135       this.encoding.getEncoder().startBlockEncoding(encodingCtx, out);
136     }
137   }
138 
139   @Override
140   public void endBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out,
141       byte[] uncompressedBytesWithHeader, BlockType blockType) throws IOException {
142     this.encoding.getEncoder().endBlockEncoding(encodingCtx, out, uncompressedBytesWithHeader);
143   }
144 }