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 SeekerStateBufferedEncodedSeeker(comparator, decodingCtx);
88    }
89  
90    @Override
91    protected ByteBuffer internalDecodeKeyValues(DataInputStream source, int allocateHeaderLength,
92        int skipLastBytes, HFileBlockDefaultDecodingContext decodingCtx) throws IOException {
93      int decompressedSize = source.readInt();
94      ByteBuffer buffer = ByteBuffer.allocate(decompressedSize +
95          allocateHeaderLength);
96      buffer.position(allocateHeaderLength);
97      ByteBufferUtils.copyFromStreamToBuffer(buffer, source, decompressedSize);
98  
99      return buffer;
100   }
101 
102   private static class SeekerStateBufferedEncodedSeeker
103       extends BufferedEncodedSeeker<SeekerState> {
104 
105     public SeekerStateBufferedEncodedSeeker(KVComparator comparator,
106       HFileBlockDecodingContext decodingCtx) {
107       super(comparator, decodingCtx);
108     }
109 
110     @Override
111     protected void decodeNext() {
112       current.keyLength = currentBuffer.getInt();
113       current.valueLength = currentBuffer.getInt();
114       current.ensureSpaceForKey();
115       currentBuffer.get(current.keyBuffer, 0, current.keyLength);
116       current.valueOffset = currentBuffer.position();
117       ByteBufferUtils.skip(currentBuffer, current.valueLength);
118       if (includesTags()) {
119         // Read short as unsigned, high byte first
120         current.tagsLength = ((currentBuffer.get() & 0xff) << 8) ^ (currentBuffer.get() & 0xff);
121         ByteBufferUtils.skip(currentBuffer, current.tagsLength);
122       }
123       if (includesMvcc()) {
124         current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
125       } else {
126         current.memstoreTS = 0;
127       }
128       current.nextKvOffset = currentBuffer.position();
129     }
130 
131     @Override
132     protected void decodeFirst() {
133       ByteBufferUtils.skip(currentBuffer, Bytes.SIZEOF_INT);
134       current.lastCommonPrefix = 0;
135       decodeNext();
136     }
137   }
138 }