HBASE-19497 Fix findbugs and error-prone warnings in hbase-common (branch-2)
[hbase.git] / hbase-common / src / test / java / org / apache / hadoop / hbase / nio / TestMultiByteBuff.java
blob3b724b1cf2cde775dd30d4bbf07ceea03dbc58ea
1 /**
2 * Copyright The Apache Software Foundation
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 package org.apache.hadoop.hbase.nio;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotEquals;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
28 import java.io.IOException;
29 import java.nio.BufferOverflowException;
30 import java.nio.ByteBuffer;
32 import org.apache.hadoop.hbase.testclassification.MiscTests;
33 import org.apache.hadoop.hbase.testclassification.SmallTests;
34 import org.apache.hadoop.hbase.util.ByteBufferUtils;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.apache.hadoop.hbase.util.ObjectIntPair;
37 import org.junit.Test;
38 import org.junit.experimental.categories.Category;
40 @Category({ MiscTests.class, SmallTests.class })
41 public class TestMultiByteBuff {
43 @Test
44 public void testWritesAndReads() {
45 // Absolute reads
46 ByteBuffer bb1 = ByteBuffer.allocate(15);
47 ByteBuffer bb2 = ByteBuffer.allocate(15);
48 int i1 = 4;
49 bb1.putInt(i1);
50 long l1 = 45L, l2 = 100L, l3 = 12345L;
51 bb1.putLong(l1);
52 short s1 = 2;
53 bb1.putShort(s1);
54 byte[] b = Bytes.toBytes(l2);
55 bb1.put(b, 0, 1);
56 bb2.put(b, 1, 7);
57 bb2.putLong(l3);
58 MultiByteBuff mbb = new MultiByteBuff(bb1, bb2);
59 assertEquals(l1, mbb.getLong(4));
60 assertEquals(l2, mbb.getLong(14));
61 assertEquals(l3, mbb.getLong(22));
62 assertEquals(i1, mbb.getInt(0));
63 assertEquals(s1, mbb.getShort(12));
64 // Relative reads
65 assertEquals(i1, mbb.getInt());
66 assertEquals(l1, mbb.getLong());
67 assertEquals(s1, mbb.getShort());
68 assertEquals(l2, mbb.getLong());
69 assertEquals(l3, mbb.getLong());
70 // Absolute writes
71 bb1 = ByteBuffer.allocate(15);
72 bb2 = ByteBuffer.allocate(15);
73 mbb = new MultiByteBuff(bb1, bb2);
74 byte b1 = 5, b2 = 31;
75 mbb.put(b1);
76 mbb.putLong(l1);
77 mbb.putInt(i1);
78 mbb.putLong(l2);
79 mbb.put(b2);
80 mbb.position(mbb.position() + 2);
81 try {
82 mbb.putLong(l3);
83 fail("'Should have thrown BufferOverflowException");
84 } catch (BufferOverflowException e) {
86 mbb.position(mbb.position() - 2);
87 mbb.putLong(l3);
88 mbb.rewind();
89 assertEquals(b1, mbb.get());
90 assertEquals(l1, mbb.getLong());
91 assertEquals(i1, mbb.getInt());
92 assertEquals(l2, mbb.getLong());
93 assertEquals(b2, mbb.get());
94 assertEquals(l3, mbb.getLong());
95 mbb.put(21, b1);
96 mbb.position(21);
97 assertEquals(b1, mbb.get());
98 mbb.put(b);
99 assertEquals(l2, mbb.getLong(22));
102 @Test
103 public void testPutPrimitives() {
104 ByteBuffer bb = ByteBuffer.allocate(10);
105 SingleByteBuff s = new SingleByteBuff(bb);
106 s.putLong(-4465109508325701663L);
107 bb.rewind();
108 long long1 = bb.getLong();
109 assertEquals(-4465109508325701663L, long1);
110 s.position(8);
113 @Test
114 public void testArrayBasedMethods() {
115 byte[] b = new byte[15];
116 ByteBuffer bb1 = ByteBuffer.wrap(b, 1, 10).slice();
117 ByteBuffer bb2 = ByteBuffer.allocate(15);
118 ByteBuff mbb1 = new MultiByteBuff(bb1, bb2);
119 assertFalse(mbb1.hasArray());
120 try {
121 mbb1.array();
122 fail();
123 } catch (UnsupportedOperationException e) {
125 try {
126 mbb1.arrayOffset();
127 fail();
128 } catch (UnsupportedOperationException e) {
130 mbb1 = new SingleByteBuff(bb1);
131 assertTrue(mbb1.hasArray());
132 assertEquals(1, mbb1.arrayOffset());
133 assertEquals(b, mbb1.array());
134 mbb1 = new SingleByteBuff(ByteBuffer.allocateDirect(10));
135 assertFalse(mbb1.hasArray());
136 try {
137 mbb1.array();
138 fail();
139 } catch (UnsupportedOperationException e) {
141 try {
142 mbb1.arrayOffset();
143 fail();
144 } catch (UnsupportedOperationException e) {
148 @Test
149 public void testMarkAndResetWithMBB() {
150 ByteBuffer bb1 = ByteBuffer.allocateDirect(15);
151 ByteBuffer bb2 = ByteBuffer.allocateDirect(15);
152 bb1.putInt(4);
153 long l1 = 45L, l2 = 100L, l3 = 12345L;
154 bb1.putLong(l1);
155 bb1.putShort((short) 2);
156 byte[] b = Bytes.toBytes(l2);
157 bb1.put(b, 0, 1);
158 bb2.put(b, 1, 7);
159 bb2.putLong(l3);
160 ByteBuff multi = new MultiByteBuff(bb1, bb2);
161 assertEquals(4, multi.getInt());
162 assertEquals(l1, multi.getLong());
163 multi.mark();
164 assertEquals((short) 2, multi.getShort());
165 multi.reset();
166 assertEquals((short) 2, multi.getShort());
167 multi.mark();
168 assertEquals(l2, multi.getLong());
169 multi.reset();
170 assertEquals(l2, multi.getLong());
171 multi.mark();
172 assertEquals(l3, multi.getLong());
173 multi.reset();
174 assertEquals(l3, multi.getLong());
175 // Try absolute gets with mark and reset
176 multi.mark();
177 assertEquals(l2, multi.getLong(14));
178 multi.reset();
179 assertEquals(l3, multi.getLong(22));
180 // Just reset to see what happens
181 multi.reset();
182 assertEquals(l2, multi.getLong(14));
183 multi.mark();
184 assertEquals(l3, multi.getLong(22));
185 multi.reset();
188 @Test
189 public void testSkipNBytes() {
190 ByteBuffer bb1 = ByteBuffer.allocate(15);
191 ByteBuffer bb2 = ByteBuffer.allocate(15);
192 bb1.putInt(4);
193 long l1 = 45L, l2 = 100L, l3 = 12345L;
194 bb1.putLong(l1);
195 bb1.putShort((short) 2);
196 byte[] b = Bytes.toBytes(l2);
197 bb1.put(b, 0, 1);
198 bb2.put(b, 1, 7);
199 bb2.putLong(l3);
200 MultiByteBuff multi = new MultiByteBuff(bb1, bb2);
201 assertEquals(4, multi.getInt());
202 assertEquals(l1, multi.getLong());
203 multi.skip(10);
204 assertEquals(l3, multi.getLong());
207 @Test
208 public void testMoveBack() {
209 ByteBuffer bb1 = ByteBuffer.allocate(15);
210 ByteBuffer bb2 = ByteBuffer.allocate(15);
211 bb1.putInt(4);
212 long l1 = 45L, l2 = 100L, l3 = 12345L;
213 bb1.putLong(l1);
214 bb1.putShort((short) 2);
215 byte[] b = Bytes.toBytes(l2);
216 bb1.put(b, 0, 1);
217 bb2.put(b, 1, 7);
218 bb2.putLong(l3);
219 MultiByteBuff multi = new MultiByteBuff(bb1, bb2);
220 assertEquals(4, multi.getInt());
221 assertEquals(l1, multi.getLong());
222 multi.skip(10);
223 multi.moveBack(4);
224 multi.moveBack(6);
225 multi.moveBack(8);
226 assertEquals(l1, multi.getLong());
229 @Test
230 public void testSubBuffer() {
231 ByteBuffer bb1 = ByteBuffer.allocateDirect(10);
232 ByteBuffer bb2 = ByteBuffer.allocateDirect(10);
233 MultiByteBuff multi = new MultiByteBuff(bb1, bb2);
234 long l1 = 1234L, l2 = 100L;
235 multi.putLong(l1);
236 multi.putLong(l2);
237 multi.rewind();
238 ByteBuffer sub = multi.asSubByteBuffer(Bytes.SIZEOF_LONG);
239 assertEquals(bb1, sub);
240 assertEquals(l1, ByteBufferUtils.toLong(sub, sub.position()));
241 multi.skip(Bytes.SIZEOF_LONG);
242 sub = multi.asSubByteBuffer(Bytes.SIZEOF_LONG);
243 assertNotEquals(bb1, sub);
244 assertNotEquals(bb2, sub);
245 assertEquals(l2, ByteBufferUtils.toLong(sub, sub.position()));
246 multi.rewind();
247 ObjectIntPair<ByteBuffer> p = new ObjectIntPair<>();
248 multi.asSubByteBuffer(8, Bytes.SIZEOF_LONG, p);
249 assertNotEquals(bb1, p.getFirst());
250 assertNotEquals(bb2, p.getFirst());
251 assertEquals(0, p.getSecond());
252 assertEquals(l2, ByteBufferUtils.toLong(sub, p.getSecond()));
255 @Test
256 public void testSliceDuplicateMethods() throws Exception {
257 ByteBuffer bb1 = ByteBuffer.allocateDirect(10);
258 ByteBuffer bb2 = ByteBuffer.allocateDirect(15);
259 MultiByteBuff multi = new MultiByteBuff(bb1, bb2);
260 long l1 = 1234L, l2 = 100L;
261 multi.put((byte) 2);
262 multi.putLong(l1);
263 multi.putLong(l2);
264 multi.putInt(45);
265 multi.position(1);
266 multi.limit(multi.position() + (2 * Bytes.SIZEOF_LONG));
267 MultiByteBuff sliced = multi.slice();
268 assertEquals(0, sliced.position());
269 assertEquals((2 * Bytes.SIZEOF_LONG), sliced.limit());
270 assertEquals(l1, sliced.getLong());
271 assertEquals(l2, sliced.getLong());
272 MultiByteBuff dup = multi.duplicate();
273 assertEquals(1, dup.position());
274 assertEquals(dup.position() + (2 * Bytes.SIZEOF_LONG), dup.limit());
275 assertEquals(l1, dup.getLong());
276 assertEquals(l2, dup.getLong());
279 @Test
280 public void testGetWithPosOnMultiBuffers() throws IOException {
281 byte[] b = new byte[4];
282 byte[] b1 = new byte[4];
283 ByteBuffer bb1 = ByteBuffer.wrap(b);
284 ByteBuffer bb2 = ByteBuffer.wrap(b1);
285 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2);
286 mbb1.position(2);
287 mbb1.putInt(4);
288 int res = mbb1.getInt(2);
289 byte[] bres = new byte[4];
290 bres[0] = mbb1.get(2);
291 bres[1] = mbb1.get(3);
292 bres[2] = mbb1.get(4);
293 bres[3] = mbb1.get(5);
294 int expected = Bytes.toInt(bres);
295 assertEquals(expected, res);
298 @Test
299 public void testGetIntStrictlyForwardWithPosOnMultiBuffers() throws IOException {
300 byte[] b = new byte[4];
301 byte[] b1 = new byte[8];
302 ByteBuffer bb1 = ByteBuffer.wrap(b);
303 ByteBuffer bb2 = ByteBuffer.wrap(b1);
304 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2);
305 mbb1.position(2);
306 mbb1.putInt(4);
307 mbb1.position(7);
308 mbb1.put((byte) 2);
309 mbb1.putInt(3);
310 mbb1.rewind();
311 mbb1.getIntAfterPosition(4);
312 byte res = mbb1.get(7);
313 assertEquals((byte) 2, res);
314 mbb1.position(7);
315 int intRes = mbb1.getIntAfterPosition(1);
316 assertEquals(3, intRes);
319 @Test
320 public void testPositonalCopyToByteArray() throws Exception {
321 byte[] b = new byte[4];
322 byte[] b1 = new byte[8];
323 ByteBuffer bb1 = ByteBuffer.wrap(b);
324 ByteBuffer bb2 = ByteBuffer.wrap(b1);
325 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2);
326 mbb1.position(2);
327 mbb1.putInt(4);
328 mbb1.position(7);
329 mbb1.put((byte) 2);
330 mbb1.putInt(3);
331 byte[] dst = new byte[4];
332 mbb1.get(2, dst, 0, 4);
333 assertEquals(4, Bytes.toInt(dst));
334 assertEquals(12, mbb1.position());
335 mbb1.position(1);
336 dst = new byte[4];
337 mbb1.get(8, dst, 0, 4);
338 assertEquals(3, Bytes.toInt(dst));
339 assertEquals(1, mbb1.position());
340 mbb1.position(12);
341 dst = new byte[1];
342 mbb1.get(7, dst, 0, 1);
343 assertEquals(2, dst[0]);
344 assertEquals(12, mbb1.position());
347 @Test
348 public void testToBytes() throws Exception {
349 byte[] b = new byte[4];
350 byte[] b1 = new byte[8];
351 for (int i = 0; i < b.length; i++) {
352 b[i] = (byte) i;
354 for (int i = 0; i < b1.length; i++) {
355 b1[i] = (byte) (b1.length + i);
357 ByteBuffer bb1 = ByteBuffer.wrap(b);
358 ByteBuffer bb2 = ByteBuffer.wrap(b1);
359 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2);
361 // Test 1 Offset hitting exclusive second element
362 byte[] actual = mbb1.toBytes(6, 4);
363 assertTrue(Bytes.equals(actual, 0, actual.length,
364 b1, 2, 4));
365 // Test 2 offset hitting exclusive second element
366 // but continuing to the end of the second one
367 actual = mbb1.toBytes(5, 7);
368 assertTrue(Bytes.equals(actual, 0, actual.length,
369 b1, 1, 7));
370 // Test 3 with offset hitting in first element,
371 // continuing to next
372 actual = mbb1.toBytes(2, 7);
373 byte[] expected = new byte[7];
374 System.arraycopy(b, 2, expected, 0, 2);
375 System.arraycopy(b1, 0, expected, 2, 5);
376 assertTrue(Bytes.equals(actual, expected));
377 // Test 4 hitting only in first exclusively
378 actual = mbb1.toBytes(1, 3);
379 assertTrue(Bytes.equals(actual, 0, actual.length,
380 b, 1, 3));
383 @Test
384 public void testHasRemaining() {
385 ByteBuffer b1 = ByteBuffer.allocate(8);
386 ByteBuffer b2 = ByteBuffer.allocate(8);
387 ByteBuffer b3 = ByteBuffer.allocate(8);
388 MultiByteBuff mbb1 = new MultiByteBuff(b1, b2, b3);
389 assertTrue(mbb1.hasRemaining());
390 mbb1.limit(20); // Limit in mid of last of BB
391 mbb1.position(15);
392 mbb1.get();// We are at the end of second BB
393 assertTrue(mbb1.hasRemaining());
394 mbb1.position(20);
395 assertFalse(mbb1.hasRemaining());
396 mbb1.limit(12); // Limit in mid of second BB
397 mbb1.position(11);
398 assertTrue(mbb1.hasRemaining());
399 mbb1.get(); // Now we have reached the limit
400 assertFalse(mbb1.hasRemaining());
401 mbb1.limit(16);// Limit at begin of the last BB
402 mbb1.position(15);
403 assertTrue(mbb1.hasRemaining());
404 mbb1.get(); // Now we have reached the limit
405 assertFalse(mbb1.hasRemaining());