001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.codec;
019
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.OutputStream;
023import java.nio.ByteBuffer;
024
025import org.apache.hadoop.hbase.ByteBufferKeyValue;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.HBaseInterfaceAudience;
028import org.apache.hadoop.hbase.KeyValue;
029import org.apache.hadoop.hbase.KeyValueUtil;
030import org.apache.hadoop.hbase.nio.ByteBuff;
031import org.apache.hadoop.hbase.util.ByteBufferUtils;
032import org.apache.yetus.audience.InterfaceAudience;
033
034/**
035 * Codec that does KeyValue version 1 serialization with serializing tags also.
036 *
037 * <p>
038 * Encodes Cell as serialized in KeyValue with total length prefix. This
039 * is how KVs were serialized in Puts, Deletes and Results pre-0.96. Its what would happen if you
040 * called the Writable#write KeyValue implementation. This encoder will fail if the passed Cell is
041 * not an old-school pre-0.96 KeyValue. Does not copy bytes writing. It just writes them direct to
042 * the passed stream.
043 *
044 * <p>
045 * If you wrote two KeyValues to this encoder, it would look like this in the stream:
046 *
047 * <pre>
048 * length-of-KeyValue1 // A java int with the length of KeyValue1 backing array
049 * KeyValue1 backing array filled with a KeyValue serialized in its particular format
050 * length-of-KeyValue2
051 * KeyValue2 backing array
052 * </pre>
053 *
054 * Note: The only difference of this with KeyValueCodec is the latter ignores tags in Cells.
055 * <b>Use this Codec only at server side.</b>
056 */
057@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
058public class KeyValueCodecWithTags implements Codec {
059  public static class KeyValueEncoder extends BaseEncoder {
060    public KeyValueEncoder(final OutputStream out) {
061      super(out);
062    }
063
064    @Override
065    public void write(Cell cell) throws IOException {
066      checkFlushed();
067      // Write tags
068      ByteBufferUtils.putInt(this.out, KeyValueUtil.getSerializedSize(cell, true));
069      KeyValueUtil.oswrite(cell, out, true);
070    }
071  }
072
073  public static class KeyValueDecoder extends BaseDecoder {
074    public KeyValueDecoder(final InputStream in) {
075      super(in);
076    }
077
078    @Override
079    protected Cell parseCell() throws IOException {
080      // create KeyValue with tags
081      return KeyValueUtil.createKeyValueFromInputStream(in, true);
082    }
083  }
084
085  public static class ByteBuffKeyValueDecoder extends KeyValueCodec.ByteBuffKeyValueDecoder {
086
087    public ByteBuffKeyValueDecoder(ByteBuff buf) {
088      super(buf);
089    }
090
091    @Override
092    protected Cell createCell(byte[] buf, int offset, int len) {
093      return new KeyValue(buf, offset, len);
094    }
095
096    @Override
097    protected Cell createCell(ByteBuffer bb, int pos, int len) {
098      return new ByteBufferKeyValue(bb, pos, len);
099    }
100  }
101
102  /**
103   * Implementation depends on {@link InputStream#available()}
104   */
105  @Override
106  public Decoder getDecoder(final InputStream is) {
107    return new KeyValueDecoder(is);
108  }
109
110  @Override
111  public Encoder getEncoder(OutputStream os) {
112    return new KeyValueEncoder(os);
113  }
114
115  @Override
116  public Decoder getDecoder(ByteBuff buf) {
117    return new ByteBuffKeyValueDecoder(buf);
118  }
119}