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 getMvccVersion() {
135     if (!includeMvccVersion) {
136       return 0L;
137     }
138     return mvccVersion;
139   }
140 
141   @Override
142   public long getSequenceId() {
143     return getMvccVersion();
144   }
145 
146   @Override
147   public int getValueLength() {
148     return valueLength;
149   }
150 
151   @Override
152   public byte[] getRowArray() {
153     return rowBuffer;
154   }
155 
156   @Override
157   public int getRowOffset() {
158     return 0;
159   }
160 
161   @Override
162   public short getRowLength() {
163     return (short) rowLength;
164   }
165 
166   @Override
167   public byte[] getFamilyArray() {
168     return familyBuffer;
169   }
170 
171   @Override
172   public int getFamilyOffset() {
173     return familyOffset;
174   }
175 
176   @Override
177   public byte getFamilyLength() {
178     return (byte) familyLength;
179   }
180 
181   @Override
182   public byte[] getQualifierArray() {
183     return qualifierBuffer;
184   }
185 
186   @Override
187   public int getQualifierOffset() {
188     return qualifierOffset;
189   }
190 
191   @Override
192   public int getQualifierLength() {
193     return qualifierLength;
194   }
195 
196   @Override
197   public byte[] getValueArray() {
198     return block;
199   }
200 
201   @Override
202   public int getValueOffset() {
203     return absoluteValueOffset;
204   }
205 
206   @Override
207   public byte getTypeByte() {
208     return type.getCode();
209   }
210 
211   /* Deprecated methods pushed into the Cell interface */
212   @Override
213   public byte[] getValue() {
214     return CellUtil.cloneValue(this);
215   }
216 
217   @Override
218   public byte[] getFamily() {
219     return CellUtil.cloneFamily(this);
220   }
221 
222   @Override
223   public byte[] getQualifier() {
224     return CellUtil.cloneQualifier(this);
225   }
226 
227   @Override
228   public byte[] getRow() {
229     return CellUtil.cloneRow(this);
230   }
231 
232   /************************* helper methods *************************/
233 
234   /**
235    * Need this separate method so we can call it from subclasses' toString() methods
236    */
237   protected String getKeyValueString(){
238     KeyValue kv = KeyValueUtil.copyToNewKeyValue(this);
239     return kv.toString();
240   }
241 
242   @Override
243   public int getTagsOffset() {
244     return tagsOffset;
245   }
246 
247   @Override
248   public int getTagsLength() {
249     return tagsLength;
250   }
251 
252   @Override
253   public byte[] getTagsArray() {
254     return this.tagsBuffer;
255   }
256 
257   @Override
258   public void setSequenceId(long seqId) {
259     mvccVersion = seqId;
260   }
261 }