1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.io.hfile;
18
19 import java.io.IOException;
20 import java.nio.ByteBuffer;
21
22 import org.apache.hadoop.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
24 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoder;
25 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
26 import org.apache.hadoop.hbase.io.encoding.HFileBlockDecodingContext;
27 import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultDecodingContext;
28 import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultEncodingContext;
29 import org.apache.hadoop.hbase.io.encoding.HFileBlockEncodingContext;
30 import org.apache.hadoop.hbase.io.hfile.HFile.FileInfo;
31 import org.apache.hadoop.hbase.util.Bytes;
32
33
34
35
36
37 @InterfaceAudience.Private
38 public class HFileDataBlockEncoderImpl implements HFileDataBlockEncoder {
39 private final DataBlockEncoding encoding;
40
41
42
43
44
45 public HFileDataBlockEncoderImpl(DataBlockEncoding encoding) {
46 this.encoding = encoding != null ? encoding : DataBlockEncoding.NONE;
47 }
48
49 public static HFileDataBlockEncoder createFromFileInfo(
50 FileInfo fileInfo) throws IOException {
51 DataBlockEncoding encoding = DataBlockEncoding.NONE;
52 byte[] dataBlockEncodingType = fileInfo.get(DATA_BLOCK_ENCODING);
53 if (dataBlockEncodingType != null) {
54 String dataBlockEncodingStr = Bytes.toString(dataBlockEncodingType);
55 try {
56 encoding = DataBlockEncoding.valueOf(dataBlockEncodingStr);
57 } catch (IllegalArgumentException ex) {
58 throw new IOException("Invalid data block encoding type in file info: "
59 + dataBlockEncodingStr, ex);
60 }
61 }
62
63 if (encoding == DataBlockEncoding.NONE) {
64 return NoOpDataBlockEncoder.INSTANCE;
65 }
66 return new HFileDataBlockEncoderImpl(encoding);
67 }
68
69 @Override
70 public void saveMetadata(HFile.Writer writer) throws IOException {
71 writer.appendFileInfo(DATA_BLOCK_ENCODING, encoding.getNameInBytes());
72 }
73
74 @Override
75 public DataBlockEncoding getDataBlockEncoding() {
76 return encoding;
77 }
78
79
80
81
82
83
84
85
86 @Override
87 public void beforeWriteToDisk(ByteBuffer in,
88 boolean includesMemstoreTS,
89 HFileBlockEncodingContext encodeCtx,
90 BlockType blockType) throws IOException {
91 if (encoding == DataBlockEncoding.NONE) {
92
93 ((HFileBlockDefaultEncodingContext) encodeCtx).compressAfterEncodingWithBlockType(
94 in.array(), blockType);
95 return;
96 }
97 encodeBufferToHFileBlockBuffer(in, encoding,
98 includesMemstoreTS, encodeCtx);
99 }
100
101 @Override
102 public boolean useEncodedScanner() {
103 return encoding != DataBlockEncoding.NONE;
104 }
105
106
107
108
109
110
111
112
113
114 private void encodeBufferToHFileBlockBuffer(ByteBuffer in,
115 DataBlockEncoding algo, boolean includesMemstoreTS,
116 HFileBlockEncodingContext encodeCtx) {
117 DataBlockEncoder encoder = algo.getEncoder();
118 try {
119 encoder.encodeKeyValues(in, includesMemstoreTS, encodeCtx);
120 } catch (IOException e) {
121 throw new RuntimeException(String.format(
122 "Bug in data block encoder "
123 + "'%s', it probably requested too much data, " +
124 "exception message: %s.",
125 algo.toString(), e.getMessage()), e);
126 }
127 }
128
129 @Override
130 public String toString() {
131 return getClass().getSimpleName() + "(encoding=" + encoding + ")";
132 }
133
134 @Override
135 public HFileBlockEncodingContext newDataBlockEncodingContext(
136 Algorithm compressionAlgorithm, byte[] dummyHeader) {
137 DataBlockEncoder encoder = encoding.getEncoder();
138 if (encoder != null) {
139 return encoder.newDataBlockEncodingContext(
140 compressionAlgorithm, encoding, dummyHeader);
141 }
142 return new HFileBlockDefaultEncodingContext(
143 compressionAlgorithm, null, dummyHeader);
144 }
145
146 @Override
147 public HFileBlockDecodingContext newDataBlockDecodingContext(
148 Algorithm compressionAlgorithm) {
149 DataBlockEncoder encoder = encoding.getEncoder();
150 if (encoder != null) {
151 return encoder.newDataBlockDecodingContext(compressionAlgorithm);
152 }
153 return new HFileBlockDefaultDecodingContext(compressionAlgorithm);
154 }
155 }