Skip to content

Commit c7c824f

Browse files
committed
Use primitive bit field for TypeMatcher instead of elaborate data structure. (#207)
Inspired by pull request #223 (@dr0i).
1 parent 3103856 commit c7c824f

File tree

1 file changed

+20
-5
lines changed
  • metafix/src/main/java/org/metafacture/metafix

1 file changed

+20
-5
lines changed

metafix/src/main/java/org/metafacture/metafix/Value.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
import org.metafacture.commons.tries.WildcardTrie;
2121

2222
import java.util.ArrayList;
23+
import java.util.Arrays;
2324
import java.util.Collection;
2425
import java.util.ConcurrentModificationException;
25-
import java.util.EnumSet;
2626
import java.util.HashMap;
2727
import java.util.HashSet;
2828
import java.util.LinkedHashMap;
@@ -305,9 +305,10 @@ enum Type {
305305

306306
public static class TypeMatcher {
307307

308-
private final Set<Type> expected = EnumSet.noneOf(Type.class);
309308
private final Value value;
310309

310+
private byte expected; // NOTE: Covers at most 7 `Type`s.
311+
311312
private TypeMatcher(final Value value) {
312313
this.value = value;
313314
}
@@ -325,20 +326,26 @@ public TypeMatcher ifString(final Consumer<String> consumer) {
325326
}
326327

327328
public void orElse(final Consumer<Value> consumer) {
328-
if (!expected.contains(value.type)) {
329+
if (!expecting(value.type)) {
329330
consumer.accept(value);
330331
}
331332
}
332333

333334
public void orElseThrow() {
334335
orElse(v -> {
335-
final String types = expected.stream().map(Type::name).collect(Collectors.joining(" or "));
336+
final String types = Arrays.stream(Type.values()).filter(this::expecting)
337+
.map(Type::name).collect(Collectors.joining(" or "));
338+
336339
throw new IllegalStateException("Expected " + types + ", got " + value.type);
337340
});
338341
}
339342

340343
private <T> TypeMatcher match(final Type type, final Consumer<T> consumer, final T rawValue) {
341-
if (expected.add(type)) {
344+
final byte newExpected = (byte) (expected | bit(type));
345+
346+
if (expected != newExpected) {
347+
expected = newExpected;
348+
342349
if (value.isType(type)) {
343350
consumer.accept(rawValue);
344351
}
@@ -350,6 +357,14 @@ private <T> TypeMatcher match(final Type type, final Consumer<T> consumer, final
350357
}
351358
}
352359

360+
private boolean expecting(final Type type) {
361+
return (expected & bit(type)) != 0;
362+
}
363+
364+
private byte bit(final Type type) {
365+
return (byte) (1 << type.ordinal());
366+
}
367+
353368
}
354369

355370
private abstract static class AbstractValueType {

0 commit comments

Comments
 (0)