mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
java.util.BitSet implementation
This commit is contained in:
parent
2e0ca31148
commit
e1d712ef71
169
classpath/java/util/BitSet.java
Normal file
169
classpath/java/util/BitSet.java
Normal file
@ -0,0 +1,169 @@
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author zsombor
|
||||
*
|
||||
*/
|
||||
public class BitSet implements Serializable, Cloneable {
|
||||
|
||||
final static int BITS_PER_LONG = 64;
|
||||
final static int BITS_PER_LONG_SHIFT = 6;
|
||||
final static long MASK = 0xFFFFFFFFFFFFFFFFL;
|
||||
|
||||
private long[] bits;
|
||||
|
||||
private static int longPosition(int index) {
|
||||
return index >> BITS_PER_LONG_SHIFT;
|
||||
}
|
||||
|
||||
private static long bitPosition(int index) {
|
||||
return 1L << (index % BITS_PER_LONG);
|
||||
}
|
||||
|
||||
public BitSet(int bitLength) {
|
||||
if (bitLength % BITS_PER_LONG == 0) {
|
||||
enlarge(longPosition(bitLength));
|
||||
} else {
|
||||
enlarge(longPosition(bitLength) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public BitSet() {
|
||||
enlarge(1);
|
||||
}
|
||||
|
||||
public void and(BitSet otherBits) {
|
||||
int max = Math.max(bits.length, otherBits.bits.length);
|
||||
for (int i = 0; i < max; i++) {
|
||||
bits[i] &= otherBits.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void andNot(BitSet otherBits) {
|
||||
int max = Math.max(bits.length, otherBits.bits.length);
|
||||
enlarge(max);
|
||||
for (int i = 0; i < max; i++) {
|
||||
bits[i] &= ~otherBits.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void or(BitSet otherBits) {
|
||||
int max = Math.max(bits.length, otherBits.bits.length);
|
||||
enlarge(max);
|
||||
for (int i = 0; i < max; i++) {
|
||||
bits[i] |= otherBits.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void xor(BitSet otherBits) {
|
||||
int max = Math.max(bits.length, otherBits.bits.length);
|
||||
enlarge(max);
|
||||
for (int i = 0; i < max; i++) {
|
||||
bits[i] ^= otherBits.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
private void enlarge(int newSize) {
|
||||
if (bits == null || bits.length <= newSize) {
|
||||
long[] newBits = new long[newSize + 1];
|
||||
if (bits != null) {
|
||||
System.arraycopy(bits, 0, newBits, 0, bits.length);
|
||||
}
|
||||
bits = newBits;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear(int index) {
|
||||
int pos = longPosition(index);
|
||||
if (pos < bits.length) {
|
||||
bits[pos] &= (MASK ^ bitPosition(index));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean get(int index) {
|
||||
int pos = longPosition(index);
|
||||
if (pos < bits.length) {
|
||||
return (bits[pos] & bitPosition(index)) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void set(int index) {
|
||||
int pos = longPosition(index);
|
||||
enlarge(pos);
|
||||
bits[pos] |= bitPosition(index);
|
||||
}
|
||||
|
||||
public void set(int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
set(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear(int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
if (bits[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean intersects(BitSet otherBits) {
|
||||
int max = Math.max(bits.length, otherBits.bits.length);
|
||||
for (int i = 0; i < max; i++) {
|
||||
if ((bits[i] & otherBits.bits[i]) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return bits.length << BITS_PER_LONG_SHIFT;
|
||||
}
|
||||
|
||||
public int nextSetBit(int fromIndex) {
|
||||
return nextBit(fromIndex, false);
|
||||
}
|
||||
|
||||
private int nextBit(int fromIndex, boolean bitClear) {
|
||||
int pos = longPosition(fromIndex);
|
||||
if (pos >= bits.length) {
|
||||
return -1;
|
||||
}
|
||||
int current = fromIndex;
|
||||
do {
|
||||
long currValue = bits[pos];
|
||||
if (currValue == 0) {
|
||||
pos++;
|
||||
current = pos << BITS_PER_LONG_SHIFT;
|
||||
} else {
|
||||
do {
|
||||
long bitPos = bitPosition(current);
|
||||
if (((currValue & bitPos) != 0) ^ bitClear) {
|
||||
return current;
|
||||
} else {
|
||||
current++;
|
||||
}
|
||||
} while (current % BITS_PER_LONG != 0);
|
||||
}
|
||||
pos++;
|
||||
} while (pos < bits.length);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int nextClearBit(int fromIndex) {
|
||||
return nextBit(fromIndex, true);
|
||||
}
|
||||
|
||||
}
|
64
test/BitsetTest.java
Normal file
64
test/BitsetTest.java
Normal file
@ -0,0 +1,64 @@
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitsetTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet(16);
|
||||
bits.set(5);
|
||||
bits.set(1);
|
||||
|
||||
BitSet other = new BitSet(16);
|
||||
other.set(5);
|
||||
|
||||
assertTrue("bit 1 is set", bits.get(1));
|
||||
assertTrue("bit 5 is set", bits.get(5));
|
||||
assertTrue("bit 0 is not set", !bits.get(0));
|
||||
assertTrue("bit 16 is not set", !bits.get(16));
|
||||
|
||||
bits.and(other);
|
||||
|
||||
assertTrue("bit 5 is set", bits.get(5));
|
||||
assertTrue("bit 1 is not set", !bits.get(1));
|
||||
|
||||
bits.set(100);
|
||||
|
||||
assertTrue("bit 100 is set", bits.get(100));
|
||||
assertTrue("bit 101 is not set", !bits.get(101));
|
||||
|
||||
other.set(101);
|
||||
|
||||
bits.or(other);
|
||||
|
||||
assertTrue("bit 101 is set", bits.get(101));
|
||||
|
||||
assertEquals("first bit is 5", 5, bits.nextSetBit(0));
|
||||
assertEquals("first bit is 5 from 3", 5, bits.nextSetBit(4));
|
||||
assertEquals("first bit is 5 from 5", 5, bits.nextSetBit(5));
|
||||
assertEquals("second bit is 100", 100, bits.nextSetBit(6));
|
||||
assertEquals("second bit is 100 from 100", 100, bits.nextSetBit(100));
|
||||
assertEquals("third bit is 101", 101, bits.nextSetBit(101));
|
||||
assertEquals("there is no 4th bit", -1, bits.nextSetBit(102));
|
||||
|
||||
assertEquals("first empty bit is 0", 0, bits.nextClearBit(0));
|
||||
assertEquals("after 5, 6 is empty", 6, bits.nextClearBit(5));
|
||||
assertEquals("after 100, 102 is empty", 102, bits.nextClearBit(100));
|
||||
|
||||
}
|
||||
|
||||
static void assertTrue(String msg, boolean flag) {
|
||||
if (flag) {
|
||||
System.out.println(msg + " : OK.");
|
||||
} else {
|
||||
throw new RuntimeException("Error:"+msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void assertEquals(String msg, int expected, int actual) {
|
||||
if (expected==actual) {
|
||||
System.out.println(msg + " : OK. ["+actual+']');
|
||||
} else {
|
||||
throw new RuntimeException("Error:"+msg+" expected:"+expected+", actual:"+actual);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user