1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.util;
18
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.DataInputStream;
28 import java.io.DataOutputStream;
29 import java.io.IOException;
30 import java.nio.ByteBuffer;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Set;
34 import java.util.SortedSet;
35 import java.util.TreeSet;
36
37 import org.apache.hadoop.hbase.testclassification.SmallTests;
38 import org.apache.hadoop.io.WritableUtils;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43 @Category(SmallTests.class)
44 public class TestByteBufferUtils {
45
46 private byte[] array;
47
48
49
50
51 @Before
52 public void setUp() {
53 array = new byte[8];
54 for (int i = 0; i < array.length; ++i) {
55 array[i] = (byte) ('a' + i);
56 }
57 }
58
59 private static final int MAX_VLONG_LENGTH = 9;
60 private static final Collection<Long> testNumbers;
61
62 private static void addNumber(Set<Long> a, long l) {
63 if (l != Long.MIN_VALUE) {
64 a.add(l - 1);
65 }
66 a.add(l);
67 if (l != Long.MAX_VALUE) {
68 a.add(l + 1);
69 }
70 for (long divisor = 3; divisor <= 10; ++divisor) {
71 for (long delta = -1; delta <= 1; ++delta) {
72 a.add(l / divisor + delta);
73 }
74 }
75 }
76
77 static {
78 SortedSet<Long> a = new TreeSet<Long>();
79 for (int i = 0; i <= 63; ++i) {
80 long v = (-1L) << i;
81 assertTrue(v < 0);
82 addNumber(a, v);
83 v = (1L << i) - 1;
84 assertTrue(v >= 0);
85 addNumber(a, v);
86 }
87
88 testNumbers = Collections.unmodifiableSet(a);
89 System.err.println("Testing variable-length long serialization using: "
90 + testNumbers + " (count: " + testNumbers.size() + ")");
91 assertEquals(1753, testNumbers.size());
92 assertEquals(Long.MIN_VALUE, a.first().longValue());
93 assertEquals(Long.MAX_VALUE, a.last().longValue());
94 }
95
96 @Test
97 public void testReadWriteVLong() {
98 for (long l : testNumbers) {
99 ByteBuffer b = ByteBuffer.allocate(MAX_VLONG_LENGTH);
100 ByteBufferUtils.writeVLong(b, l);
101 b.flip();
102 assertEquals(l, ByteBufferUtils.readVLong(b));
103 }
104 }
105
106 @Test
107 public void testConsistencyWithHadoopVLong() throws IOException {
108 ByteArrayOutputStream baos = new ByteArrayOutputStream();
109 DataOutputStream dos = new DataOutputStream(baos);
110 for (long l : testNumbers) {
111 baos.reset();
112 ByteBuffer b = ByteBuffer.allocate(MAX_VLONG_LENGTH);
113 ByteBufferUtils.writeVLong(b, l);
114 String bufStr = Bytes.toStringBinary(b.array(),
115 b.arrayOffset(), b.position());
116 WritableUtils.writeVLong(dos, l);
117 String baosStr = Bytes.toStringBinary(baos.toByteArray());
118 assertEquals(baosStr, bufStr);
119 }
120 }
121
122
123
124
125 @Test
126 public void testMoveBufferToStream() {
127 final int arrayOffset = 7;
128 final int initialPosition = 10;
129 final int endPadding = 5;
130 byte[] arrayWrapper =
131 new byte[arrayOffset + initialPosition + array.length + endPadding];
132 System.arraycopy(array, 0, arrayWrapper,
133 arrayOffset + initialPosition, array.length);
134 ByteBuffer buffer = ByteBuffer.wrap(arrayWrapper, arrayOffset,
135 initialPosition + array.length).slice();
136 assertEquals(initialPosition + array.length, buffer.limit());
137 assertEquals(0, buffer.position());
138 buffer.position(initialPosition);
139 ByteArrayOutputStream bos = new ByteArrayOutputStream();
140 try {
141 ByteBufferUtils.moveBufferToStream(bos, buffer, array.length);
142 } catch (IOException e) {
143 fail("IOException in testCopyToStream()");
144 }
145 assertArrayEquals(array, bos.toByteArray());
146 assertEquals(initialPosition + array.length, buffer.position());
147 }
148
149
150
151
152
153 @Test
154 public void testCopyToStreamWithOffset() throws IOException {
155 ByteBuffer buffer = ByteBuffer.wrap(array);
156
157 ByteArrayOutputStream bos = new ByteArrayOutputStream();
158
159 ByteBufferUtils.copyBufferToStream(bos, buffer, array.length / 2,
160 array.length / 2);
161
162 byte[] returnedArray = bos.toByteArray();
163 for (int i = 0; i < array.length / 2; ++i) {
164 int pos = array.length / 2 + i;
165 assertEquals(returnedArray[i], array[pos]);
166 }
167 }
168
169
170
171
172
173 @Test
174 public void testCopyFromStream() throws IOException {
175 ByteBuffer buffer = ByteBuffer.allocate(array.length);
176 ByteArrayInputStream bis = new ByteArrayInputStream(array);
177 DataInputStream dis = new DataInputStream(bis);
178
179 ByteBufferUtils.copyFromStreamToBuffer(buffer, dis, array.length / 2);
180 ByteBufferUtils.copyFromStreamToBuffer(buffer, dis,
181 array.length - array.length / 2);
182 for (int i = 0; i < array.length; ++i) {
183 assertEquals(array[i], buffer.get(i));
184 }
185 }
186
187
188
189
190 @Test
191 public void testCopyFromBuffer() {
192 ByteBuffer srcBuffer = ByteBuffer.allocate(array.length);
193 ByteBuffer dstBuffer = ByteBuffer.allocate(array.length);
194 srcBuffer.put(array);
195
196 ByteBufferUtils.copyFromBufferToBuffer(dstBuffer, srcBuffer,
197 array.length / 2, array.length / 4);
198 for (int i = 0; i < array.length / 4; ++i) {
199 assertEquals(srcBuffer.get(i + array.length / 2),
200 dstBuffer.get(i));
201 }
202 }
203
204
205
206
207
208 @Test
209 public void testCompressedInt() throws IOException {
210 testCompressedInt(0);
211 testCompressedInt(Integer.MAX_VALUE);
212 testCompressedInt(Integer.MIN_VALUE);
213
214 for (int i = 0; i < 3; i++) {
215 testCompressedInt((128 << i) - 1);
216 }
217
218 for (int i = 0; i < 3; i++) {
219 testCompressedInt((128 << i));
220 }
221 }
222
223
224
225
226 @Test
227 public void testIntFitsIn() {
228 assertEquals(1, ByteBufferUtils.intFitsIn(0));
229 assertEquals(1, ByteBufferUtils.intFitsIn(1));
230 assertEquals(2, ByteBufferUtils.intFitsIn(1 << 8));
231 assertEquals(3, ByteBufferUtils.intFitsIn(1 << 16));
232 assertEquals(4, ByteBufferUtils.intFitsIn(-1));
233 assertEquals(4, ByteBufferUtils.intFitsIn(Integer.MAX_VALUE));
234 assertEquals(4, ByteBufferUtils.intFitsIn(Integer.MIN_VALUE));
235 }
236
237
238
239
240 @Test
241 public void testLongFitsIn() {
242 assertEquals(1, ByteBufferUtils.longFitsIn(0));
243 assertEquals(1, ByteBufferUtils.longFitsIn(1));
244 assertEquals(3, ByteBufferUtils.longFitsIn(1l << 16));
245 assertEquals(5, ByteBufferUtils.longFitsIn(1l << 32));
246 assertEquals(8, ByteBufferUtils.longFitsIn(-1));
247 assertEquals(8, ByteBufferUtils.longFitsIn(Long.MIN_VALUE));
248 assertEquals(8, ByteBufferUtils.longFitsIn(Long.MAX_VALUE));
249 }
250
251
252
253
254 @Test
255 public void testArePartEqual() {
256 byte[] array = new byte[] { 1, 2, 3, 4, 5, 1, 2, 3, 4 };
257 ByteBuffer buffer = ByteBuffer.wrap(array);
258 assertTrue(ByteBufferUtils.arePartsEqual(buffer, 0, 4, 5, 4));
259 assertTrue(ByteBufferUtils.arePartsEqual(buffer, 1, 2, 6, 2));
260 assertFalse(ByteBufferUtils.arePartsEqual(buffer, 1, 2, 6, 3));
261 assertFalse(ByteBufferUtils.arePartsEqual(buffer, 1, 3, 6, 2));
262 assertFalse(ByteBufferUtils.arePartsEqual(buffer, 0, 3, 6, 3));
263 }
264
265
266
267
268 @Test
269 public void testPutInt() {
270 testPutInt(0);
271 testPutInt(Integer.MAX_VALUE);
272
273 for (int i = 0; i < 3; i++) {
274 testPutInt((128 << i) - 1);
275 }
276
277 for (int i = 0; i < 3; i++) {
278 testPutInt((128 << i));
279 }
280 }
281
282
283
284 private void testCompressedInt(int value) throws IOException {
285 int parsedValue = 0;
286
287 ByteArrayOutputStream bos = new ByteArrayOutputStream();
288 ByteBufferUtils.putCompressedInt(bos, value);
289
290 ByteArrayInputStream bis = new ByteArrayInputStream(
291 bos.toByteArray());
292 parsedValue = ByteBufferUtils.readCompressedInt(bis);
293
294 assertEquals(value, parsedValue);
295 }
296
297 private void testPutInt(int value) {
298 ByteArrayOutputStream baos = new ByteArrayOutputStream();
299 try {
300 ByteBufferUtils.putInt(baos, value);
301 } catch (IOException e) {
302 throw new RuntimeException("Bug in putIn()", e);
303 }
304
305 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
306 DataInputStream dis = new DataInputStream(bais);
307 try {
308 assertEquals(dis.readInt(), value);
309 } catch (IOException e) {
310 throw new RuntimeException("Bug in test!", e);
311 }
312 }
313
314 @Test
315 public void testToBytes(){
316 ByteBuffer buffer = ByteBuffer.allocate(5);
317 buffer.put(new byte[]{0,1,2,3,4});
318 assertEquals(5, buffer.position());
319 assertEquals(5, buffer.limit());
320 byte[] copy = ByteBufferUtils.toBytes(buffer, 2);
321 assertArrayEquals(new byte[]{2,3,4}, copy);
322 assertEquals(5, buffer.position());
323 assertEquals(5, buffer.limit());
324 }
325 }