/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.unit; import java.util.BitSet; import java.util.Random; import org.h2.test.TestBase; import org.h2.util.BitField; /** * A unit test for bit fields. */ public class TestBitField extends TestBase { /** * Run just this test. * * @param a ignored */ public static void main(String... a) throws Exception { TestBase.createCaller().init().test(); } public void test() { testNextClearBit(); testByteOperations(); testRandom(); testGetSet(); testRandomSetRange(); } private void testNextClearBit() { BitSet set = new BitSet(); BitField field = new BitField(); set.set(0, 640); field.set(0, 640, true); assertEquals(set.nextClearBit(0), field.nextClearBit(0)); Random random = new Random(1); field = new BitField(); field.set(0, 500, true); for (int i = 0; i < 100000; i++) { int a = random.nextInt(120); int b = a + 1 + random.nextInt(200); field.clear(a); field.clear(b); assertEquals(b, field.nextClearBit(a + 1)); field.set(a); field.set(b); } } private void testByteOperations() { BitField used = new BitField(); testSetFast(used, false); testSetFast(used, true); } private void testSetFast(BitField used, boolean init) { int len = 10000; Random random = new Random(1); for (int i = 0, x = 0; i < len / 8; i++) { int mask = random.nextInt() & 255; if (init) { assertEquals(mask, used.getByte(x)); x += 8; // for (int j = 0; j < 8; j++, x++) { // if (used.get(x) != ((mask & (1 << j)) != 0)) { // throw Message.getInternalError( // "Redo failure, block: " + x + // " expected in-use bit: " + used.get(x)); // } // } } else { used.setByte(x, mask); x += 8; // for (int j = 0; j < 8; j++, x++) { // if ((mask & (1 << j)) != 0) { // used.set(x); // } // } } } } private void testRandom() { BitField bits = new BitField(); BitSet set = new BitSet(); int max = 300; int count = 100000; Random random = new Random(1); for (int i = 0; i < count; i++) { int idx = random.nextInt(max); if (random.nextBoolean()) { if (random.nextBoolean()) { bits.set(idx); set.set(idx); } else { bits.clear(idx); set.clear(idx); } } else { assertEquals(set.get(idx), bits.get(idx)); assertEquals(set.nextClearBit(idx), bits.nextClearBit(idx)); assertEquals(set.length(), bits.length()); } } } private void testGetSet() { BitField bits = new BitField(); for (int i = 0; i < 10000; i++) { bits.set(i); if (!bits.get(i)) { fail("not set: " + i); } if (bits.get(i + 1)) { fail("set: " + i); } } for (int i = 0; i < 10000; i++) { if (!bits.get(i)) { fail("not set: " + i); } } for (int i = 0; i < 1000; i++) { int k = bits.nextClearBit(0); if (k != 10000) { fail("" + k); } } } private void testRandomSetRange() { BitField bits = new BitField(); BitSet set = new BitSet(); Random random = new Random(1); int maxOffset = 500; int maxLen = 500; int total = maxOffset + maxLen; int count = 10000; for (int i = 0; i < count; i++) { int offset = random.nextInt(maxOffset); int len = random.nextInt(maxLen); boolean val = random.nextBoolean(); set.set(offset, offset + len, val); bits.set(offset, offset + len, val); for (int j = 0; j < total; j++) { assertEquals(set.get(j), bits.get(j)); } } } }