HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-common / src / main / java / org / apache / hadoop / hbase / ByteBufferKeyOnlyKeyValue.java
blobd55733769ddff7a5c6925f8c430e1f7d2fe0991e
1 /**
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 package org.apache.hadoop.hbase;
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.Optional;
26 import org.apache.hadoop.hbase.util.ByteBufferUtils;
27 import org.apache.hadoop.hbase.util.Bytes;
28 import org.apache.hadoop.hbase.util.ClassSize;
29 import org.apache.yetus.audience.InterfaceAudience;
31 /**
32 * This is a key only Cell implementation which is identical to {@link KeyValue.KeyOnlyKeyValue}
33 * with respect to key serialization but have its data in the form of Byte buffer
34 * (onheap and offheap).
36 @InterfaceAudience.Private
37 public class ByteBufferKeyOnlyKeyValue extends ByteBufferExtendedCell {
38 public static final int FIXED_OVERHEAD = ClassSize.OBJECT + ClassSize.REFERENCE
39 + (2 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_SHORT;
40 private ByteBuffer buf;
41 private int offset = 0; // offset into buffer where key starts at
42 private int length = 0; // length of this.
43 private short rowLen;
45 /**
46 * Used in cases where we want to avoid lot of garbage by allocating new objects with different
47 * keys. Use the emtpy construtor and set the keys using {@link #setKey(ByteBuffer, int, int)}
49 public ByteBufferKeyOnlyKeyValue() {
52 public ByteBufferKeyOnlyKeyValue(ByteBuffer buf, int offset, int length) {
53 setKey(buf, offset, length);
56 /**
57 * A setter that helps to avoid object creation every time and whenever
58 * there is a need to create new OffheapKeyOnlyKeyValue.
59 * @param key
60 * @param offset
61 * @param length
63 public void setKey(ByteBuffer key, int offset, int length) {
64 setKey(key, offset, length, ByteBufferUtils.toShort(key, offset));
67 /**
68 * A setter that helps to avoid object creation every time and whenever
69 * there is a need to create new OffheapKeyOnlyKeyValue.
70 * @param key - the key part of the cell
71 * @param offset - offset of the cell
72 * @param length - length of the cell
73 * @param rowLen - the rowlen part of the cell
75 public void setKey(ByteBuffer key, int offset, int length, short rowLen) {
76 this.buf = key;
77 this.offset = offset;
78 this.length = length;
79 this.rowLen = rowLen;
82 @Override
83 public byte[] getRowArray() {
84 if (this.buf.hasArray()) {
85 return this.buf.array();
87 return CellUtil.cloneRow(this);
90 @Override
91 public int getRowOffset() {
92 if (this.buf.hasArray()) {
93 return getRowPosition() + this.buf.arrayOffset();
95 return 0;
98 @Override
99 public short getRowLength() {
100 return this.rowLen;
103 @Override
104 public byte[] getFamilyArray() {
105 if (this.buf.hasArray()) {
106 return this.buf.array();
108 return CellUtil.cloneFamily(this);
111 @Override
112 public int getFamilyOffset() {
113 if (this.buf.hasArray()) {
114 return getFamilyPosition() + this.buf.arrayOffset();
116 return 0;
119 @Override
120 public byte getFamilyLength() {
121 return getFamilyLength(getFamilyLengthPosition());
124 private byte getFamilyLength(int famLenPos) {
125 return ByteBufferUtils.toByte(this.buf, famLenPos);
128 @Override
129 public byte[] getQualifierArray() {
130 if (this.buf.hasArray()) {
131 return this.buf.array();
133 return CellUtil.cloneQualifier(this);
136 @Override
137 public int getQualifierOffset() {
138 if (this.buf.hasArray()) {
139 return getQualifierPosition() + this.buf.arrayOffset();
141 return 0;
144 @Override
145 public int getQualifierLength() {
146 return getQualifierLength(getRowLength(), getFamilyLength());
149 private int getQualifierLength(int rlength, int flength) {
150 return this.length - (int) KeyValue.getKeyDataStructureSize(rlength, flength, 0);
153 @Override
154 public long getTimestamp() {
155 return ByteBufferUtils.toLong(this.buf, getTimestampOffset());
158 private int getTimestampOffset() {
159 return this.offset + this.length - KeyValue.TIMESTAMP_TYPE_SIZE;
162 @Override
163 public byte getTypeByte() {
164 return getTypeByte(this.length);
167 byte getTypeByte(int keyLen) {
168 return ByteBufferUtils.toByte(this.buf, this.offset + keyLen - 1);
171 @Override
172 public void setSequenceId(long seqId) throws IOException {
173 throw new IllegalArgumentException("This is a key only Cell");
176 @Override
177 public void setTimestamp(long ts) throws IOException {
178 throw new IllegalArgumentException("This is a key only Cell");
181 @Override
182 public void setTimestamp(byte[] ts) throws IOException {
183 throw new IllegalArgumentException("This is a key only Cell");
186 @Override
187 public long getSequenceId() {
188 return 0;
191 @Override
192 public byte[] getValueArray() {
193 throw new IllegalArgumentException("This is a key only Cell");
196 @Override
197 public int getValueOffset() {
198 return 0;
201 @Override
202 public int getValueLength() {
203 return 0;
206 @Override
207 public byte[] getTagsArray() {
208 throw new IllegalArgumentException("This is a key only Cell");
211 @Override
212 public int getTagsOffset() {
213 return 0;
216 @Override
217 public int getTagsLength() {
218 return 0;
221 @Override
222 public ByteBuffer getRowByteBuffer() {
223 return this.buf;
226 @Override
227 public int getRowPosition() {
228 return this.offset + Bytes.SIZEOF_SHORT;
231 @Override
232 public ByteBuffer getFamilyByteBuffer() {
233 return this.buf;
236 @Override
237 public int getFamilyPosition() {
238 return getFamilyLengthPosition() + Bytes.SIZEOF_BYTE;
241 // The position in BB where the family length is added.
242 private int getFamilyLengthPosition() {
243 return getFamilyLengthPosition(getRowLength());
246 int getFamilyLengthPosition(int rowLength) {
247 return this.offset + Bytes.SIZEOF_SHORT + rowLength;
250 @Override
251 public ByteBuffer getQualifierByteBuffer() {
252 return this.buf;
255 @Override
256 public int getQualifierPosition() {
257 int famLenPos = getFamilyLengthPosition();
258 return famLenPos + Bytes.SIZEOF_BYTE + getFamilyLength(famLenPos);
261 @Override
262 public ByteBuffer getValueByteBuffer() {
263 throw new IllegalArgumentException("This is a key only Cell");
266 @Override
267 public int getValuePosition() {
268 return 0;
271 @Override
272 public ByteBuffer getTagsByteBuffer() {
273 throw new IllegalArgumentException("This is a key only Cell");
276 @Override
277 public int getTagsPosition() {
278 return 0;
281 @Override
282 public String toString() {
283 return CellUtil.toString(this, false);
286 @Override
287 public Iterator<Tag> getTags() {
288 return Collections.emptyIterator();
291 @Override
292 public Optional<Tag> getTag(byte type) {
293 return Optional.empty();
296 @Override
297 public long heapSize() {
298 if (this.buf.hasArray()) {
299 return ClassSize.align(FIXED_OVERHEAD + length);
301 return ClassSize.align(FIXED_OVERHEAD);