HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-common / src / main / java / org / apache / hadoop / hbase / ByteBufferKeyValue.java
bloba2a8198bd4d87cc927caa8548ec92788fe9ecce5
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org.apache.hadoop.hbase;
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.nio.ByteBuffer;
23 import org.apache.hadoop.hbase.util.ByteBufferUtils;
24 import org.apache.hadoop.hbase.util.Bytes;
25 import org.apache.hadoop.hbase.util.ClassSize;
26 import org.apache.yetus.audience.InterfaceAudience;
28 /**
29 * This Cell is an implementation of {@link ByteBufferExtendedCell} where the data resides in
30 * off heap/ on heap ByteBuffer
32 @InterfaceAudience.Private
33 public class ByteBufferKeyValue extends ByteBufferExtendedCell {
35 protected final ByteBuffer buf;
36 protected final int offset;
37 protected final int length;
38 private long seqId = 0;
40 public static final int FIXED_OVERHEAD = ClassSize.OBJECT + ClassSize.REFERENCE
41 + (2 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_LONG;
43 public ByteBufferKeyValue(ByteBuffer buf, int offset, int length, long seqId) {
44 this.buf = buf;
45 this.offset = offset;
46 this.length = length;
47 this.seqId = seqId;
50 public ByteBufferKeyValue(ByteBuffer buf, int offset, int length) {
51 this.buf = buf;
52 this.offset = offset;
53 this.length = length;
56 public ByteBuffer getBuffer() {
57 return this.buf;
60 public int getOffset() {
61 return this.offset;
64 @Override
65 public byte[] getRowArray() {
66 return CellUtil.cloneRow(this);
69 @Override
70 public int getRowOffset() {
71 return 0;
74 @Override
75 public short getRowLength() {
76 return ByteBufferUtils.toShort(this.buf, this.offset + KeyValue.ROW_OFFSET);
79 @Override
80 public byte[] getFamilyArray() {
81 return CellUtil.cloneFamily(this);
84 @Override
85 public int getFamilyOffset() {
86 return 0;
89 @Override
90 public byte getFamilyLength() {
91 return getFamilyLength(getFamilyLengthPosition());
94 int getFamilyLengthPosition() {
95 return getFamilyLengthPosition(getRowLength());
98 int getFamilyLengthPosition(int rowLength) {
99 return this.offset + KeyValue.ROW_KEY_OFFSET + rowLength;
102 byte getFamilyLength(int famLenPos) {
103 return ByteBufferUtils.toByte(this.buf, famLenPos);
106 @Override
107 public byte[] getQualifierArray() {
108 return CellUtil.cloneQualifier(this);
111 @Override
112 public int getQualifierOffset() {
113 return 0;
116 @Override
117 public int getQualifierLength() {
118 return getQualifierLength(getKeyLength(), getRowLength(), getFamilyLength());
121 int getQualifierLength(int keyLength, int rlength, int flength) {
122 return keyLength - (int) KeyValue.getKeyDataStructureSize(rlength, flength, 0);
125 @Override
126 public long getTimestamp() {
127 return getTimestamp(getKeyLength());
130 long getTimestamp(int keyLength) {
131 int offset = getTimestampOffset(keyLength);
132 return ByteBufferUtils.toLong(this.buf, offset);
135 int getKeyLength() {
136 return ByteBufferUtils.toInt(this.buf, this.offset);
139 private int getTimestampOffset(int keyLen) {
140 return this.offset + KeyValue.ROW_OFFSET + keyLen - KeyValue.TIMESTAMP_TYPE_SIZE;
143 @Override
144 public byte getTypeByte() {
145 return getTypeByte(getKeyLength());
148 byte getTypeByte(int keyLen) {
149 return ByteBufferUtils.toByte(this.buf, this.offset + keyLen - 1 + KeyValue.ROW_OFFSET);
152 @Override
153 public long getSequenceId() {
154 return this.seqId;
157 @Override
158 public void setSequenceId(long seqId) {
159 this.seqId = seqId;
162 @Override
163 public byte[] getValueArray() {
164 return CellUtil.cloneValue(this);
167 @Override
168 public int getValueOffset() {
169 return 0;
172 @Override
173 public int getValueLength() {
174 return ByteBufferUtils.toInt(this.buf, this.offset + Bytes.SIZEOF_INT);
177 @Override
178 public byte[] getTagsArray() {
179 return PrivateCellUtil.cloneTags(this);
182 @Override
183 public int getTagsOffset() {
184 return 0;
187 @Override
188 public int getTagsLength() {
189 int tagsLen = this.length - (getKeyLength() + getValueLength()
190 + KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE);
191 if (tagsLen > 0) {
192 // There are some Tag bytes in the byte[]. So reduce 2 bytes which is
193 // added to denote the tags
194 // length
195 tagsLen -= KeyValue.TAGS_LENGTH_SIZE;
197 return tagsLen;
200 @Override
201 public ByteBuffer getRowByteBuffer() {
202 return this.buf;
205 @Override
206 public int getRowPosition() {
207 return this.offset + KeyValue.ROW_KEY_OFFSET;
210 @Override
211 public ByteBuffer getFamilyByteBuffer() {
212 return this.buf;
215 @Override
216 public int getFamilyPosition() {
217 return getFamilyPosition(getFamilyLengthPosition());
220 public int getFamilyPosition(int familyLengthPosition) {
221 return familyLengthPosition + Bytes.SIZEOF_BYTE;
224 @Override
225 public ByteBuffer getQualifierByteBuffer() {
226 return this.buf;
229 @Override
230 public int getQualifierPosition() {
231 return getQualifierPosition(getFamilyPosition(), getFamilyLength());
234 int getQualifierPosition(int familyPosition, int familyLength) {
235 return familyPosition + familyLength;
238 @Override
239 public ByteBuffer getValueByteBuffer() {
240 return this.buf;
243 @Override
244 public int getValuePosition() {
245 return this.offset + KeyValue.ROW_OFFSET + getKeyLength();
248 @Override
249 public ByteBuffer getTagsByteBuffer() {
250 return this.buf;
253 @Override
254 public int getTagsPosition() {
255 int tagsLen = getTagsLength();
256 if (tagsLen == 0) {
257 return this.offset + this.length;
259 return this.offset + this.length - tagsLen;
262 @Override
263 public long heapSize() {
264 if (this.buf.hasArray()) {
265 return ClassSize.align(FIXED_OVERHEAD + length);
267 return ClassSize.align(FIXED_OVERHEAD) + this.getSerializedSize();
270 @Override
271 public int write(OutputStream out, boolean withTags) throws IOException {
272 int length = getSerializedSize(withTags);
273 ByteBufferUtils.copyBufferToStream(out, this.buf, this.offset, length);
274 return length;
277 @Override
278 public int getSerializedSize(boolean withTags) {
279 if (withTags) {
280 return this.length;
282 return getKeyLength() + this.getValueLength() + KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE;
285 @Override
286 public int getSerializedSize() {
287 return this.length;
290 @Override
291 public void write(ByteBuffer buf, int offset) {
292 ByteBufferUtils.copyFromBufferToBuffer(this.buf, buf, this.offset, offset, this.length);
295 @Override
296 public String toString() {
297 return CellUtil.toString(this, true);
300 @Override
301 public void setTimestamp(long ts) throws IOException {
302 ByteBufferUtils.copyFromArrayToBuffer(this.buf, this.getTimestampOffset(), Bytes.toBytes(ts), 0,
303 Bytes.SIZEOF_LONG);
306 private int getTimestampOffset() {
307 return this.offset + KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE
308 + getKeyLength() - KeyValue.TIMESTAMP_TYPE_SIZE;
311 @Override
312 public void setTimestamp(byte[] ts) throws IOException {
313 ByteBufferUtils.copyFromArrayToBuffer(this.buf, this.getTimestampOffset(), ts, 0,
314 Bytes.SIZEOF_LONG);
317 @Override
318 public ExtendedCell deepClone() {
319 byte[] copy = new byte[this.length];
320 ByteBufferUtils.copyFromBufferToArray(copy, this.buf, this.offset, 0, this.length);
321 KeyValue kv = new KeyValue(copy, 0, copy.length);
322 kv.setSequenceId(this.getSequenceId());
323 return kv;
327 * Needed doing 'contains' on List. Only compares the key portion, not the value.
329 @Override
330 public boolean equals(Object other) {
331 if (!(other instanceof Cell)) {
332 return false;
334 return CellUtil.equals(this, (Cell) other);
338 * In line with {@link #equals(Object)}, only uses the key portion, not the value.
340 @Override
341 public int hashCode() {
342 return calculateHashForKey(this);
345 private int calculateHashForKey(ByteBufferExtendedCell cell) {
346 int rowHash = ByteBufferUtils.hashCode(cell.getRowByteBuffer(), cell.getRowPosition(),
347 cell.getRowLength());
348 int familyHash = ByteBufferUtils.hashCode(cell.getFamilyByteBuffer(), cell.getFamilyPosition(),
349 cell.getFamilyLength());
350 int qualifierHash = ByteBufferUtils.hashCode(cell.getQualifierByteBuffer(),
351 cell.getQualifierPosition(), cell.getQualifierLength());
353 int hash = 31 * rowHash + familyHash;
354 hash = 31 * hash + qualifierHash;
355 hash = 31 * hash + (int) cell.getTimestamp();
356 hash = 31 * hash + cell.getTypeByte();
357 return hash;