LANG-1147 EnumUtils *BitVector issue with more than 32 values Enum

This closes #97
This commit is contained in:
Sebb 2015-06-13 00:38:27 +01:00
parent 529964961f
commit 06b7cd3a31
3 changed files with 56 additions and 4 deletions

View File

@ -22,6 +22,7 @@
<body>
<release version="3.5" date="tba" description="tba">
<action issue="LANG-1147" type="fix" dev="sebb" due-to="Loic Guibert">EnumUtils *BitVector issue with more than 32 values Enum</action>
<action issue="LANG-1059" type="fix" dev="sebb" due-to="Colin Casey">Capitalize javadoc is incorrect</action>
<action issue="LANG-1137" type="add" dev="britter" due-to="Matthew Aguirre">Add check for duplicate event listener in EventListenerSupport</action>
<action issue="LANG-1133" type="bug" dev="chas" due-to="Pascal Schumacher">FastDateParser_TimeZoneStrategyTest#testTimeZoneStrategyPattern fails on Windows with German Locale</action>

View File

@ -144,7 +144,7 @@ public static <E extends Enum<E>> long generateBitVector(final Class<E> enumClas
long total = 0;
for (final E constant : values) {
Validate.isTrue(constant != null, NULL_ELEMENTS_NOT_PERMITTED);
total |= 1 << constant.ordinal();
total |= 1L << constant.ordinal();
}
return total;
}
@ -175,7 +175,7 @@ public static <E extends Enum<E>> long[] generateBitVectors(final Class<E> enumC
}
final long[] result = new long[(enumClass.getEnumConstants().length - 1) / Long.SIZE + 1];
for (final E value : condensed) {
result[value.ordinal() / Long.SIZE] |= 1 << (value.ordinal() % Long.SIZE);
result[value.ordinal() / Long.SIZE] |= 1L << (value.ordinal() % Long.SIZE);
}
ArrayUtils.reverse(result);
return result;
@ -226,7 +226,7 @@ public static <E extends Enum<E>> long[] generateBitVectors(final Class<E> enumC
Collections.addAll(condensed, values);
final long[] result = new long[(enumClass.getEnumConstants().length - 1) / Long.SIZE + 1];
for (final E value : condensed) {
result[value.ordinal() / Long.SIZE] |= 1 << (value.ordinal() % Long.SIZE);
result[value.ordinal() / Long.SIZE] |= 1L << (value.ordinal() % Long.SIZE);
}
ArrayUtils.reverse(result);
return result;
@ -269,7 +269,7 @@ public static <E extends Enum<E>> EnumSet<E> processBitVectors(final Class<E> en
ArrayUtils.reverse(lvalues);
for (final E constant : enumClass.getEnumConstants()) {
final int block = constant.ordinal() / Long.SIZE;
if (block < lvalues.length && (lvalues[block] & 1 << (constant.ordinal() % Long.SIZE)) != 0) {
if (block < lvalues.length && (lvalues[block] & 1L << (constant.ordinal() % Long.SIZE)) != 0) {
results.add(constant);
}
}

View File

@ -215,6 +215,12 @@ public void test_generateBitVector() {
assertEquals(5L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED, Traffic.GREEN)));
assertEquals(6L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.AMBER, Traffic.GREEN)));
assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN)));
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertEquals((1L << 31), EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A31)));
assertEquals((1L << 32), EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A32)));
assertEquals((1L << 63), EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A63)));
assertEquals(Long.MIN_VALUE, EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A63)));
}
@Test
@ -227,6 +233,16 @@ public void test_generateBitVectors() {
assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.GREEN)), 5L);
assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.AMBER, Traffic.GREEN)), 6L);
assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN)), 7L);
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A31)), (1L << 31));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A32)), (1L << 32));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A63)), (1L << 63));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A63)), Long.MIN_VALUE);
// More than 64 values Enum
assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, EnumSet.of(TooMany.M2)), 1L, 0L);
assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, EnumSet.of(TooMany.L2, TooMany.M2)), 1L, (1L << 63));
}
@Test
@ -241,6 +257,12 @@ public void test_generateBitVectorFromArray() {
assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN));
//gracefully handles duplicates:
assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN));
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertEquals((1L << 31), EnumUtils.generateBitVector(Enum64.class, Enum64.A31));
assertEquals((1L << 32), EnumUtils.generateBitVector(Enum64.class, Enum64.A32));
assertEquals((1L << 63), EnumUtils.generateBitVector(Enum64.class, Enum64.A63));
assertEquals(Long.MIN_VALUE, EnumUtils.generateBitVector(Enum64.class, Enum64.A63));
}
@Test
@ -255,6 +277,17 @@ public void test_generateBitVectorsFromArray() {
assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN), 7L);
//gracefully handles duplicates:
assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN), 7L);
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A31), (1L << 31));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A32), (1L << 32));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A63), (1L << 63));
assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A63), Long.MIN_VALUE);
// More than 64 values Enum
assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, TooMany.M2), 1L, 0L);
assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, TooMany.L2, TooMany.M2), 1L, (1L << 63));
}
private void assertArrayEquals(final long[] actual, final long... expected) {
@ -283,6 +316,12 @@ public void test_processBitVector() {
assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 5L));
assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 6L));
assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 7L));
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertEquals(EnumSet.of(Enum64.A31), EnumUtils.processBitVector(Enum64.class, (1L << 31)));
assertEquals(EnumSet.of(Enum64.A32), EnumUtils.processBitVector(Enum64.class, (1L << 32)));
assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVector(Enum64.class, (1L << 63)));
assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVector(Enum64.class, Long.MIN_VALUE));
}
@Test
@ -314,6 +353,12 @@ public void test_processBitVectors() {
assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 5L));
assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 6L));
assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 7L));
// 64 values Enum (to test whether no int<->long jdk convertion issue exists)
assertEquals(EnumSet.of(Enum64.A31), EnumUtils.processBitVectors(Enum64.class, (1L << 31)));
assertEquals(EnumSet.of(Enum64.A32), EnumUtils.processBitVectors(Enum64.class, (1L << 32)));
assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVectors(Enum64.class, (1L << 63)));
assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVectors(Enum64.class, Long.MIN_VALUE));
}
@Test(expected=IllegalArgumentException.class)
@ -369,6 +414,12 @@ enum Traffic {
RED, AMBER, GREEN
}
enum Enum64 {
A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15,
A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31,
A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, A46, A47,
A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60, A61, A62, A63;
}
enum TooMany {
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,