GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
TestBitfield00.java
Go to the documentation of this file.
1/**
2 * Copyright 2015 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.common.util;
30
31import java.io.IOException;
32
33import org.junit.Test;
34import org.junit.Assert;
35
36import com.jogamp.junit.util.SingletonJunitCase;
37
38import org.junit.FixMethodOrder;
39import org.junit.runners.MethodSorters;
40
41/**
42 * Test basic bitfield operations for {@link Bitfield}
43 */
44@FixMethodOrder(MethodSorters.NAME_ASCENDING)
45public class TestBitfield00 extends SingletonJunitCase {
46
47 @Test
48 public void test01_BitCount32_One() {
49 final String[] pyramid32bit_one = BitDemoData.pyramid32bit_one;
50 for(int i=0; i<pyramid32bit_one.length; i++) {
51 final int val0 = 1 << i;
52 final int oneBitCountI = Integer.bitCount(val0);
53 final String pattern0 = pyramid32bit_one[i];
54 final int val1 = BitDemoData.toInteger(pattern0);
55 final String pattern1 = BitDemoData.toBinaryString(val0, 32);
56 final int oneBitCount0 = BitDemoData.getOneBitCount(pattern0);
57 final int oneBitCount1 = Bitfield.Util.bitCount(val0);
58 final String msg = String.format("Round %02d: 0x%08x %s, c %d / %d%n : 0x%08x %s, c %d%n",
59 i, val0, pattern0, oneBitCount0, oneBitCountI, val1, pattern1, oneBitCount1);
60
61 Assert.assertEquals(msg, val0, val1);
62 Assert.assertEquals(msg, pattern0, pattern1);
63
64 Assert.assertEquals(msg, oneBitCount0, oneBitCountI);
65 Assert.assertEquals(msg, oneBitCount0, oneBitCount1);
66 }
67 }
68
69 @SuppressWarnings("unused")
70 @Test
72 final long MAX = BitDemoData.UNSIGNED_INT_MAX_VALUE;
73 final long MAX_minus = MAX-0x1FF;
74 final long MAX_half = MAX/2;
75 final long MAX_half_minus = MAX_half-0x1FF;
76 final long MAX_half_plus = MAX_half+0x1FF;
77
78 if( false ) {
79 for(long l=0; l<=MAX; l++) {
80 test_BitCount32_Samples(l);
81 }
82 }
83 for(long l=0; l>=0x1FF; l++) {
84 test_BitCount32_Samples(l);
85 }
86 for(long l=MAX_half_minus; l<=MAX_half_plus; l++) {
87 test_BitCount32_Samples(l);
88 }
89 for(long l=MAX_minus; l<=MAX; l++) {
90 test_BitCount32_Samples(l);
91 }
92 }
93 static void test_BitCount32_Samples(final long l) {
94 final int oneBitCountL = Long.bitCount(l);
95 final int val0 = (int)l;
96 final int oneBitCountI = Integer.bitCount(val0);
97 final int oneBitCount1 = Bitfield.Util.bitCount(val0);
98 final String msg = String.format("Round 0x%08x, c %d / %d / %d", val0,
99 oneBitCountL, oneBitCountI, oneBitCount1);
100 Assert.assertEquals(msg, oneBitCountI, oneBitCountL);
101 Assert.assertEquals(msg, oneBitCountI, oneBitCount1);
102 }
103
104 static int[] testDataOneBit = new int[] {
105 0,0, 1,1, 2,1, 3,2, 4,1, 5,2, 6,2, 7,3,
106 8,1, 9,2, 10,2, 11,3, 12,2, 13,3, 14,3, 15,4, 16,1, 17,2,
107 0x3F,6, 0x40,1, 0x41,2, 0x7f,7, 0x80,1, 0x81,2, 0xfe,7, 0xff,8,
108 0x4000,1, 0x4001,2, 0x7000,3, 0x7fff,15,
109 0x0FFFFFF0,24,
110 0x55555555,16,
111 0x7F53F57B,23, 0xFEA7EAF6,23, /* << 1 */
112 0x80000000, 1,
113 0xAAAAAAAA,16,
114 0xC0C0C0C0, 8,
115 0xFF000000, 8,
116 0xFFFFFFFF,32
117 };
118 @Test
120 for(int i = 0; i<testDataOneBit.length; i+=2) {
121 test_BitCount32_Data(testDataOneBit[i], testDataOneBit[i+1]);
122 }
123 }
124 static void test_BitCount32_Data(final int i, final int expOneBits) {
125 final int oneBitCountI = Integer.bitCount(i);
126 final int oneBitCount1 = Bitfield.Util.bitCount(i);
127 final String msg = String.format("Round 0x%08x, c %d / %d", i,
128 oneBitCountI, oneBitCount1);
129 Assert.assertEquals(msg, oneBitCount1, expOneBits);
130 Assert.assertEquals(msg, oneBitCountI, oneBitCount1);
131 }
132
133 @Test
134 public void test10_Setup() {
135 final int bitSize32 = 32;
136 final int bitSize128 = 128;
137 final Bitfield bf1 = Bitfield.Factory.create(bitSize32);
138 Assert.assertEquals(bitSize32, bf1.size());
139 Assert.assertTrue(bf1 instanceof jogamp.common.util.Int32Bitfield);
140 final Bitfield bf2 = Bitfield.Factory.create(bitSize128);
141 Assert.assertEquals(bitSize128, bf2.size());
142 Assert.assertTrue(bf2 instanceof jogamp.common.util.Int32ArrayBitfield);
143
144 // verify no bit is set
145 Assert.assertEquals(0, bf1.bitCount());
146 Assert.assertEquals(0, bf2.bitCount());
147
148 bf1.clearField(true);
149 bf2.clearField(true);
150 Assert.assertEquals(bf1.size(), bf1.bitCount());
151 Assert.assertEquals(bf2.size(), bf2.bitCount());
152
153 bf1.clearField(false);
154 bf2.clearField(false);
155 Assert.assertEquals(0, bf1.bitCount());
156 Assert.assertEquals(0, bf2.bitCount());
157 }
158 static class TestDataBF {
159 final int bitSize;
160 final int val;
161 final String pattern;
162 public TestDataBF(final int bitSize, final int value, final String pattern) {
163 this.bitSize = bitSize;
164 this.val = value;
165 this.pattern = pattern;
166 }
167 }
168 static TestDataBF[] testDataBF32Bit = {
169 new TestDataBF(32, BitDemoData.testIntMSB, BitDemoData.testStringMSB),
170 new TestDataBF(32, BitDemoData.testIntMSB_rev, BitDemoData.testStringMSB_rev),
171 new TestDataBF(32, BitDemoData.testIntLSB, BitDemoData.testStringLSB),
172 new TestDataBF(32, BitDemoData.testIntLSB_revByte, BitDemoData.testStringLSB_revByte),
173
174 // H->L : 0x04030201: 00000100 00000011 00000010 00000001
175 new TestDataBF(32, 0x04030201, "00000100000000110000001000000001"),
176
177 // H->L : 0xAFFECAFE: 10101111 11111110 11001010 11111110
178 new TestDataBF(32, 0xAFFECAFE, "10101111111111101100101011111110"),
179 // H->L : 0xDEADBEEF: 11011110 10101101 10111110 11101111
180 new TestDataBF(32, 0xDEADBEEF, "11011110101011011011111011101111")
181 };
182 static TestDataBF[] testDataBF16Bit = {
183 // H->L : 0x0201: 00000100 00000011 00000010 00000001
184 new TestDataBF(16, 0x0201, "0000001000000001"),
185 // H->L : 0x0403: 00000100 00000011
186 new TestDataBF(16, 0x0403, "0000010000000011"),
187
188 // H->L : 0xAFFE: 10101111 11111110
189 new TestDataBF(16, 0xAFFE, "1010111111111110"),
190 // H->L : 0xCAFE: 11001010 11111110
191 new TestDataBF(16, 0xCAFE, "1100101011111110"),
192
193 // H->L : 0xDEADBEEF: 11011110 10101101 10111110 11101111
194 new TestDataBF(16, 0xDEAD, "1101111010101101"),
195 new TestDataBF(16, 0xBEEF, "1011111011101111")
196 };
197 static TestDataBF[] testDataBF3Bit = {
198 new TestDataBF(3, 0x01, "001"),
199 new TestDataBF(3, 0x02, "010"),
200 new TestDataBF(3, 0x05, "101")
201 };
202
203 @Test
205 for(int i=0; i<testDataBF32Bit.length; i++) {
206 test_ValidateTestData( testDataBF32Bit[i] );
207 }
208 for(int i=0; i<testDataBF16Bit.length; i++) {
209 test_ValidateTestData( testDataBF16Bit[i] );
210 }
211 for(int i=0; i<testDataBF3Bit.length; i++) {
212 test_ValidateTestData( testDataBF3Bit[i] );
213 }
214 }
215 static void test_ValidateTestData(final TestDataBF d) {
216 final int oneBitCount0 = Bitfield.Util.bitCount(d.val);
217 final int oneBitCount1 = BitDemoData.getOneBitCount(d.pattern);
218 Assert.assertEquals(oneBitCount1, oneBitCount0);
219 final String pattern0 = BitDemoData.toBinaryString(d.val, d.bitSize);
220 Assert.assertEquals(d.pattern, pattern0);
221 final int val1 = BitDemoData.toInteger(d.pattern);
222 Assert.assertEquals(d.val, val1);
223 Assert.assertEquals(d.bitSize, pattern0.length());
224 }
225
226 static void assertEquals(final Bitfield bf, final int bf_off, final int v, final String pattern, final int oneBitCount) {
227 final int len = pattern.length();
228 for(int i=0; i<len; i++) {
229 final boolean exp0 = 0 != ( v & ( 1 << i ) );
230 final boolean exp1 = '1' == pattern.charAt(len-1-i);
231 final boolean has = bf.get(i+bf_off);
232 final String msg = String.format("Pos %04d: Value 0x%08x / %s, c %d", i, v, pattern, oneBitCount);
233 Assert.assertEquals(msg, exp0, has);
234 Assert.assertEquals(msg, exp1, has);
235 }
236 }
237
238 @Test
239 public void test21_Aligned32bit() {
240 for(int i=0; i<testDataBF32Bit.length; i++) {
241 test_Aligned32bit( testDataBF32Bit[i] );
242 }
243 for(int i=0; i<testDataBF16Bit.length; i++) {
244 test_Aligned32bit( testDataBF16Bit[i] );
245 }
246 for(int i=0; i<testDataBF3Bit.length; i++) {
247 test_Aligned32bit( testDataBF3Bit[i] );
248 }
249 }
250 static int get32BitStorageSize(final int bits) {
251 final int units = Math.max(1, ( bits + 31 ) >>> 5);
252 return units << 5;
253 }
254 static void test_Aligned32bit(final TestDataBF d) {
255 final int oneBitCount = Bitfield.Util.bitCount(d.val);
256
257 final Bitfield bf1 = Bitfield.Factory.create(d.bitSize);
258 Assert.assertEquals(get32BitStorageSize(d.bitSize), bf1.size());
259 final Bitfield bf2 = Bitfield.Factory.create(d.bitSize+128);
260 Assert.assertEquals(get32BitStorageSize(d.bitSize+128), bf2.size());
261
262 bf1.put32( 0, d.bitSize, d.val);
263 Assert.assertEquals(d.val, bf1.get32( 0, d.bitSize));
264 Assert.assertEquals(oneBitCount, bf1.bitCount());
265 assertEquals(bf1, 0, d.val, d.pattern, oneBitCount);
266
267 bf2.put32( 0, d.bitSize, d.val);
268 Assert.assertEquals(d.val, bf2.get32( 0, d.bitSize));
269 Assert.assertEquals(oneBitCount*1, bf2.bitCount());
270 assertEquals(bf2, 0, d.val, d.pattern, oneBitCount);
271 bf2.put32(64, d.bitSize, d.val);
272 Assert.assertEquals(d.val, bf2.get32(64, d.bitSize));
273 Assert.assertEquals(oneBitCount*2, bf2.bitCount());
274 assertEquals(bf2, 64, d.val, d.pattern, oneBitCount);
275
276 Assert.assertEquals(d.val, bf2.copy32(0, 96, d.bitSize));
277 Assert.assertEquals(d.val, bf2.get32(96, d.bitSize));
278 Assert.assertEquals(oneBitCount*3, bf2.bitCount());
279 assertEquals(bf2, 96, d.val, d.pattern, oneBitCount);
280 }
281
282 @Test
283 public void test21_Unaligned() {
284 for(int i=0; i<testDataBF32Bit.length; i++) {
285 test_Unaligned(testDataBF32Bit[i]);
286 }
287 for(int i=0; i<testDataBF16Bit.length; i++) {
288 test_Unaligned(testDataBF16Bit[i]);
289 }
290 for(int i=0; i<testDataBF3Bit.length; i++) {
291 test_Unaligned( testDataBF3Bit[i] );
292 }
293 }
294 static void test_Unaligned(final TestDataBF d) {
295 final Bitfield bf1 = Bitfield.Factory.create(d.bitSize);
296 final Bitfield bf2 = Bitfield.Factory.create(d.bitSize+128);
297 Assert.assertEquals(get32BitStorageSize(d.bitSize), bf1.size());
298 Assert.assertEquals(get32BitStorageSize(d.bitSize+128), bf2.size());
299 test_Unaligned( d, bf1 );
300 test_Unaligned( d, bf2 );
301 }
302 static void test_Unaligned(final TestDataBF d, final Bitfield bf) {
303 final int maxBitpos = bf.size()-d.bitSize;
304 for(int i=0; i<=maxBitpos; i++) {
305 bf.clearField(false);
306 test_Unaligned(d, bf, i);
307 }
308 }
309 static void test_Unaligned(final TestDataBF d, final Bitfield bf, final int lowBitnum) {
310 final int maxBitpos = bf.size()-d.bitSize;
311 final int oneBitCount = Bitfield.Util.bitCount(d.val);
312
313 final String msg = String.format("Value 0x%08x / %s, l %d/%d, c %d, lbPos %d -> %d",
314 d.val, d.pattern, d.bitSize, bf.size(), oneBitCount, lowBitnum, maxBitpos);
315
316 //
317 // via put32
318 //
319 bf.put32( lowBitnum, d.bitSize, d.val);
320 for(int i=0; i<d.bitSize; i++) {
321 Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ), bf.get(lowBitnum+i));
322 }
323 Assert.assertEquals(msg, d.val, bf.get32( lowBitnum, d.bitSize));
324 Assert.assertEquals(msg, oneBitCount, bf.bitCount());
325 assertEquals(bf, lowBitnum, d.val, d.pattern, oneBitCount);
326
327 //
328 // via copy32
329 //
330 if( lowBitnum < maxBitpos ) {
331 // copy bits 1 forward
332 // clear trailing orig bit
333 Assert.assertEquals(msg, d.val, bf.copy32(lowBitnum, lowBitnum+1, d.bitSize));
334 bf.clear(lowBitnum);
335 Assert.assertEquals(msg, d.val, bf.get32( lowBitnum+1, d.bitSize));
336 Assert.assertEquals(msg, oneBitCount, bf.bitCount());
337 assertEquals(bf, lowBitnum+1, d.val, d.pattern, oneBitCount);
338 }
339
340 // test put() return value (previous value)
341 bf.clearField(false);
342 Assert.assertEquals(msg+", bitpos "+0, false, bf.put(lowBitnum+0, true));
343 Assert.assertEquals(msg+", bitpos "+0, true, bf.put(lowBitnum+0, false));
344
345 //
346 // via put
347 //
348 for(int i=0; i<d.bitSize; i++) {
349 Assert.assertEquals(msg+", bitpos "+i, false, bf.put(lowBitnum+i, 0 != ( d.val & ( 1 << i ) )));
350 }
351 Assert.assertEquals(msg, d.val, bf.get32(lowBitnum, d.bitSize));
352 for(int i=0; i<d.bitSize; i++) {
353 Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ), bf.get(lowBitnum+i));
354 }
355 Assert.assertEquals(msg, oneBitCount, bf.bitCount());
356 assertEquals(bf, lowBitnum, d.val, d.pattern, oneBitCount);
357
358 //
359 // via copy
360 //
361 if( lowBitnum < maxBitpos ) {
362 // copy bits 1 forward
363 // clear trailing orig bit
364 for(int i=d.bitSize-1; i>=0; i--) {
365 Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ),
366 bf.copy(lowBitnum+i, lowBitnum+1+i) );
367 }
368 bf.clear(lowBitnum);
369 Assert.assertEquals(msg, d.val, bf.get32( lowBitnum+1, d.bitSize));
370 for(int i=0; i<d.bitSize; i++) {
371 Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ), bf.get(lowBitnum+1+i));
372 }
373 Assert.assertEquals(msg, oneBitCount, bf.bitCount());
374 assertEquals(bf, lowBitnum+1, d.val, d.pattern, oneBitCount);
375 }
376
377 //
378 // via set/clear
379 //
380 bf.clearField(false);
381 for(int i=0; i<d.bitSize; i++) {
382 if( 0 != ( d.val & ( 1 << i ) ) ) {
383 bf.set(lowBitnum+i);
384 } else {
385 bf.clear(lowBitnum+i);
386 }
387 }
388 Assert.assertEquals(msg, d.val, bf.get32(lowBitnum, d.bitSize));
389 for(int i=0; i<d.bitSize; i++) {
390 Assert.assertEquals(msg+", bitpos "+i, 0 != ( d.val & ( 1 << i ) ), bf.get(lowBitnum+i));
391 }
392 Assert.assertEquals(msg, oneBitCount, bf.bitCount());
393 assertEquals(bf, lowBitnum, d.val, d.pattern, oneBitCount);
394
395 //
396 // Validate 'other bits' put32/get32
397 //
398 bf.clearField(false);
399 bf.put32( lowBitnum, d.bitSize, d.val);
400 checkOtherBits(d, bf, lowBitnum, msg, 0);
401
402 bf.clearField(true);
403 bf.put32( lowBitnum, d.bitSize, d.val);
404 checkOtherBits(d, bf, lowBitnum, msg, Bitfield.UNSIGNED_INT_MAX_VALUE);
405 }
406
407 static void checkOtherBits(final TestDataBF d, final Bitfield bf, final int lowBitnum, final String msg, final int expBits) {
408 final int highBitnum = lowBitnum + d.bitSize - 1;
409 // System.err.println(msg+": [0"+".."+"("+lowBitnum+".."+highBitnum+").."+(bf.size()-1)+"]");
410 for(int i=0; i<lowBitnum; i+=32) {
411 final int len = Math.min(32, lowBitnum-i);
412 final int val = bf.get32(i, len);
413 final int exp = expBits & Bitfield.Util.getBitMask(len);
414 // System.err.println(" <"+i+".."+(i+len-1)+">, exp "+BitDemoData.toHexString(exp));
415 Assert.assertEquals(msg+", bitpos "+i, exp, val);
416 }
417 for(int i=highBitnum+1; i<bf.size(); i+=32) {
418 final int len = Math.min(32, bf.size() - i);
419 final int val = bf.get32(i, len);
420 final int exp = expBits & Bitfield.Util.getBitMask(len);
421 // System.err.println(" <"+i+".."+(i+len-1)+">, exp "+BitDemoData.toHexString(exp));
422 Assert.assertEquals(msg+", bitpos "+i, exp, val);
423 }
424 }
425
426 public static void main(final String args[]) throws IOException {
427 final String tstname = TestBitfield00.class.getName();
428 org.junit.runner.JUnitCore.main(tstname);
429 }
430
431}
static int getOneBitCount(final String pattern)
static String toBinaryString(final int v, final int bitCount)
static final long UNSIGNED_INT_MAX_VALUE
static final String[] pyramid32bit_one
static int toInteger(final String bitPattern)
Simple Bitfield factory for returning the efficient implementation.
Definition: Bitfield.java:146
static Bitfield create(final int storageBitSize)
Creates am efficient Bitfield instance based on the requested storageBitSize.
Definition: Bitfield.java:154
Bit operation utilities (static).
Definition: Bitfield.java:43
static final int bitCount(int n)
Returns the number of set bits within given 32bit integer in O(1) using a HAKEM 169 Bit Count inspire...
Definition: Bitfield.java:82
Test basic bitfield operations for Bitfield.
static void main(final String args[])
Simple bitfield interface for efficient bit storage access in O(1).
Definition: Bitfield.java:36
int bitCount()
Returns the number of one bits within this bitfield.
void clearField(final boolean bit)
Set all bits of this bitfield to the given value bit.
int size()
Returns the storage size in bit units, e.g.