mirror of
https://github.com/corda/corda.git
synced 2025-03-11 15:04:14 +00:00
Merge branch 'master' of https://github.com/mkeesey/avian
This commit is contained in:
commit
7ab4cb0083
@ -80,6 +80,30 @@ public class BitSet implements Serializable, Cloneable {
|
||||
bits[i] ^= otherBits.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void flip(int index) {
|
||||
flip(index, index+1);
|
||||
}
|
||||
|
||||
public void flip(int fromIndex, int toIndex) {
|
||||
if (fromIndex > toIndex || fromIndex < 0 || toIndex < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (fromIndex != toIndex) {
|
||||
int basePartition = longPosition(fromIndex);
|
||||
int lastPartition = longPosition(toIndex - 1); //range is [fromIndex, toIndex)
|
||||
int numPartitionsToTraverse = lastPartition - basePartition + 1;
|
||||
enlarge(lastPartition);
|
||||
|
||||
int currentFirstIndex = fromIndex;
|
||||
for (int i = 0; i < numPartitionsToTraverse; ++i) {
|
||||
int currentToIndex = Math.min(toIndex, (basePartition + i + 1) * BITS_PER_LONG);
|
||||
int currentRange = currentToIndex - currentFirstIndex;
|
||||
long mask = (((1L << currentRange) - 1L) << (currentFirstIndex % BITS_PER_LONG));
|
||||
bits[i + basePartition] ^= mask;
|
||||
currentFirstIndex = currentToIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void enlarge(int newSize) {
|
||||
if (bits == null || bits.length < newSize) {
|
||||
@ -182,4 +206,12 @@ public class BitSet implements Serializable, Cloneable {
|
||||
return nextBit(fromIndex, true);
|
||||
}
|
||||
|
||||
public int cardinality() {
|
||||
int numSetBits = 0;
|
||||
for (int i = nextSetBit(0); i >= 0; i = nextSetBit(i+1)) {
|
||||
++numSetBits;
|
||||
}
|
||||
|
||||
return numSetBits;
|
||||
}
|
||||
}
|
||||
|
149
classpath/java/util/EnumSet.java
Normal file
149
classpath/java/util/EnumSet.java
Normal file
@ -0,0 +1,149 @@
|
||||
package java.util;
|
||||
|
||||
public class EnumSet<T extends Enum<T>> extends AbstractSet<T> {
|
||||
|
||||
private BitSet bitset;
|
||||
private Class<T> elementType;
|
||||
|
||||
private EnumSet(int size, Class<T> type) {
|
||||
bitset = new BitSet(size);
|
||||
elementType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T element) {
|
||||
int index = element.ordinal();
|
||||
boolean contains = bitset.get(index);
|
||||
if (!contains) {
|
||||
bitset.set(index);
|
||||
}
|
||||
|
||||
return !contains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object toRemove) {
|
||||
T element = tryToCast(toRemove);
|
||||
|
||||
int index = element.ordinal();
|
||||
boolean contains = bitset.get(index);
|
||||
if (contains) {
|
||||
bitset.clear(index);
|
||||
}
|
||||
|
||||
return contains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object toCheck) {
|
||||
T element = tryToCast(toCheck);
|
||||
int index = element.ordinal();
|
||||
return bitset.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return bitset.cardinality();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new EnumSetIterator();
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> allOf(Class<T> elementType) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(elementType);
|
||||
addAllElementsToSet(Arrays.asList(elementType.getEnumConstants()), enumSet);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> noneOf(Class<T> elementType) {
|
||||
return createEmptyEnumSet(elementType);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> of(T first, T ... rest) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(first.getDeclaringClass());
|
||||
enumSet.add(first);
|
||||
addAllElementsToSet(Arrays.asList(rest), enumSet);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> complementOf(EnumSet<T> s) {
|
||||
EnumSet<T> enumSet = copyOf(s);
|
||||
enumSet.bitset.flip(0, s.elementType.getEnumConstants().length);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>>EnumSet<T> copyOf(EnumSet<T> s) {
|
||||
EnumSet<T> enumSet = createEmptyEnumSet(s.elementType);
|
||||
enumSet.bitset.or(s.bitset);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>>EnumSet<T> createEmptyEnumSet(Class<T> elementType) {
|
||||
T[] constants = elementType.getEnumConstants();
|
||||
EnumSet<T> enumSet = new EnumSet<T>(constants.length, elementType);
|
||||
|
||||
return enumSet;
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>> void addAllElementsToSet(Iterable<T> elements, EnumSet<T> enumSet) {
|
||||
for (T element : elements) {
|
||||
enumSet.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T tryToCast(Object object) throws ClassCastException {
|
||||
//We want the class cast exception if we can't convert.
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
private class EnumSetIterator implements Iterator<T> {
|
||||
private int currentIndex = 0;
|
||||
private boolean removeAllowed = false;
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException("EnumSet has no more elements");
|
||||
}
|
||||
|
||||
int indexOfNextValue = nextIndex();
|
||||
T element = elementType.getEnumConstants()[indexOfNextValue];
|
||||
currentIndex = indexOfNextValue + 1;
|
||||
removeAllowed = true;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
int indexOfNextValue = nextIndex();
|
||||
if (indexOfNextValue >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
//TODO
|
||||
if (!removeAllowed) {
|
||||
throw new IllegalStateException("Cannot remove from this iterator in this state");
|
||||
}
|
||||
|
||||
bitset.clear(currentIndex - 1);
|
||||
removeAllowed = false;
|
||||
}
|
||||
|
||||
private int nextIndex() {
|
||||
return bitset.nextSetBit(currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,16 +14,19 @@ public class BitsetTest {
|
||||
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));
|
||||
assertCardinality(bits, 2);
|
||||
|
||||
bits.and(other);
|
||||
|
||||
assertTrue("bit 5 is set", bits.get(5));
|
||||
assertTrue("bit 1 is not set", !bits.get(1));
|
||||
assertCardinality(bits, 1);
|
||||
|
||||
bits.set(100);
|
||||
|
||||
assertTrue("bit 100 is set", bits.get(100));
|
||||
assertTrue("bit 101 is not set", !bits.get(101));
|
||||
assertCardinality(bits, 2);
|
||||
|
||||
other.set(101);
|
||||
|
||||
@ -38,11 +41,39 @@ public class BitsetTest {
|
||||
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));
|
||||
assertCardinality(bits, 3);
|
||||
|
||||
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));
|
||||
|
||||
testFlip();
|
||||
}
|
||||
|
||||
private static void testFlip() {
|
||||
/* simple case */
|
||||
BitSet bitset = new BitSet();
|
||||
bitset.set(0);
|
||||
bitset.flip(0, 0);
|
||||
assertTrue("Should not be flipped with 0 length range", bitset.get(0));
|
||||
bitset.flip(0, 1);
|
||||
assertTrue("Should be false with range of one", !bitset.get(0));
|
||||
bitset.flip(0);
|
||||
assertTrue("Should be true again", bitset.get(0));
|
||||
|
||||
/* need to grow */
|
||||
bitset.flip(1000);
|
||||
assertTrue("1000 should be true", bitset.get(1000));
|
||||
assertTrue("1001 should be false", !bitset.get(1001));
|
||||
assertTrue("999 should be false", !bitset.get(999));
|
||||
|
||||
/* Range over 2 segments */
|
||||
bitset.flip(60, 70);
|
||||
assertTrue("59 should be false", !bitset.get(59));
|
||||
for (int i=60; i < 70; ++i) {
|
||||
assertTrue(i + " should be true", bitset.get(i));
|
||||
}
|
||||
assertTrue("70 should be false", !bitset.get(70));
|
||||
}
|
||||
|
||||
static void assertTrue(String msg, boolean flag) {
|
||||
@ -61,4 +92,8 @@ public class BitsetTest {
|
||||
}
|
||||
}
|
||||
|
||||
static void assertCardinality(BitSet set, int expectedCardinality) {
|
||||
assertEquals("Checking cardinality", expectedCardinality, set.cardinality());
|
||||
}
|
||||
|
||||
}
|
||||
|
107
test/EnumSetTest.java
Normal file
107
test/EnumSetTest.java
Normal file
@ -0,0 +1,107 @@
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class EnumSetTest {
|
||||
private enum SmallEnum {
|
||||
ONE,
|
||||
TWO,
|
||||
THREE
|
||||
}
|
||||
|
||||
private enum LargerEnum {
|
||||
LARGEONE,
|
||||
LARGETWO,
|
||||
LARGETHREE,
|
||||
LARGEFOUR,
|
||||
LARGEFIVE,
|
||||
LARGESIX
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testAllOf();
|
||||
testNoneOf();
|
||||
testIterators();
|
||||
testOf();
|
||||
testCopyOf();
|
||||
testComplimentOf();
|
||||
}
|
||||
|
||||
private static void testComplimentOf() {
|
||||
EnumSet<SmallEnum> one = EnumSet.of(SmallEnum.ONE, SmallEnum.THREE);
|
||||
EnumSet<SmallEnum> two = EnumSet.complementOf(one);
|
||||
assertElementInSet(SmallEnum.TWO, two);
|
||||
assertSize(1, two);
|
||||
}
|
||||
|
||||
private static void testCopyOf() {
|
||||
EnumSet<SmallEnum> one = EnumSet.of(SmallEnum.ONE, SmallEnum.THREE);
|
||||
EnumSet<SmallEnum> two = EnumSet.copyOf(one);
|
||||
assertElementInSet(SmallEnum.ONE, two);
|
||||
assertElementInSet(SmallEnum.THREE, two);
|
||||
assertSize(2, two);
|
||||
}
|
||||
|
||||
private static void testOf() {
|
||||
EnumSet<LargerEnum> set = EnumSet.of(LargerEnum.LARGEONE, LargerEnum.LARGEFIVE, LargerEnum.LARGETWO);
|
||||
assertElementInSet(LargerEnum.LARGEONE, set);
|
||||
assertElementInSet(LargerEnum.LARGEFIVE, set);
|
||||
assertElementInSet(LargerEnum.LARGETWO, set);
|
||||
assertSize(3, set);
|
||||
}
|
||||
|
||||
private static void testAllOf() {
|
||||
EnumSet<SmallEnum> set = EnumSet.allOf(SmallEnum.class);
|
||||
for (SmallEnum current : SmallEnum.values()) {
|
||||
assertElementInSet(current, set);
|
||||
}
|
||||
assertSize(3, set);
|
||||
}
|
||||
|
||||
private static void testNoneOf() {
|
||||
EnumSet<SmallEnum> set = EnumSet.noneOf(SmallEnum.class);
|
||||
assertSize(0, set);
|
||||
}
|
||||
|
||||
private static void testIterators() {
|
||||
EnumSet<SmallEnum> set = EnumSet.allOf(SmallEnum.class);
|
||||
Iterator<SmallEnum> iterator = set.iterator();
|
||||
boolean exceptionCaught = false;
|
||||
try {
|
||||
iterator.remove();
|
||||
} catch (IllegalStateException e) {
|
||||
exceptionCaught = true;
|
||||
}
|
||||
if (!exceptionCaught) {
|
||||
throw new RuntimeException("Calling remove() before next() should throw IllegalStateException");
|
||||
}
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
iterator.remove();
|
||||
}
|
||||
assertSize(0, set);
|
||||
|
||||
exceptionCaught = false;
|
||||
try {
|
||||
iterator.next();
|
||||
} catch (NoSuchElementException e) {
|
||||
exceptionCaught = true;
|
||||
}
|
||||
if (!exceptionCaught) {
|
||||
throw new RuntimeException("Calling next() when hasNext() == false should throw NoSuchElementException");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertElementInSet(Enum<?> element, EnumSet<?> set) {
|
||||
if (!set.contains(element)) {
|
||||
throw new RuntimeException("expected " + element + " in the set!");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertSize(int expectedSize, EnumSet<?> set) {
|
||||
if (set.size() != expectedSize) {
|
||||
throw new RuntimeException("expected the set to be size=" + expectedSize + ", actual=" + set.size());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user