View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with this
4    * work for additional information regarding copyright ownership. The ASF
5    * licenses this file to you under the Apache License, Version 2.0 (the
6    * "License"); you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14   * License for the specific language governing permissions and limitations
15   * under the License.
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.CellComparator;
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.nio.ByteBuff;
28  import org.apache.hadoop.hbase.util.ByteBufferUtils;
29  import org.apache.hadoop.hbase.util.Bytes;
30
31  /**
32   * Just copy data, do not do any kind of compression. Use for comparison and
33   * benchmarking.
34   */
35  @InterfaceAudience.Private
36  public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder {
37
38    private static class CopyKeyEncodingState extends EncodingState {
39      NoneEncoder encoder = null;
40    }
41  
42    @Override
43    public void startBlockEncoding(HFileBlockEncodingContext blkEncodingCtx,
44        DataOutputStream out) throws IOException {
45      if (blkEncodingCtx.getClass() != HFileBlockDefaultEncodingContext.class) {
46        throw new IOException(this.getClass().getName() + " only accepts "
47            + HFileBlockDefaultEncodingContext.class.getName() + " as the "
48            + "encoding context.");
49      }
50
51      HFileBlockDefaultEncodingContext encodingCtx = (HFileBlockDefaultEncodingContext) blkEncodingCtx;
52      encodingCtx.prepareEncoding(out);
53
54      NoneEncoder encoder = new NoneEncoder(out, encodingCtx);
55      CopyKeyEncodingState state = new CopyKeyEncodingState();
56      state.encoder = encoder;
57      blkEncodingCtx.setEncodingState(state);
58    }
59
60    @Override
61    public int internalEncode(Cell cell,
62        HFileBlockDefaultEncodingContext encodingContext, DataOutputStream out)
63        throws IOException {
64      CopyKeyEncodingState state = (CopyKeyEncodingState) encodingContext
65          .getEncodingState();
66      NoneEncoder encoder = state.encoder;
67      return encoder.write(cell);
68    }
69
70    @Override
71    public Cell getFirstKeyCellInBlock(ByteBuff block) {
72      int keyLength = block.getIntAfterPosition(Bytes.SIZEOF_INT);
73      int pos = 3 * Bytes.SIZEOF_INT;
74      ByteBuffer key = block.asSubByteBuffer(pos + keyLength).duplicate();
75      return createFirstKeyCell(key, keyLength);
76    }
77
78    @Override
79    public String toString() {
80      return CopyKeyDataBlockEncoder.class.getSimpleName();
81    }
82
83    @Override
84    public EncodedSeeker createSeeker(CellComparator 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          currentBuffer.skip(current.valueLength);
95          if (includesTags()) {
96            // Read short as unsigned, high byte first
97            current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
98            currentBuffer.skip(current.tagsLength);
99          }
100         if (includesMvcc()) {
101           current.memstoreTS = ByteBuff.readVLong(currentBuffer);
102         } else {
103           current.memstoreTS = 0;
104         }
105         current.nextKvOffset = currentBuffer.position();
106       }
107
108       @Override
109       protected void decodeFirst() {
110         currentBuffer.skip(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 }