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  import org.apache.hadoop.hbase.Cell;
22  import org.apache.hadoop.hbase.CellComparator;
23  import org.apache.hadoop.hbase.CellUtil;
24  import org.apache.hadoop.hbase.KeyValue;
25  import org.apache.hadoop.hbase.KeyValueUtil;
26  import org.apache.hadoop.hbase.SettableSequenceId;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.util.Bytes;
29  
30  /**
31   * As the PrefixTreeArrayScanner moves through the tree bytes, it changes the values in the fields
32   * of this class so that Cell logic can be applied, but without allocating new memory for every Cell
33   * iterated through.
34   */
35  @InterfaceAudience.Private
36  public class PrefixTreeCell implements Cell, SettableSequenceId, Comparable<Cell> {
37    // Create a reference here?  Can be removed too
38    protected CellComparator comparator = CellComparator.COMPARATOR;
39  
40    /********************** static **********************/
41  
42    public static final KeyValue.Type[] TYPES = new KeyValue.Type[256];
43    static {
44      for (KeyValue.Type type : KeyValue.Type.values()) {
45        TYPES[type.getCode() & 0xff] = type;
46      }
47    }
48  
49    //Same as KeyValue constructor.  Only used to avoid NPE's when full cell hasn't been initialized.
50    public static final KeyValue.Type DEFAULT_TYPE = KeyValue.Type.Put;
51  
52    /******************** fields ************************/
53  
54    protected byte[] block;
55    //we could also avoid setting the mvccVersion in the scanner/searcher, but this is simpler
56    protected boolean includeMvccVersion;
57  
58    protected byte[] rowBuffer;
59    protected int rowLength;
60  
61    protected byte[] familyBuffer;
62    protected int familyOffset;
63    protected int familyLength;
64  
65    protected byte[] qualifierBuffer;// aligned to the end of the array
66    protected int qualifierOffset;
67    protected int qualifierLength;
68  
69    protected Long timestamp;
70    protected Long mvccVersion;
71  
72    protected KeyValue.Type type;
73  
74    protected int absoluteValueOffset;
75    protected int valueLength;
76  
77    protected byte[] tagsBuffer;
78    protected int tagsOffset;
79    protected int tagsLength;
80  
81    /********************** Cell methods ******************/
82  
83    /**
84     * For debugging.  Currently creates new KeyValue to utilize its toString() method.
85     */
86    @Override
87    public String toString() {
88      return getKeyValueString();
89    }
90  
91    @Override
92    public boolean equals(Object obj) {
93      if (!(obj instanceof Cell)) {
94        return false;
95      }
96      //Temporary hack to maintain backwards compatibility with KeyValue.equals
97      return CellUtil.equalsIgnoreMvccVersion(this, (Cell)obj);
98  
99      //TODO return CellComparator.equals(this, (Cell)obj);//see HBASE-6907
100   }
101 
102   @Override
103   public int hashCode() {
104     return calculateHashForKey(this);
105   }
106 
107   private int calculateHashForKey(Cell cell) {
108     // pre-calculate the 3 hashes made of byte ranges
109     int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
110     int familyHash = Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(),
111         cell.getFamilyLength());
112     int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
113         cell.getQualifierLength());
114 
115     // combine the 6 sub-hashes
116     int hash = 31 * rowHash + familyHash;
117     hash = 31 * hash + qualifierHash;
118     hash = 31 * hash + (int) cell.getTimestamp();
119     hash = 31 * hash + cell.getTypeByte();
120     return hash;
121   }
122 
123   @Override
124   public int compareTo(Cell other) {
125     return comparator.compare(this, other);
126   }
127 
128   @Override
129   public long getTimestamp() {
130     return timestamp;
131   }
132 
133   @Override
134   public long getSequenceId() {
135     if (!includeMvccVersion) {
136       return 0L;
137     }
138     return mvccVersion;
139   }
140 
141   @Override
142   public int getValueLength() {
143     return valueLength;
144   }
145 
146   @Override
147   public byte[] getRowArray() {
148     return rowBuffer;
149   }
150 
151   @Override
152   public int getRowOffset() {
153     return 0;
154   }
155 
156   @Override
157   public short getRowLength() {
158     return (short) rowLength;
159   }
160 
161   @Override
162   public byte[] getFamilyArray() {
163     return familyBuffer;
164   }
165 
166   @Override
167   public int getFamilyOffset() {
168     return familyOffset;
169   }
170 
171   @Override
172   public byte getFamilyLength() {
173     return (byte) familyLength;
174   }
175 
176   @Override
177   public byte[] getQualifierArray() {
178     return qualifierBuffer;
179   }
180 
181   @Override
182   public int getQualifierOffset() {
183     return qualifierOffset;
184   }
185 
186   @Override
187   public int getQualifierLength() {
188     return qualifierLength;
189   }
190 
191   @Override
192   public byte[] getValueArray() {
193     return block;
194   }
195 
196   @Override
197   public int getValueOffset() {
198     return absoluteValueOffset;
199   }
200 
201   @Override
202   public byte getTypeByte() {
203     return type.getCode();
204   }
205 
206   /************************* helper methods *************************/
207 
208   /**
209    * Need this separate method so we can call it from subclasses' toString() methods
210    */
211   protected String getKeyValueString(){
212     KeyValue kv = KeyValueUtil.copyToNewKeyValue(this);
213     return kv.toString();
214   }
215 
216   @Override
217   public int getTagsOffset() {
218     return tagsOffset;
219   }
220 
221   @Override
222   public int getTagsLength() {
223     return tagsLength;
224   }
225 
226   @Override
227   public byte[] getTagsArray() {
228     return this.tagsBuffer;
229   }
230 
231   @Override
232   public void setSequenceId(long seqId) {
233     mvccVersion = seqId;
234   }
235 }