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
63 public static final int UNSET_HASH_VALUE = -1;
64
65
66
67
68
69
70
71 protected byte[] bytes;
72
73
74
75
76
77 protected int offset;
78
79
80
81
82 protected int length;
83
84
85
86
87
88 protected int hash = UNSET_HASH_VALUE;
89
90
91
92
93 @Override
94 public byte[] getBytes() {
95 return bytes;
96 }
97
98 @Override
99 public abstract ByteRange unset();
100
101 @Override
102 public ByteRange set(int capacity) {
103 return set(new byte[capacity]);
104 }
105
106 @Override
107 public ByteRange set(byte[] bytes) {
108 if (null == bytes)
109 return unset();
110 clearHashCache();
111 this.bytes = bytes;
112 this.offset = 0;
113 this.length = bytes.length;
114 return this;
115 }
116
117 @Override
118 public ByteRange set(byte[] bytes, int offset, int length) {
119 if (null == bytes)
120 return unset();
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 return get(index, dst, 0, dst.length);
178 }
179
180 @Override
181 public ByteRange get(int index, byte[] dst, int offset, int length) {
182 if (0 == length)
183 return this;
184 System.arraycopy(this.bytes, this.offset + index, dst, offset, length);
185 return this;
186 }
187
188 @Override
189 public short getShort(int index) {
190 int offset = this.offset + index;
191 short n = 0;
192 n ^= bytes[offset] & 0xFF;
193 n <<= 8;
194 n ^= bytes[offset + 1] & 0xFF;
195 return n;
196 }
197
198 @Override
199 public int getInt(int index) {
200 int offset = this.offset + index;
201 int n = 0;
202 for (int i = offset; i < (offset + Bytes.SIZEOF_INT); i++) {
203 n <<= 8;
204 n ^= bytes[i] & 0xFF;
205 }
206 return n;
207 }
208
209 @Override
210 public long getLong(int index) {
211 int offset = this.offset + index;
212 long l = 0;
213 for (int i = offset; i < offset + Bytes.SIZEOF_LONG; i++) {
214 l <<= 8;
215 l ^= bytes[i] & 0xFF;
216 }
217 return l;
218 }
219
220
221 @Override
222 public long getVLong(int index) {
223 int shift = 0;
224 long result = 0;
225 while (shift < 64) {
226 final byte b = get(index++);
227 result |= (long) (b & 0x7F) << shift;
228 if ((b & 0x80) == 0) {
229 break;
230 }
231 shift += 7;
232 }
233 return result;
234 }
235
236
237 public static int getVLongSize(long val) {
238 int rPos = 0;
239 while ((val & ~0x7F) != 0) {
240 val >>>= 7;
241 rPos++;
242 }
243 return rPos + 1;
244 }
245
246 @Override
247 public abstract ByteRange put(int index, byte val);
248
249 @Override
250 public abstract ByteRange put(int index, byte[] val);
251
252 @Override
253 public abstract ByteRange put(int index, byte[] val, int offset, int length);
254
255 @Override
256 public abstract ByteRange putInt(int index, int val);
257
258 @Override
259 public abstract ByteRange putLong(int index, long val);
260
261 @Override
262 public abstract ByteRange putShort(int index, short val);
263
264 @Override
265 public abstract int putVLong(int index, long val);
266
267
268
269
270
271 @Override
272 public byte[] deepCopyToNewArray() {
273 byte[] result = new byte[length];
274 System.arraycopy(bytes, offset, result, 0, length);
275 return result;
276 }
277
278 @Override
279 public void deepCopyTo(byte[] destination, int destinationOffset) {
280 System.arraycopy(bytes, offset, destination, destinationOffset, length);
281 }
282
283 @Override
284 public void deepCopySubRangeTo(int innerOffset, int copyLength, byte[] destination,
285 int destinationOffset) {
286 System.arraycopy(bytes, offset + innerOffset, destination, destinationOffset, copyLength);
287 }
288
289
290
291
292
293 @Override
294 public int hashCode() {
295 if (isHashCached()) {
296 return hash;
297 }
298 if (this.isEmpty()) {
299 hash = 0;
300 return hash;
301 }
302 int off = offset;
303 hash = 0;
304 for (int i = 0; i < length; i++) {
305 hash = 31 * hash + bytes[off++];
306 }
307 return hash;
308 }
309
310 protected boolean isHashCached() {
311 return hash != UNSET_HASH_VALUE;
312 }
313
314 protected void clearHashCache() {
315 hash = UNSET_HASH_VALUE;
316 }
317
318
319
320
321
322 @Override
323 public int compareTo(ByteRange other) {
324 return Bytes.compareTo(bytes, offset, length, other.getBytes(), other.getOffset(),
325 other.getLength());
326 }
327
328 @Override
329 public String toString() {
330 return Bytes.toStringBinary(bytes, offset, length);
331 }
332 }