HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-common / src / main / java / org / apache / hadoop / hbase / codec / KeyValueCodec.java
blob19a80b07128f46c6fdcdcc8feaefe6d96aafce25
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.codec;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.ByteBuffer;
25 import org.apache.hadoop.hbase.Cell;
26 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
27 import org.apache.hadoop.hbase.KeyValueUtil;
28 import org.apache.hadoop.hbase.NoTagsByteBufferKeyValue;
29 import org.apache.hadoop.hbase.NoTagsKeyValue;
30 import org.apache.hadoop.hbase.nio.ByteBuff;
31 import org.apache.hadoop.hbase.util.ByteBufferUtils;
32 import org.apache.yetus.audience.InterfaceAudience;
34 /**
35 * Codec that does KeyValue version 1 serialization.
37 * <p>Encodes Cell as serialized in KeyValue with total length prefix.
38 * This is how KVs were serialized in Puts, Deletes and Results pre-0.96. Its what would
39 * happen if you called the Writable#write KeyValue implementation. This encoder will fail
40 * if the passed Cell is not an old-school pre-0.96 KeyValue. Does not copy bytes writing.
41 * It just writes them direct to the passed stream.
43 * <p>If you wrote two KeyValues to this encoder, it would look like this in the stream:
44 * <pre>
45 * length-of-KeyValue1 // A java int with the length of KeyValue1 backing array
46 * KeyValue1 backing array filled with a KeyValue serialized in its particular format
47 * length-of-KeyValue2
48 * KeyValue2 backing array
49 * </pre>
51 @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
52 public class KeyValueCodec implements Codec {
53 public static class KeyValueEncoder extends BaseEncoder {
54 public KeyValueEncoder(final OutputStream out) {
55 super(out);
58 @Override
59 public void write(Cell cell) throws IOException {
60 checkFlushed();
61 // Do not write tags over RPC
62 ByteBufferUtils.putInt(this.out, KeyValueUtil.getSerializedSize(cell, false));
63 KeyValueUtil.oswrite(cell, out, false);
67 public static class KeyValueDecoder extends BaseDecoder {
68 public KeyValueDecoder(final InputStream in) {
69 super(in);
72 @Override
73 protected Cell parseCell() throws IOException {
74 // No tags here
75 return KeyValueUtil.createKeyValueFromInputStream(in, false);
79 public static class ByteBuffKeyValueDecoder implements Codec.Decoder {
81 protected final ByteBuff buf;
82 protected Cell current = null;
84 public ByteBuffKeyValueDecoder(ByteBuff buf) {
85 this.buf = buf;
88 @Override
89 public boolean advance() throws IOException {
90 if (!this.buf.hasRemaining()) {
91 return false;
93 int len = buf.getInt();
94 ByteBuffer bb = buf.asSubByteBuffer(len);
95 if (bb.isDirect()) {
96 this.current = createCell(bb, bb.position(), len);
97 } else {
98 this.current = createCell(bb.array(), bb.arrayOffset() + bb.position(), len);
100 buf.skip(len);
101 return true;
104 @Override
105 public Cell current() {
106 return this.current;
109 protected Cell createCell(byte[] buf, int offset, int len) {
110 return new NoTagsKeyValue(buf, offset, len);
113 protected Cell createCell(ByteBuffer bb, int pos, int len) {
114 // We know there is not going to be any tags.
115 return new NoTagsByteBufferKeyValue(bb, pos, len);
120 * Implementation depends on {@link InputStream#available()}
122 @Override
123 public Decoder getDecoder(final InputStream is) {
124 return new KeyValueDecoder(is);
127 @Override
128 public Decoder getDecoder(ByteBuff buf) {
129 return new ByteBuffKeyValueDecoder(buf);
132 @Override
133 public Encoder getEncoder(OutputStream os) {
134 return new KeyValueEncoder(os);