View Javadoc

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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  
19  package org.apache.hadoop.hbase.codec.prefixtree.decode;
20  
21  
22  import java.nio.ByteBuffer;
23  import org.apache.hadoop.hbase.ByteBufferedCell;
24  import org.apache.hadoop.hbase.Cell;
25  import org.apache.hadoop.hbase.CellComparator;
26  import org.apache.hadoop.hbase.CellUtil;
27  import org.apache.hadoop.hbase.KeyValue;
28  import org.apache.hadoop.hbase.KeyValueUtil;
29  import org.apache.hadoop.hbase.SettableSequenceId;
30  import org.apache.hadoop.hbase.classification.InterfaceAudience;
31  import org.apache.hadoop.hbase.nio.ByteBuff;
32  import org.apache.hadoop.hbase.util.ByteBufferUtils;
33  import org.apache.hadoop.hbase.util.Bytes;
34  import org.apache.hadoop.hbase.util.ObjectIntPair;
35  
36  /**
37   * As the PrefixTreeArrayScanner moves through the tree bytes, it changes the
38   * values in the fields of this class so that Cell logic can be applied, but
39   * without allocating new memory for every Cell iterated through.
40   */
41  @InterfaceAudience.Private
42  public class PrefixTreeCell extends ByteBufferedCell implements SettableSequenceId,
43      Comparable<Cell> {
44    // Create a reference here? Can be removed too
45    protected CellComparator comparator = CellComparator.COMPARATOR;
46  
47    /********************** static **********************/
48  
49    public static final KeyValue.Type[] TYPES = new KeyValue.Type[256];
50    static {
51      for (KeyValue.Type type : KeyValue.Type.values()) {
52        TYPES[type.getCode() & 0xff] = type;
53      }
54    }
55  
56    // Same as KeyValue constructor. Only used to avoid NPE's when full cell
57    // hasn't been initialized.
58    public static final KeyValue.Type DEFAULT_TYPE = KeyValue.Type.Put;
59  
60    /******************** fields ************************/
61  
62    protected ByteBuff block;
63    // we could also avoid setting the mvccVersion in the scanner/searcher, but
64    // this is simpler
65    protected boolean includeMvccVersion;
66  
67    protected byte[] rowBuffer;
68    protected int rowLength;
69  
70    protected byte[] familyBuffer;
71    protected int familyOffset;
72    protected int familyLength;
73  
74    protected byte[] qualifierBuffer;// aligned to the end of the array
75    protected int qualifierOffset;
76    protected int qualifierLength;
77  
78    protected Long timestamp;
79    protected Long mvccVersion;
80  
81    protected KeyValue.Type type;
82  
83    protected int absoluteValueOffset;
84    protected int valueLength;
85  
86    protected byte[] tagsBuffer;
87    protected int tagsOffset;
88    protected int tagsLength;
89    // Pair to set the value ByteBuffer and its offset
90    protected ObjectIntPair<ByteBuffer> pair = new ObjectIntPair<ByteBuffer>();
91  
92    /********************** Cell methods ******************/
93  
94    /**
95     * For debugging. Currently creates new KeyValue to utilize its toString()
96     * method.
97     */
98    @Override
99    public String toString() {
100     return getKeyValueString();
101   }
102 
103   @Override
104   public boolean equals(Object obj) {
105     if (!(obj instanceof Cell)) {
106       return false;
107     }
108     // Temporary hack to maintain backwards compatibility with KeyValue.equals
109     return CellUtil.equalsIgnoreMvccVersion(this, (Cell) obj);
110 
111     // TODO return CellComparator.equals(this, (Cell)obj);//see HBASE-6907
112   }
113 
114   @Override
115   public int hashCode() {
116     return calculateHashForKey(this);
117   }
118 
119   private int calculateHashForKey(Cell cell) {
120     // pre-calculate the 3 hashes made of byte ranges
121     int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
122     int familyHash = Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(),
123         cell.getFamilyLength());
124     int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
125         cell.getQualifierLength());
126 
127     // combine the 6 sub-hashes
128     int hash = 31 * rowHash + familyHash;
129     hash = 31 * hash + qualifierHash;
130     hash = 31 * hash + (int) cell.getTimestamp();
131     hash = 31 * hash + cell.getTypeByte();
132     return hash;
133   }
134 
135   @Override
136   public int compareTo(Cell other) {
137     return comparator.compare(this, other);
138   }
139 
140   @Override
141   public long getTimestamp() {
142     return timestamp;
143   }
144 
145   @Override
146   public long getSequenceId() {
147     if (!includeMvccVersion) {
148       return 0L;
149     }
150     return mvccVersion;
151   }
152 
153   @Override
154   public int getValueLength() {
155     return valueLength;
156   }
157 
158   @Override
159   public byte[] getRowArray() {
160     return rowBuffer;
161   }
162 
163   @Override
164   public int getRowOffset() {
165     return 0;
166   }
167 
168   @Override
169   public short getRowLength() {
170     return (short) rowLength;
171   }
172 
173   @Override
174   public byte[] getFamilyArray() {
175     return familyBuffer;
176   }
177 
178   @Override
179   public int getFamilyOffset() {
180     return familyOffset;
181   }
182 
183   @Override
184   public byte getFamilyLength() {
185     return (byte) familyLength;
186   }
187 
188   @Override
189   public byte[] getQualifierArray() {
190     return qualifierBuffer;
191   }
192 
193   @Override
194   public int getQualifierOffset() {
195     return qualifierOffset;
196   }
197 
198   @Override
199   public int getQualifierLength() {
200     return qualifierLength;
201   }
202 
203   @Override
204   public byte[] getValueArray() {
205     if (this.pair.getFirst().hasArray()) {
206       return this.pair.getFirst().array();
207     } else {
208       // Just in case getValueArray is called on offheap BB
209       byte[] val = new byte[valueLength];
210       ByteBufferUtils.copyFromBufferToArray(val, this.pair.getFirst(), this.pair.getSecond(), 0,
211         valueLength);
212       return val;
213     }
214   }
215 
216   @Override
217   public int getValueOffset() {
218     if (this.pair.getFirst().hasArray()) {
219       return this.pair.getSecond() + this.pair.getFirst().arrayOffset();
220     } else {
221       return 0;
222     }
223   }
224 
225   @Override
226   public byte getTypeByte() {
227     return type.getCode();
228   }
229 
230   /************************* helper methods *************************/
231 
232   /**
233    * Need this separate method so we can call it from subclasses' toString()
234    * methods
235    */
236   protected String getKeyValueString() {
237     KeyValue kv = KeyValueUtil.copyToNewKeyValue(this);
238     return kv.toString();
239   }
240 
241   @Override
242   public int getTagsOffset() {
243     return tagsOffset;
244   }
245 
246   @Override
247   public int getTagsLength() {
248     return tagsLength;
249   }
250 
251   @Override
252   public byte[] getTagsArray() {
253     return this.tagsBuffer;
254   }
255 
256   @Override
257   public void setSequenceId(long seqId) {
258     mvccVersion = seqId;
259   }
260 
261   @Override
262   public ByteBuffer getRowByteBuffer() {
263     return ByteBuffer.wrap(rowBuffer);
264   }
265 
266   @Override
267   public int getRowPosition() {
268     return 0;
269   }
270 
271   @Override
272   public ByteBuffer getFamilyByteBuffer() {
273     return ByteBuffer.wrap(familyBuffer);
274   }
275 
276   @Override
277   public int getFamilyPosition() {
278     return getFamilyOffset();
279   }
280 
281   @Override
282   public ByteBuffer getQualifierByteBuffer() {
283     return ByteBuffer.wrap(qualifierBuffer);
284   }
285 
286   @Override
287   public int getQualifierPosition() {
288     return getQualifierOffset();
289   }
290 
291   @Override
292   public ByteBuffer getValueByteBuffer() {
293     return pair.getFirst();
294   }
295 
296   @Override
297   public int getValuePosition() {
298     return pair.getSecond();
299   }
300 
301   @Override
302   public ByteBuffer getTagsByteBuffer() {
303     return ByteBuffer.wrap(tagsBuffer);
304   }
305 
306   @Override
307   public int getTagsPosition() {
308     return getTagsOffset();
309   }
310 }