1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.io.encoding;
18
19 import static org.apache.hadoop.hbase.io.compress.Compression.Algorithm.NONE;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.DataOutputStream;
23 import java.io.IOException;
24
25 import org.apache.hadoop.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.io.compress.Compression;
27 import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
28 import org.apache.hadoop.hbase.io.hfile.BlockType;
29 import org.apache.hadoop.io.compress.CompressionOutputStream;
30 import org.apache.hadoop.io.compress.Compressor;
31
32 import com.google.common.base.Preconditions;
33
34
35
36
37
38
39
40
41 @InterfaceAudience.Private
42 public class HFileBlockDefaultEncodingContext implements
43 HFileBlockEncodingContext {
44
45 private byte[] onDiskBytesWithHeader;
46 private byte[] uncompressedBytesWithHeader;
47 private BlockType blockType;
48 private final DataBlockEncoding encodingAlgo;
49
50
51 private Compressor compressor;
52
53
54 private CompressionOutputStream compressionStream;
55
56
57 private ByteArrayOutputStream compressedByteStream;
58
59
60 private final Compression.Algorithm compressionAlgorithm;
61
62 private ByteArrayOutputStream encodedStream = new ByteArrayOutputStream();
63 private DataOutputStream dataOut = new DataOutputStream(encodedStream);
64
65 private byte[] dummyHeader;
66
67
68
69
70
71
72 public HFileBlockDefaultEncodingContext(
73 Compression.Algorithm compressionAlgorithm,
74 DataBlockEncoding encoding, byte[] headerBytes) {
75 this.encodingAlgo = encoding;
76 this.compressionAlgorithm =
77 compressionAlgorithm == null ? NONE : compressionAlgorithm;
78 if (this.compressionAlgorithm != NONE) {
79 compressor = compressionAlgorithm.getCompressor();
80 compressedByteStream = new ByteArrayOutputStream();
81 try {
82 compressionStream =
83 compressionAlgorithm.createPlainCompressionStream(
84 compressedByteStream, compressor);
85 } catch (IOException e) {
86 throw new RuntimeException(
87 "Could not create compression stream for algorithm "
88 + compressionAlgorithm, e);
89 }
90 }
91 dummyHeader = Preconditions.checkNotNull(headerBytes,
92 "Please pass HConstants.HFILEBLOCK_DUMMY_HEADER instead of null for param headerBytes");
93 }
94
95 @Override
96 public void setDummyHeader(byte[] headerBytes) {
97 dummyHeader = headerBytes;
98 }
99
100
101
102
103
104 public void prepareEncoding() throws IOException {
105 encodedStream.reset();
106 dataOut.write(dummyHeader);
107 if (encodingAlgo != null
108 && encodingAlgo != DataBlockEncoding.NONE) {
109 encodingAlgo.writeIdInBytes(dataOut);
110 }
111 }
112
113 @Override
114 public void postEncoding(BlockType blockType)
115 throws IOException {
116 dataOut.flush();
117 compressAfterEncodingWithBlockType(encodedStream.toByteArray(), blockType);
118 this.blockType = blockType;
119 }
120
121
122
123
124
125
126 public void compressAfterEncodingWithBlockType(byte[] uncompressedBytesWithHeader,
127 BlockType blockType) throws IOException {
128 compressAfterEncoding(uncompressedBytesWithHeader, blockType, dummyHeader);
129 }
130
131
132
133
134
135
136
137 protected void compressAfterEncoding(byte[] uncompressedBytesWithHeader,
138 BlockType blockType, byte[] headerBytes) throws IOException {
139 this.uncompressedBytesWithHeader = uncompressedBytesWithHeader;
140 if (compressionAlgorithm != NONE) {
141 compressedByteStream.reset();
142 compressedByteStream.write(headerBytes);
143 compressionStream.resetState();
144 compressionStream.write(uncompressedBytesWithHeader,
145 headerBytes.length, uncompressedBytesWithHeader.length
146 - headerBytes.length);
147
148 compressionStream.flush();
149 compressionStream.finish();
150 onDiskBytesWithHeader = compressedByteStream.toByteArray();
151 } else {
152 onDiskBytesWithHeader = uncompressedBytesWithHeader;
153 }
154 this.blockType = blockType;
155 }
156
157 @Override
158 public byte[] getOnDiskBytesWithHeader() {
159 return onDiskBytesWithHeader;
160 }
161
162 @Override
163 public byte[] getUncompressedBytesWithHeader() {
164 return uncompressedBytesWithHeader;
165 }
166
167 @Override
168 public BlockType getBlockType() {
169 return blockType;
170 }
171
172
173
174
175
176 @Override
177 public void close() {
178 if (compressor != null) {
179 compressionAlgorithm.returnCompressor(compressor);
180 compressor = null;
181 }
182 }
183
184 @Override
185 public Algorithm getCompression() {
186 return this.compressionAlgorithm;
187 }
188
189 public DataOutputStream getOutputStreamForEncoder() {
190 return this.dataOut;
191 }
192
193 @Override
194 public DataBlockEncoding getDataBlockEncoding() {
195 return this.encodingAlgo;
196 }
197 }