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