package the8472.utils; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; public class CowSet<E> implements Set<E> { static final AtomicReferenceFieldUpdater<CowSet,HashMap> u = AtomicReferenceFieldUpdater.newUpdater(CowSet.class, HashMap.class, "backingStore"); volatile HashMap<E,Boolean> backingStore = new HashMap<>(); <T> T update(Function<HashMap<E,Boolean>, ? extends T> c) { HashMap<E, Boolean> current; final HashMap<E, Boolean> newMap = new HashMap<>(); T ret; do { current = u.get(this); newMap.clear(); newMap.putAll(current); ret = c.apply(newMap); } while(!u.compareAndSet(this, current, newMap)); return ret; } @Override public int size() { return backingStore.size(); } @Override public boolean isEmpty() { return backingStore.isEmpty(); } @Override public boolean contains(Object o) { return backingStore.containsKey(o); } @Override public Iterator<E> iterator() { return Collections.unmodifiableCollection(backingStore.keySet()).iterator(); } @Override public Object[] toArray() { return backingStore.keySet().toArray(); } @Override public <T> T[] toArray(T[] a) { return backingStore.keySet().toArray(a); } @Override public boolean add(E e) { return update(m -> m.putIfAbsent(e, Boolean.TRUE) == null); } @Override public boolean remove(Object o) { return update(m -> m.keySet().remove(o)); } @Override public boolean containsAll(Collection<?> c) { throw new UnsupportedOperationException("not implemented"); } @Override public boolean addAll(Collection<? extends E> c) { throw new UnsupportedOperationException("not implemented"); } @Override public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException("not implemented"); } @Override public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException("not implemented"); } @Override public void clear() { backingStore = new HashMap<>(); } @Override public Stream<E> stream() { return backingStore.keySet().stream(); } @Override public boolean removeIf(Predicate<? super E> filter) { return update(m -> { return m.keySet().removeIf(filter); }); } public Set<E> snapshot() { return Collections.unmodifiableSet(backingStore.keySet()); } }