View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase;
20  
21  import java.nio.ByteBuffer;
22  
23  import org.apache.hadoop.hbase.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.util.ByteBufferUtils;
25  import org.apache.hadoop.hbase.util.Bytes;
26  
27  /**
28   * This is a key only Cell implementation which is identical to {@link KeyValue.KeyOnlyKeyValue}
29   * with respect to key serialization but have its data in the form of Byte buffer
30   * (onheap and offheap).
31   */
32  @InterfaceAudience.Private
33  public class ByteBufferedKeyOnlyKeyValue extends ByteBufferedCell {
34  
35    private ByteBuffer buf;
36    private int offset = 0; // offset into buffer where key starts at
37    private int length = 0; // length of this.
38    private short rowLen;
39  
40    /**
41     * Used in cases where we want to avoid lot of garbage by allocating new objects with different
42     * keys. Use the emtpy construtor and set the keys using {@link #setKey(ByteBuffer, int, int)}
43     */
44    public ByteBufferedKeyOnlyKeyValue() {
45    }
46  
47    public ByteBufferedKeyOnlyKeyValue(ByteBuffer buf, int offset, int length) {
48      setKey(buf, offset, length);
49    }
50  
51    /**
52     * A setter that helps to avoid object creation every time and whenever
53     * there is a need to create new OffheapKeyOnlyKeyValue.
54     * @param key
55     * @param offset
56     * @param length
57     */
58    public void setKey(ByteBuffer key, int offset, int length) {
59      this.buf = key;
60      this.offset = offset;
61      this.length = length;
62      this.rowLen = ByteBufferUtils.toShort(this.buf, this.offset);
63    }
64  
65    @Override
66    public byte[] getRowArray() {
67      if (this.buf.hasArray()) {
68        return this.buf.array();
69      }
70      return CellUtil.cloneRow(this);
71    }
72  
73    @Override
74    public int getRowOffset() {
75      if (this.buf.hasArray()) {
76        return getRowPosition() + this.buf.arrayOffset();
77      }
78      return 0;
79    }
80  
81    @Override
82    public short getRowLength() {
83      return this.rowLen;
84    }
85  
86    @Override
87    public byte[] getFamilyArray() {
88      if (this.buf.hasArray()) {
89        return this.buf.array();
90      }
91      return CellUtil.cloneFamily(this);
92    }
93  
94    @Override
95    public int getFamilyOffset() {
96      if (this.buf.hasArray()) {
97        return getFamilyPosition() + this.buf.arrayOffset();
98      }
99      return 0;
100   }
101 
102   @Override
103   public byte getFamilyLength() {
104     return getFamilyLength(getFamilyLengthPosition());
105   }
106 
107   private byte getFamilyLength(int famLenPos) {
108     return ByteBufferUtils.toByte(this.buf, famLenPos);
109   }
110 
111   @Override
112   public byte[] getQualifierArray() {
113     if (this.buf.hasArray()) {
114       return this.buf.array();
115     }
116     return CellUtil.cloneQualifier(this);
117   }
118 
119   @Override
120   public int getQualifierOffset() {
121     if (this.buf.hasArray()) {
122       return getQualifierPosition() + this.buf.arrayOffset();
123     }
124     return 0;
125   }
126 
127   @Override
128   public int getQualifierLength() {
129     return getQualifierLength(getRowLength(), getFamilyLength());
130   }
131 
132   private int getQualifierLength(int rlength, int flength) {
133     return this.length - (int) KeyValue.getKeyDataStructureSize(rlength, flength, 0);
134   }
135 
136   @Override
137   public long getTimestamp() {
138     return ByteBufferUtils.toLong(this.buf, getTimestampOffset());
139   }
140 
141   private int getTimestampOffset() {
142     return this.offset + this.length - KeyValue.TIMESTAMP_TYPE_SIZE;
143   }
144 
145   @Override
146   public byte getTypeByte() {
147     return ByteBufferUtils.toByte(this.buf, this.offset + this.length - 1);
148   }
149 
150   @Override
151   public long getSequenceId() {
152     return 0;
153   }
154 
155   @Override
156   public byte[] getValueArray() {
157     throw new IllegalArgumentException("This is a key only Cell");
158   }
159 
160   @Override
161   public int getValueOffset() {
162     return 0;
163   }
164 
165   @Override
166   public int getValueLength() {
167     return 0;
168   }
169 
170   @Override
171   public byte[] getTagsArray() {
172     throw new IllegalArgumentException("This is a key only Cell");
173   }
174 
175   @Override
176   public int getTagsOffset() {
177     return 0;
178   }
179 
180   @Override
181   public int getTagsLength() {
182     return 0;
183   }
184 
185   @Override
186   public ByteBuffer getRowByteBuffer() {
187     return this.buf;
188   }
189 
190   @Override
191   public int getRowPosition() {
192     return this.offset + Bytes.SIZEOF_SHORT;
193   }
194 
195   @Override
196   public ByteBuffer getFamilyByteBuffer() {
197     return this.buf;
198   }
199 
200   @Override
201   public int getFamilyPosition() {
202     return getFamilyLengthPosition() + Bytes.SIZEOF_BYTE;
203   }
204 
205   // The position in BB where the family length is added.
206   private int getFamilyLengthPosition() {
207     return this.offset + Bytes.SIZEOF_SHORT + getRowLength();
208   }
209 
210   @Override
211   public ByteBuffer getQualifierByteBuffer() {
212     return this.buf;
213   }
214 
215   @Override
216   public int getQualifierPosition() {
217     int famLenPos = getFamilyLengthPosition();
218     return famLenPos + Bytes.SIZEOF_BYTE + getFamilyLength(famLenPos);
219   }
220 
221   @Override
222   public ByteBuffer getValueByteBuffer() {
223     throw new IllegalArgumentException("This is a key only Cell");
224   }
225 
226   @Override
227   public int getValuePosition() {
228     return 0;
229   }
230 
231   @Override
232   public ByteBuffer getTagsByteBuffer() {
233     throw new IllegalArgumentException("This is a key only Cell");
234   }
235 
236   @Override
237   public int getTagsPosition() {
238     return 0;
239   }
240 
241   @Override
242   public String toString() {
243     return CellUtil.toString(this, false);
244   }
245 }