1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 package org.apache.hadoop.hbase.util;
52
53 import org.apache.hadoop.hbase.classification.InterfaceAudience;
54 import org.apache.hadoop.hbase.classification.InterfaceStability;
55
56
57
58
59 @InterfaceAudience.Private
60 @InterfaceStability.Evolving
61 public abstract class AbstractByteRange implements ByteRange {
62 public static final int UNSET_HASH_VALUE = -1;
63
64
65
66
67
68
69
70 protected byte[] bytes;
71
72
73
74
75
76 protected int offset;
77
78
79
80
81 protected int length;
82
83
84
85
86
87 protected int hash = UNSET_HASH_VALUE;
88
89
90
91
92 @Override
93 public byte[] getBytes() {
94 return bytes;
95 }
96
97 @Override
98 public ByteRange set(int capacity) {
99 return set(new byte[capacity]);
100 }
101
102 @Override
103 public ByteRange set(byte[] bytes) {
104 if (null == bytes) {
105 return unset();
106 }
107
108 clearHashCache();
109 this.bytes = bytes;
110 this.offset = 0;
111 this.length = bytes.length;
112 return this;
113 }
114
115 @Override
116 public ByteRange set(byte[] bytes, int offset, int length) {
117 if (null == bytes) {
118 return unset();
119 }
120
121 clearHashCache();
122 this.bytes = bytes;
123 this.offset = offset;
124 this.length = length;
125 return this;
126 }
127
128 @Override
129 public int getOffset() {
130 return offset;
131 }
132
133 @Override
134 public ByteRange setOffset(int offset) {
135 clearHashCache();
136 this.offset = offset;
137 return this;
138 }
139
140 @Override
141 public int getLength() {
142 return length;
143 }
144
145 @Override
146 public ByteRange setLength(int length) {
147 clearHashCache();
148 this.length = length;
149 return this;
150 }
151
152 @Override
153 public boolean isEmpty() {
154 return isEmpty(this);
155 }
156
157
158
159
160 public static boolean isEmpty(ByteRange range) {
161 return range == null || range.getLength() == 0;
162 }
163
164
165
166
167
168 @Override
169 public byte get(int index) {
170 return bytes[offset + index];
171 }
172
173 @Override
174 public ByteRange get(int index, byte[] dst) {
175 if (0 == dst.length) {
176 return this;
177 }
178
179 return get(index, dst, 0, dst.length);
180 }
181
182 @Override
183 public ByteRange get(int index, byte[] dst, int offset, int length) {
184 if (0 == length) {
185 return this;
186 }
187
188 System.arraycopy(this.bytes, this.offset + index, dst, offset, length);
189 return this;
190 }
191
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;
200 }
201
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;
209 }
210 return n;
211 }
212
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;
220 }
221 return l;
222 }
223
224
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;
234 }
235 shift += 7;
236 }
237 return result;
238 }
239
240
241 public static int getVLongSize(long val) {
242 int rPos = 0;
243 while ((val & ~0x7F) != 0) {
244 val >>>= 7;
245 rPos++;
246 }
247 return rPos + 1;
248 }
249
250
251
252
253
254 @Override
255 public byte[] deepCopyToNewArray() {
256 byte[] result = new byte[length];
257 System.arraycopy(bytes, offset, result, 0, length);
258 return result;
259 }
260
261 @Override
262 public void deepCopyTo(byte[] destination, int destinationOffset) {
263 System.arraycopy(bytes, offset, destination, destinationOffset, length);
264 }
265
266 @Override
267 public void deepCopySubRangeTo(int innerOffset, int copyLength, byte[] destination,
268 int destinationOffset) {
269 System.arraycopy(bytes, offset + innerOffset, destination, destinationOffset, copyLength);
270 }
271
272
273
274
275
276 @Override
277 public int hashCode() {
278 if (isHashCached()) {
279 return hash;
280 }
281 if (this.isEmpty()) {
282 hash = 0;
283 return hash;
284 }
285 int off = offset;
286 hash = 0;
287 for (int i = 0; i < length; i++) {
288 hash = 31 * hash + bytes[off++];
289 }
290 return hash;
291 }
292
293 protected boolean isHashCached() {
294 return hash != UNSET_HASH_VALUE;
295 }
296
297 protected void clearHashCache() {
298 hash = UNSET_HASH_VALUE;
299 }
300
301
302
303
304
305 @Override
306 public int compareTo(ByteRange other) {
307 return Bytes.compareTo(bytes, offset, length, other.getBytes(), other.getOffset(),
308 other.getLength());
309 }
310
311 @Override
312 public String toString() {
313 return Bytes.toStringBinary(bytes, offset, length);
314 }
315 }