diff options
Diffstat (limited to 'third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java')
-rw-r--r-- | third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java new file mode 100644 index 0000000000..44bdbd6f61 --- /dev/null +++ b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java @@ -0,0 +1,150 @@ +package org.checkerframework.dataflow.util; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; + +/** + * A set that is more efficient than HashSet for 0 and 1 elements. + */ +final public class MostlySingleton<T> implements Set<T> { + private enum State { + EMPTY, SINGLETON, ANY + } + private State state = State.EMPTY; + private T value; + private HashSet<T> set; + + @Override + public int size() { + switch (state) { + case EMPTY: + return 0; + case SINGLETON: + return 1; + case ANY: + return set.size(); + default: + throw new AssertionError(); + } + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public boolean contains(Object o) { + switch (state) { + case EMPTY: + return false; + case SINGLETON: + return Objects.equals(o, value); + case ANY: + return set.contains(o); + default: + throw new AssertionError(); + } + } + + @Override + @SuppressWarnings("fallthrough") + public boolean add(T e) { + switch (state) { + case EMPTY: + state = State.SINGLETON; + value = e; + return true; + case SINGLETON: + state = State.ANY; + set = new HashSet<T>(); + set.add(value); + value = null; + // fallthrough + case ANY: + return set.add(e); + default: + throw new AssertionError(); + } + } + + @Override + public Iterator<T> iterator() { + switch (state) { + case EMPTY: + return Collections.emptyIterator(); + case SINGLETON: + return new Iterator<T>() { + private boolean hasNext = true; + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public T next() { + if (hasNext) { + hasNext = false; + return value; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + case ANY: + return set.iterator(); + default: + throw new AssertionError(); + } + } + + @Override + public Object[] toArray() { + throw new UnsupportedOperationException(); + } + + @Override + public <S> S[] toArray(S[] a) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends T> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } +} |