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.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   * Just copy data, do not do any kind of compression. Use for comparison and
32   * benchmarking.
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 BufferedEncodedSeeker<SeekerState>(comparator, decodingCtx) {
88        @Override
89        protected void decodeNext() {
90          current.keyLength = currentBuffer.getInt();
91          current.valueLength = currentBuffer.getInt();
92          current.ensureSpaceForKey();
93          currentBuffer.get(current.keyBuffer, 0, current.keyLength);
94          current.valueOffset = currentBuffer.position();
95          ByteBufferUtils.skip(currentBuffer, current.valueLength);
96          if (includesTags()) {
97            // Read short as unsigned, high byte first
98            current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
99            ByteBufferUtils.skip(currentBuffer, current.tagsLength);
100         }
101         if (includesMvcc()) {
102           current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
103         } else {
104           current.memstoreTS = 0;
105         }
106         current.nextKvOffset = currentBuffer.position();
107       }
108 
109       @Override
110       protected void decodeFirst() {
111         ByteBufferUtils.skip(currentBuffer, Bytes.SIZEOF_INT);
112         current.lastCommonPrefix = 0;
113         decodeNext();
114       }
115     };
116   }
117 
118   @Override
119   protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength,
120       int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException {
121     int decompressedSize = source.readInt();
122     ByteBuffer buffer = ByteBuffer.allocate(decompressedSize +
123         allocateHeaderLength);
124     buffer.position(allocateHeaderLength);
125     ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize);
126 
127     return buffer;
128   }
129 }