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 org
.apache
.commons
.lang3
.ArrayUtils
;
21 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
22 import org
.apache
.hadoop
.hbase
.util
.ClassSize
;
23 import org
.apache
.yetus
.audience
.InterfaceAudience
;
25 @InterfaceAudience.Private
26 public class IndividualBytesFieldCell
implements ExtendedCell
, Cloneable
{
27 // do alignment(padding gap)
28 private static final long FIXED_OVERHEAD
= ClassSize
.align(ClassSize
.OBJECT
// object header
30 + KeyValue
.TIMESTAMP_TYPE_SIZE
33 // references to all byte arrays: row, family, qualifier, value, tags
34 + 5 * ClassSize
.REFERENCE
);
36 // The following fields are backed by individual byte arrays
37 private final byte[] row
;
38 private final int rOffset
;
39 private final int rLength
;
40 private final byte[] family
;
41 private final int fOffset
;
42 private final int fLength
;
43 private final byte[] qualifier
;
44 private final int qOffset
;
45 private final int qLength
;
46 private final byte[] value
;
47 private final int vOffset
;
48 private final int vLength
;
49 private final byte[] tags
; // A byte array, rather than an array of org.apache.hadoop.hbase.Tag
50 private final int tagsOffset
;
51 private final int tagsLength
;
54 private long timestamp
;
55 private final byte type
; // A byte, rather than org.apache.hadoop.hbase.KeyValue.Type
58 public IndividualBytesFieldCell(byte[] row
, byte[] family
, byte[] qualifier
, long timestamp
,
59 KeyValue
.Type type
, long seqId
, byte[] value
, byte[] tags
) {
60 this(row
, 0, ArrayUtils
.getLength(row
),
61 family
, 0, ArrayUtils
.getLength(family
),
62 qualifier
, 0, ArrayUtils
.getLength(qualifier
),
63 timestamp
, type
, seqId
,
64 value
, 0, ArrayUtils
.getLength(value
),
65 tags
, 0, ArrayUtils
.getLength(tags
));
68 public IndividualBytesFieldCell(byte[] row
, int rOffset
, int rLength
, byte[] family
, int fOffset
,
69 int fLength
, byte[] qualifier
, int qOffset
, int qLength
, long timestamp
, KeyValue
.Type type
,
70 long seqId
, byte[] value
, int vOffset
, int vLength
, byte[] tags
, int tagsOffset
,
72 // Check row, family, qualifier and value
73 KeyValue
.checkParameters(row
, rLength
, // row and row length
74 family
, fLength
, // family and family length
75 qLength
, // qualifier length
76 vLength
); // value length
80 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp
);
84 RawCell
.checkForTagsLength(tagsLength
);
85 checkArrayBounds(row
, rOffset
, rLength
);
86 checkArrayBounds(family
, fOffset
, fLength
);
87 checkArrayBounds(qualifier
, qOffset
, qLength
);
88 checkArrayBounds(value
, vOffset
, vLength
);
89 checkArrayBounds(tags
, tagsOffset
, tagsLength
);
90 // No local copy is made, but reference to the input directly
92 this.rOffset
= rOffset
;
93 this.rLength
= rLength
;
95 this.fOffset
= fOffset
;
96 this.fLength
= fLength
;
97 this.qualifier
= qualifier
;
98 this.qOffset
= qOffset
;
99 this.qLength
= qLength
;
101 this.vOffset
= vOffset
;
102 this.vLength
= vLength
;
104 this.tagsOffset
= tagsOffset
;
105 this.tagsLength
= tagsLength
;
108 this.timestamp
= timestamp
;
109 this.type
= type
.getCode();
113 private void checkArrayBounds(byte[] bytes
, int offset
, int length
) {
114 if (offset
< 0 || length
< 0) {
115 throw new IllegalArgumentException("Negative number! offset=" + offset
+ "and length="
118 if (bytes
== null && (offset
!= 0 || length
!= 0)) {
119 throw new IllegalArgumentException("Null bytes array but offset=" + offset
+ "and length="
122 if (bytes
!= null && bytes
.length
< offset
+ length
) {
123 throw new IllegalArgumentException("Out of bounds! bytes.length=" + bytes
.length
124 + ", offset=" + offset
+ ", length=" + length
);
128 private long heapOverhead() {
129 return FIXED_OVERHEAD
130 + ClassSize
.ARRAY
// row , can not be null
131 + ((family
== null) ?
0 : ClassSize
.ARRAY
) // family , can be null
132 + ((qualifier
== null) ?
0 : ClassSize
.ARRAY
) // qualifier, can be null
133 + ((value
== null) ?
0 : ClassSize
.ARRAY
) // value , can be null
134 + ((tags
== null) ?
0 : ClassSize
.ARRAY
); // tags , can be null
138 * Implement Cell interface
142 public byte[] getRowArray() {
143 // If row is null, the constructor will reject it, by {@link KeyValue#checkParameters()},
144 // so it is safe to return row without checking.
149 public int getRowOffset() {
154 public short getRowLength() {
155 // If row is null or rLength is invalid, the constructor will reject it, by
156 // {@link KeyValue#checkParameters()}, so it is safe to call rLength and make the type
158 return (short)(rLength
);
163 public byte[] getFamilyArray() {
164 // Family could be null
165 return (family
== null) ? HConstants
.EMPTY_BYTE_ARRAY
: family
;
169 public int getFamilyOffset() {
174 public byte getFamilyLength() {
175 // If fLength is invalid, the constructor will reject it, by {@link KeyValue#checkParameters()},
176 // so it is safe to make the type conversion.
177 return (byte)(fLength
);
182 public byte[] getQualifierArray() {
183 // Qualifier could be null
184 return (qualifier
== null) ? HConstants
.EMPTY_BYTE_ARRAY
: qualifier
;
188 public int getQualifierOffset() {
193 public int getQualifierLength() {
199 public long getTimestamp() {
205 public byte getTypeByte() {
211 public long getSequenceId() {
217 public byte[] getValueArray() {
218 // Value could be null
219 return (value
== null) ? HConstants
.EMPTY_BYTE_ARRAY
: value
;
223 public int getValueOffset() {
228 public int getValueLength() {
234 public byte[] getTagsArray() {
235 // Tags can could null
236 return (tags
== null) ? HConstants
.EMPTY_BYTE_ARRAY
: tags
;
240 public int getTagsOffset() {
245 public int getTagsLength() {
250 * Implement HeapSize interface
253 public long heapSize() {
254 // Size of array headers are already included into overhead, so do not need to include it for
256 return heapOverhead() // overhead, with array headers included
257 + ClassSize
.align(getRowLength()) // row
258 + ClassSize
.align(getFamilyLength()) // family
259 + ClassSize
.align(getQualifierLength()) // qualifier
260 + ClassSize
.align(getValueLength()) // value
261 + ClassSize
.align(getTagsLength()); // tags
265 * Implement Cloneable interface
268 public Object
clone() throws CloneNotSupportedException
{
269 return super.clone(); // only a shadow copy
273 public void setSequenceId(long seqId
) {
275 throw new IllegalArgumentException("Sequence Id cannot be negative. ts=" + seqId
);
281 public void setTimestamp(long ts
) {
283 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts
);
289 public void setTimestamp(byte[] ts
) {
290 setTimestamp(Bytes
.toLong(ts
, 0));
294 public String
toString() {
295 return CellUtil
.toString(this, true);