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.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.Cell;
26 import org.apache.hadoop.hbase.CellUtil;
27 import org.apache.hadoop.hbase.KeyValue;
28 import org.apache.hadoop.hbase.KeyValueUtil;
29 import org.apache.hadoop.hbase.KeyValue.KVComparator;
30 import org.apache.hadoop.hbase.util.ByteBufferUtils;
31 import org.apache.hadoop.hbase.util.Bytes;
32 import org.apache.hadoop.io.WritableUtils;
33
34
35
36
37
38 @InterfaceAudience.Private
39 public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder {
40
41 @Override
42 public int internalEncode(Cell cell, HFileBlockDefaultEncodingContext encodingContext,
43 DataOutputStream out) throws IOException {
44 int klength = KeyValueUtil.keyLength(cell);
45 int vlength = cell.getValueLength();
46
47 out.writeInt(klength);
48 out.writeInt(vlength);
49 CellUtil.writeFlatKey(cell, out);
50 out.write(cell.getValueArray(), cell.getValueOffset(), vlength);
51 int size = klength + vlength + KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE;
52
53 if (encodingContext.getHFileContext().isIncludesTags()) {
54 int tagsLength = cell.getTagsLength();
55 out.writeShort(tagsLength);
56 if (tagsLength > 0) {
57 out.write(cell.getTagsArray(), cell.getTagsOffset(), tagsLength);
58 }
59 size += tagsLength + KeyValue.TAGS_LENGTH_SIZE;
60 }
61 if (encodingContext.getHFileContext().isIncludesMvcc()) {
62 WritableUtils.writeVLong(out, cell.getSequenceId());
63 size += WritableUtils.getVIntSize(cell.getSequenceId());
64 }
65 return size;
66 }
67
68 @Override
69 public ByteBuffer getFirstKeyInBlock(ByteBuffer block) {
70 int keyLength = block.getInt(Bytes.SIZEOF_INT);
71 ByteBuffer dup = block.duplicate();
72 int pos = 3 * Bytes.SIZEOF_INT;
73 dup.position(pos);
74 dup.limit(pos + keyLength);
75 return dup.slice();
76 }
77
78 @Override
79 public String toString() {
80 return CopyKeyDataBlockEncoder.class.getSimpleName();
81 }
82
83 @Override
84 public EncodedSeeker createSeeker(KVComparator comparator,
85 final HFileBlockDecodingContext decodingCtx) {
86 return new BufferedEncodedSeeker<SeekerState>(comparator, decodingCtx) {
87 @Override
88 protected void decodeNext() {
89 current.keyLength = currentBuffer.getInt();
90 current.valueLength = currentBuffer.getInt();
91 current.ensureSpaceForKey();
92 currentBuffer.get(current.keyBuffer, 0, current.keyLength);
93 current.valueOffset = currentBuffer.position();
94 ByteBufferUtils.skip(currentBuffer, current.valueLength);
95 if (includesTags()) {
96
97 current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
98 ByteBufferUtils.skip(currentBuffer, current.tagsLength);
99 }
100 if (includesMvcc()) {
101 current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
102 } else {
103 current.memstoreTS = 0;
104 }
105 current.nextKvOffset = currentBuffer.position();
106 }
107
108 @Override
109 protected void decodeFirst() {
110 ByteBufferUtils.skip(currentBuffer, Bytes.SIZEOF_INT);
111 current.lastCommonPrefix = 0;
112 decodeNext();
113 }
114 };
115 }
116
117 @Override
118 protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength,
119 int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException {
120 int decompressedSize = source.readInt();
121 ByteBuffer buffer = ByteBuffer.allocate(decompressedSize +
122 allocateHeaderLength);
123 buffer.position(allocateHeaderLength);
124 ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize);
125
126 return buffer;
127 }
128 }