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 java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23
24 import org.apache.hadoop.hbase.Cell;
25 import org.apache.hadoop.hbase.KeyValue.KVComparator;
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.util.ByteBufferUtils;
28 import org.apache.hadoop.hbase.util.Bytes;
29
30
31
32
33
34 @InterfaceAudience.Private
35 public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder {
36
37 private static class CopyKeyEncodingState extends EncodingState {
38 NoneEncoder encoder = null;
39 }
40
41 @Override
42 public void startBlockEncoding(HFileBlockEncodingContext blkEncodingCtx,
43 DataOutputStream out) throws IOException {
44 if (blkEncodingCtx.getClass() != HFileBlockDefaultEncodingContext.class) {
45 throw new IOException(this.getClass().getName() + " only accepts "
46 + HFileBlockDefaultEncodingContext.class.getName() + " as the "
47 + "encoding context.");
48 }
49
50 HFileBlockDefaultEncodingContext encodingCtx = (HFileBlockDefaultEncodingContext) blkEncodingCtx;
51 encodingCtx.prepareEncoding(out);
52
53 NoneEncoder encoder = new NoneEncoder(out, encodingCtx);
54 CopyKeyEncodingState state = new CopyKeyEncodingState();
55 state.encoder = encoder;
56 blkEncodingCtx.setEncodingState(state);
57 }
58
59 @Override
60 public int internalEncode(Cell cell,
61 HFileBlockDefaultEncodingContext encodingContext, DataOutputStream out)
62 throws IOException {
63 CopyKeyEncodingState state = (CopyKeyEncodingState) encodingContext
64 .getEncodingState();
65 NoneEncoder encoder = state.encoder;
66 return encoder.write(cell);
67 }
68
69 @Override
70 public ByteBuffer getFirstKeyInBlock(ByteBuffer block) {
71 int keyLength = block.getInt(Bytes.SIZEOF_INT);
72 ByteBuffer dup = block.duplicate();
73 int pos = 3 * Bytes.SIZEOF_INT;
74 dup.position(pos);
75 dup.limit(pos + keyLength);
76 return dup.slice();
77 }
78
79 @Override
80 public String toString() {
81 return CopyKeyDataBlockEncoder.class.getSimpleName();
82 }
83
84 @Override
85 public EncodedSeeker createSeeker(KVComparator comparator,
86 final HFileBlockDecodingContext decodingCtx) {
87 return new BufferedEncodedSeeker<SeekerState>(comparator, decodingCtx) {
88 @Override
89 protected void decodeNext() {
90 current.keyLength = currentBuffer.getInt();
91 current.valueLength = currentBuffer.getInt();
92 current.ensureSpaceForKey();
93 currentBuffer.get(current.keyBuffer, 0, current.keyLength);
94 current.valueOffset = currentBuffer.position();
95 ByteBufferUtils.skip(currentBuffer, current.valueLength);
96 if (includesTags()) {
97
98 current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
99 ByteBufferUtils.skip(currentBuffer, current.tagsLength);
100 }
101 if (includesMvcc()) {
102 current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
103 } else {
104 current.memstoreTS = 0;
105 }
106 current.nextKvOffset = currentBuffer.position();
107 }
108
109 @Override
110 protected void decodeFirst() {
111 ByteBufferUtils.skip(currentBuffer, Bytes.SIZEOF_INT);
112 current.lastCommonPrefix = 0;
113 decodeNext();
114 }
115 };
116 }
117
118 @Override
119 protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength,
120 int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException {
121 int decompressedSize = source.readInt();
122 ByteBuffer buffer = ByteBuffer.allocate(decompressedSize +
123 allocateHeaderLength);
124 buffer.position(allocateHeaderLength);
125 ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize);
126
127 return buffer;
128 }
129 }