HBASE-24163 MOB compactor implementations should use format specifiers when calling...
[hbase.git] / hbase-common / src / main / java / org / apache / hadoop / hbase / util / AbstractByteRange.java
blob749d0fa8fede4c6a96874ad93449897c7832fab4
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 * The portion of this file denoted by 'Copied from com.google.protobuf.CodedInputStream'
19 * is from Protocol Buffers v2.5.0 under the following license
21 * Copyright 2008 Google Inc. All rights reserved.
22 * http://code.google.com/p/protobuf/
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions are
26 * met:
28 * * Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * * Redistributions in binary form must reproduce the above
31 * copyright notice, this list of conditions and the following disclaimer
32 * in the documentation and/or other materials provided with the
33 * distribution.
34 * * Neither the name of Google Inc. nor the names of its
35 * contributors may be used to endorse or promote products derived from
36 * this software without specific prior written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
41 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
42 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 package org.apache.hadoop.hbase.util;
53 import org.apache.yetus.audience.InterfaceAudience;
54 import org.apache.yetus.audience.InterfaceStability;
56 /**
57 * An abstract implementation of the ByteRange API
59 @InterfaceAudience.Private
60 @InterfaceStability.Evolving
61 public abstract class AbstractByteRange implements ByteRange {
62 public static final int UNSET_HASH_VALUE = -1;
64 // Note to maintainers: Do not make these final, as the intention is to
65 // reuse objects of this class
67 /**
68 * The array containing the bytes in this range. It will be >= length.
70 protected byte[] bytes;
72 /**
73 * The index of the first byte in this range. {@code ByteRange.get(0)} will
74 * return bytes[offset].
76 protected int offset;
78 /**
79 * The number of bytes in the range. Offset + length must be <= bytes.length
81 protected int length;
83 /**
84 * Variable for lazy-caching the hashCode of this range. Useful for frequently
85 * used ranges, long-lived ranges, or long ranges.
87 protected int hash = UNSET_HASH_VALUE;
90 // methods for managing the backing array and range viewport
92 @Override
93 public byte[] getBytes() {
94 return bytes;
97 @Override
98 public ByteRange set(int capacity) {
99 return set(new byte[capacity]);
102 @Override
103 public ByteRange set(byte[] bytes) {
104 if (null == bytes) {
105 return unset();
108 clearHashCache();
109 this.bytes = bytes;
110 this.offset = 0;
111 this.length = bytes.length;
112 return this;
115 @Override
116 public ByteRange set(byte[] bytes, int offset, int length) {
117 if (null == bytes) {
118 return unset();
121 clearHashCache();
122 this.bytes = bytes;
123 this.offset = offset;
124 this.length = length;
125 return this;
128 @Override
129 public int getOffset() {
130 return offset;
133 @Override
134 public ByteRange setOffset(int offset) {
135 clearHashCache();
136 this.offset = offset;
137 return this;
140 @Override
141 public int getLength() {
142 return length;
145 @Override
146 public ByteRange setLength(int length) {
147 clearHashCache();
148 this.length = length;
149 return this;
152 @Override
153 public boolean isEmpty() {
154 return isEmpty(this);
158 * @return true when {@code range} is of zero length, false otherwise.
160 public static boolean isEmpty(ByteRange range) {
161 return range == null || range.getLength() == 0;
165 // methods for retrieving data
168 @Override
169 public byte get(int index) {
170 return bytes[offset + index];
173 @Override
174 public ByteRange get(int index, byte[] dst) {
175 if (0 == dst.length) {
176 return this;
179 return get(index, dst, 0, dst.length);
182 @Override
183 public ByteRange get(int index, byte[] dst, int offset, int length) {
184 if (0 == length) {
185 return this;
188 System.arraycopy(this.bytes, this.offset + index, dst, offset, length);
189 return this;
192 @Override
193 public short getShort(int index) {
194 int offset = this.offset + index;
195 short n = 0;
196 n = (short) ((n ^ bytes[offset]) & 0xFF);
197 n = (short) (n << 8);
198 n = (short) ((n ^ bytes[offset + 1]) & 0xFF);
199 return n;
202 @Override
203 public int getInt(int index) {
204 int offset = this.offset + index;
205 int n = 0;
206 for (int i = offset; i < (offset + Bytes.SIZEOF_INT); i++) {
207 n <<= 8;
208 n ^= bytes[i] & 0xFF;
210 return n;
213 @Override
214 public long getLong(int index) {
215 int offset = this.offset + index;
216 long l = 0;
217 for (int i = offset; i < offset + Bytes.SIZEOF_LONG; i++) {
218 l <<= 8;
219 l ^= bytes[i] & 0xFF;
221 return l;
224 // Copied from com.google.protobuf.CodedInputStream v2.5.0 readRawVarint64
225 @Override
226 public long getVLong(int index) {
227 int shift = 0;
228 long result = 0;
229 while (shift < 64) {
230 final byte b = get(index++);
231 result |= (long) (b & 0x7F) << shift;
232 if ((b & 0x80) == 0) {
233 break;
235 shift += 7;
237 return result;
239 // end of copied from protobuf
241 public static int getVLongSize(long val) {
242 int rPos = 0;
243 while ((val & ~0x7F) != 0) {
244 val >>>= 7;
245 rPos++;
247 return rPos + 1;
251 // methods for duplicating the current instance
254 @Override
255 public byte[] deepCopyToNewArray() {
256 byte[] result = new byte[length];
257 System.arraycopy(bytes, offset, result, 0, length);
258 return result;
261 @Override
262 public void deepCopyTo(byte[] destination, int destinationOffset) {
263 System.arraycopy(bytes, offset, destination, destinationOffset, length);
266 @Override
267 public void deepCopySubRangeTo(int innerOffset, int copyLength, byte[] destination,
268 int destinationOffset) {
269 System.arraycopy(bytes, offset + innerOffset, destination, destinationOffset, copyLength);
273 // methods used for comparison
276 @Override
277 public int hashCode() {
278 if (isHashCached()) {// hash is already calculated and cached
279 return hash;
281 if (this.isEmpty()) {// return 0 for empty ByteRange
282 hash = 0;
283 return hash;
285 int off = offset;
286 hash = 0;
287 for (int i = 0; i < length; i++) {
288 hash = 31 * hash + bytes[off++];
290 return hash;
293 protected boolean isHashCached() {
294 return hash != UNSET_HASH_VALUE;
297 protected void clearHashCache() {
298 hash = UNSET_HASH_VALUE;
301 @Override
302 public boolean equals(Object obj) {
303 if (this == obj) {
304 return true;
306 if (obj == null) {
307 return false;
309 if (!(obj instanceof ByteRange)) {
310 return false;
312 return compareTo((ByteRange) obj) == 0;
316 * Bitwise comparison of each byte in the array. Unsigned comparison, not
317 * paying attention to java's signed bytes.
319 @Override
320 public int compareTo(ByteRange other) {
321 return Bytes.compareTo(bytes, offset, length, other.getBytes(), other.getOffset(),
322 other.getLength());
325 @Override
326 public String toString() {
327 return Bytes.toStringBinary(bytes, offset, length);