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 SeekerStateBufferedEncodedSeeker(comparator, decodingCtx);
88 }
89
90 @Override
91 protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength,
92 int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException {
93 int decompressedSize = source.readInt();
94 ByteBuffer buffer = ByteBuffer.allocate(decompressedSize +
95 allocateHeaderLength);
96 buffer.position(allocateHeaderLength);
97 ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize);
98
99 return buffer;
100 }
101
102 private static class SeekerStateBufferedEncodedSeeker
103 extends BufferedEncodedSeeker<SeekerState> {
104
105 public SeekerStateBufferedEncodedSeeker(KVComparator comparator,
106 HFileBlockDecodingContext decodingCtx) {
107 super(comparator, decodingCtx);
108 }
109
110 @Override
111 protected void decodeNext() {
112 current.keyLength = currentBuffer.getInt();
113 current.valueLength = currentBuffer.getInt();
114 current.ensureSpaceForKey();
115 currentBuffer.get(current.keyBuffer, 0, current.keyLength);
116 current.valueOffset = currentBuffer.position();
117 ByteBufferUtils.skip(currentBuffer, current.valueLength);
118 if (includesTags()) {
119
120 current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
121 ByteBufferUtils.skip(currentBuffer, current.tagsLength);
122 }
123 if (includesMvcc()) {
124 current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
125 } else {
126 current.memstoreTS = 0;
127 }
128 current.nextKvOffset = currentBuffer.position();
129 }
130
131 @Override
132 protected void decodeFirst() {
133 ByteBufferUtils.skip(currentBuffer, Bytes.SIZEOF_INT);
134 current.lastCommonPrefix = 0;
135 decodeNext();
136 }
137 }
138 }