From ffc62e7351632a9c161224a24c23b9955687a61f Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 14 Feb 2020 16:23:51 +0100 Subject: [PATCH] [New] Added SynchronizedCollections for synchronizing MapOf* --- .../collections/SynchronizedCollections.java | 1007 +++++++++++++++++ 1 file changed, 1007 insertions(+) create mode 100644 li.strolch.utils/src/main/java/li/strolch/utils/collections/SynchronizedCollections.java diff --git a/li.strolch.utils/src/main/java/li/strolch/utils/collections/SynchronizedCollections.java b/li.strolch.utils/src/main/java/li/strolch/utils/collections/SynchronizedCollections.java new file mode 100644 index 000000000..712c838e9 --- /dev/null +++ b/li.strolch.utils/src/main/java/li/strolch/utils/collections/SynchronizedCollections.java @@ -0,0 +1,1007 @@ +package li.strolch.utils.collections; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.*; +import java.util.function.*; +import java.util.stream.Stream; + +class SynchronizedCollections { + + public MapOfLists synchronizedMapOfLists(MapOfLists mapOfLists) { + return new SynchronizedMapOfLists(mapOfLists); + } + + public MapOfSets synchronizedMapOfSets(MapOfSets mapOfSets) { + return new SynchronizedMapOfSets(mapOfSets); + } + + public MapOfMaps synchronizedMapOfMaps(MapOfMaps mapOfMaps) { + return new SynchronizedMapOfMaps(mapOfMaps); + } + + private static class SynchronizedMapOfLists extends MapOfLists { + private final MapOfLists m; + private final Object mutex; + + private transient Set keySet; + + SynchronizedMapOfLists(MapOfLists m) { + this.m = m; + this.mutex = new Object(); + } + + @Override + public Set keySet() { + synchronized (this.mutex) { + if (this.keySet == null) { + this.keySet = new SynchronizedSet<>(this.m.keySet(), this.mutex); + } + return this.keySet; + } + } + + @Override + public List values() { + synchronized (this.mutex) { + return this.m.values(); + } + } + + @Override + public List getList(T t) { + synchronized (this.mutex) { + return new SynchronizedList<>(this.m.getList(t), this.mutex); + } + } + + @Override + public boolean addElement(T t, U u) { + synchronized (this.mutex) { + return this.m.addElement(t, u); + } + } + + @Override + public boolean addList(T t, List u) { + synchronized (this.mutex) { + return this.m.addList(t, u); + } + } + + @Override + public boolean removeElement(T t, U u) { + synchronized (this.mutex) { + return this.m.removeElement(t, u); + } + } + + @Override + public List removeList(T t) { + synchronized (this.mutex) { + return this.m.removeList(t); + } + } + + @Override + public void clear() { + synchronized (this.mutex) { + this.m.clear(); + } + } + + @Override + public boolean containsList(T t) { + synchronized (this.mutex) { + return this.m.containsList(t); + } + } + + @Override + public boolean containsElement(T t, U u) { + synchronized (this.mutex) { + return this.m.containsElement(t, u); + } + } + + @Override + public int sizeKeys() { + synchronized (this.mutex) { + return this.m.sizeKeys(); + } + } + + @Override + public int size() { + synchronized (this.mutex) { + return this.m.size(); + } + } + + @Override + public int size(T t) { + synchronized (this.mutex) { + return this.m.size(t); + } + } + + @Override + public boolean isEmpty() { + synchronized (this.mutex) { + return this.m.isEmpty(); + } + } + + @Override + public MapOfLists addAll(MapOfLists other) { + synchronized (this.mutex) { + this.m.addAll(other); + } + return this; + } + + @Override + public List getListOrDefault(T key, List defaultValue) { + synchronized (this.mutex) { + return new SynchronizedList<>(this.m.getListOrDefault(key, defaultValue), this.mutex); + } + } + + @Override + public List computeIfAbsent(T key, Function> mappingFunction) { + synchronized (this.mutex) { + return new SynchronizedList<>(this.m.computeIfAbsent(key, mappingFunction), this.mutex); + } + } + + @Override + public void forEach(BiConsumer> action) { + synchronized (this.mutex) { + this.m.forEach(action); + } + } + } + + private static class SynchronizedMapOfMaps extends MapOfMaps { + private final MapOfMaps m; + private final Object mutex; + + private transient Set keySet; + + SynchronizedMapOfMaps(MapOfMaps m) { + this.m = m; + this.mutex = new Object(); + } + + @Override + public Set keySet() { + synchronized (this.mutex) { + if (this.keySet == null) { + this.keySet = new SynchronizedSet<>(this.m.keySet(), this.mutex); + } + return this.keySet; + } + } + + @Override + public List values() { + synchronized (mutex) { + return m.values(); + } + } + + @Override + public Map getMap(T t) { + synchronized (this.mutex) { + return new SynchronizedMap<>(this.m.getMap(t), this.mutex); + } + } + + @Override + public V getElement(T t, U u) { + synchronized (this.mutex) { + return this.m.getElement(t, u); + } + } + + @Override + public V addElement(T t, U u, V v) { + synchronized (this.mutex) { + return this.m.addElement(t, u, v); + } + } + + @Override + public List getAllElements() { + synchronized (this.mutex) { + return this.m.getAllElements(); + } + } + + @Override + public List getAllElements(T t) { + synchronized (this.mutex) { + return this.m.getAllElements(t); + } + } + + @Override + public void addMap(T t, Map u) { + synchronized (this.mutex) { + this.m.addMap(t, u); + } + } + + @Override + public V removeElement(T t, U u) { + synchronized (this.mutex) { + return this.m.removeElement(t, u); + } + } + + @Override + public Map removeMap(T t) { + synchronized (this.mutex) { + return this.m.removeMap(t); + } + } + + @Override + public void clear() { + synchronized (this.mutex) { + this.m.clear(); + } + } + + @Override + public boolean containsMap(T t) { + synchronized (this.mutex) { + return this.m.containsMap(t); + } + } + + @Override + public boolean containsElement(T t, U u) { + synchronized (this.mutex) { + return this.m.containsElement(t, u); + } + } + + @Override + public int sizeKeys() { + synchronized (this.mutex) { + return this.m.sizeKeys(); + } + } + + @Override + public int size() { + synchronized (this.mutex) { + return this.m.size(); + } + } + + @Override + public int size(T t) { + synchronized (this.mutex) { + return this.m.size(t); + } + } + + @Override + public boolean isEmpty() { + synchronized (this.mutex) { + return this.m.isEmpty(); + } + } + + @Override + public MapOfMaps putAll(MapOfMaps other) { + synchronized (this.mutex) { + this.m.putAll(other); + } + return this; + } + + @Override + public Map getMapOrDefault(T key, Map defaultValue) { + synchronized (this.mutex) { + return new SynchronizedMap<>(this.m.getMapOrDefault(key, defaultValue), this.mutex); + } + } + + @Override + public Map computeIfAbsent(T key, Function> mappingFunction) { + synchronized (this.mutex) { + return new SynchronizedMap<>(this.m.computeIfAbsent(key, mappingFunction), this.mutex); + } + } + + @Override + public void forEach(BiConsumer> action) { + synchronized (this.mutex) { + this.m.forEach(action); + } + } + } + + private static class SynchronizedMapOfSets extends MapOfSets { + + private final MapOfSets m; + private final Object mutex; + + private transient Set keySet; + + public SynchronizedMapOfSets(MapOfSets m) { + this.m = m; + this.mutex = new Object(); + } + + @Override + public Set keySet() { + synchronized (this.mutex) { + if (this.keySet == null) { + this.keySet = new SynchronizedSet<>(this.m.keySet(), this.mutex); + } + return this.keySet; + } + } + + @Override + public List values() { + synchronized (mutex) { + return this.m.values(); + } + } + + @Override + public Set getSet(T t) { + synchronized (this.mutex) { + return new SynchronizedSet<>(this.m.getSet(t), this.mutex); + } + } + + @Override + public boolean addElement(T t, U u) { + synchronized (this.mutex) { + return this.m.addElement(t, u); + } + } + + @Override + public boolean addSet(T t, Set u) { + synchronized (this.mutex) { + return this.m.addSet(t, u); + } + } + + @Override + public boolean removeElement(T t, U u) { + synchronized (this.mutex) { + return this.m.removeElement(t, u); + } + } + + @Override + public Set removeSet(T t) { + synchronized (this.mutex) { + return this.m.removeSet(t); + } + } + + @Override + public void clear() { + synchronized (this.mutex) { + this.m.clear(); + } + } + + @Override + public boolean containsSet(T t) { + synchronized (this.mutex) { + return this.m.containsSet(t); + } + } + + @Override + public boolean containsElement(T t, U u) { + synchronized (this.mutex) { + return this.m.containsElement(t, u); + } + } + + @Override + public int sizeKeys() { + synchronized (this.mutex) { + return this.m.sizeKeys(); + } + } + + @Override + public int size() { + synchronized (this.mutex) { + return this.m.size(); + } + } + + @Override + public int size(T t) { + synchronized (this.mutex) { + return this.m.size(t); + } + } + + @Override + public boolean isEmpty() { + synchronized (this.mutex) { + return this.m.isEmpty(); + } + } + + @Override + public MapOfSets addAll(MapOfSets other) { + synchronized (this.mutex) { + this.m.addAll(other); + } + return this; + } + + @Override + public Set getSetOrDefault(T key, Set defaultValue) { + synchronized (this.mutex) { + return new SynchronizedSet<>(this.m.getSetOrDefault(key, defaultValue), this.mutex); + } + } + + @Override + public Set computeIfAbsent(T key, Function> mappingFunction) { + synchronized (this.mutex) { + return new SynchronizedSet<>(this.m.computeIfAbsent(key, mappingFunction), this.mutex); + } + } + + @Override + public void forEach(BiConsumer> action) { + synchronized (this.mutex) { + this.m.forEach(action); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + synchronized (this.mutex) { + return this.m.equals(o); + } + } + + @Override + public int hashCode() { + synchronized (this.mutex) { + return this.m.hashCode(); + } + } + } + + private static class SynchronizedCollection implements Collection, Serializable { + private static final long serialVersionUID = 0L; + + final Collection c; + final Object mutex; + + SynchronizedCollection(Collection c, Object mutex) { + this.c = Objects.requireNonNull(c); + this.mutex = Objects.requireNonNull(mutex); + } + + @Override + public int size() { + synchronized (mutex) { + return c.size(); + } + } + + @Override + public boolean isEmpty() { + synchronized (mutex) { + return c.isEmpty(); + } + } + + @Override + public boolean contains(Object o) { + synchronized (mutex) { + return c.contains(o); + } + } + + @Override + public Object[] toArray() { + synchronized (mutex) { + return c.toArray(); + } + } + + @Override + public T[] toArray(T[] a) { + synchronized (mutex) { + return c.toArray(a); + } + } + + @Override + public Iterator iterator() { + return c.iterator(); + } + + @Override + public boolean add(E e) { + synchronized (mutex) { + return c.add(e); + } + } + + @Override + public boolean remove(Object o) { + synchronized (mutex) { + return c.remove(o); + } + } + + @Override + public boolean containsAll(Collection coll) { + synchronized (mutex) { + return c.containsAll(coll); + } + } + + @Override + public boolean addAll(Collection coll) { + synchronized (mutex) { + return c.addAll(coll); + } + } + + @Override + public boolean removeAll(Collection coll) { + synchronized (mutex) { + return c.removeAll(coll); + } + } + + @Override + public boolean retainAll(Collection coll) { + synchronized (mutex) { + return c.retainAll(coll); + } + } + + @Override + public void clear() { + synchronized (mutex) { + c.clear(); + } + } + + @Override + public String toString() { + synchronized (mutex) { + return c.toString(); + } + } + + @Override + public void forEach(Consumer consumer) { + synchronized (mutex) { + c.forEach(consumer); + } + } + + @Override + public boolean removeIf(Predicate filter) { + synchronized (mutex) { + return c.removeIf(filter); + } + } + + @Override + public Spliterator spliterator() { + return c.spliterator(); + } + + @Override + public Stream stream() { + return c.stream(); + } + + @Override + public Stream parallelStream() { + return c.parallelStream(); + } + + private void writeObject(ObjectOutputStream s) throws IOException { + synchronized (mutex) { + s.defaultWriteObject(); + } + } + } + + private static class SynchronizedList extends SynchronizedCollection implements List { + + final List list; + + SynchronizedList(List list, Object mutex) { + super(list, mutex); + this.list = list; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + synchronized (mutex) { + return list.equals(o); + } + } + + @Override + public int hashCode() { + synchronized (mutex) { + return list.hashCode(); + } + } + + @Override + public E get(int index) { + synchronized (mutex) { + return list.get(index); + } + } + + @Override + public E set(int index, E element) { + synchronized (mutex) { + return list.set(index, element); + } + } + + @Override + public void add(int index, E element) { + synchronized (mutex) { + list.add(index, element); + } + } + + @Override + public E remove(int index) { + synchronized (mutex) { + return list.remove(index); + } + } + + @Override + public int indexOf(Object o) { + synchronized (mutex) { + return list.indexOf(o); + } + } + + @Override + public int lastIndexOf(Object o) { + synchronized (mutex) { + return list.lastIndexOf(o); + } + } + + @Override + public boolean addAll(int index, Collection c) { + synchronized (mutex) { + return list.addAll(index, c); + } + } + + @Override + public ListIterator listIterator() { + return list.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + synchronized (mutex) { + return new SynchronizedList<>(list.subList(fromIndex, toIndex), mutex); + } + } + + @Override + public void replaceAll(UnaryOperator operator) { + synchronized (mutex) { + list.replaceAll(operator); + } + } + + @Override + public void sort(Comparator c) { + synchronized (mutex) { + list.sort(c); + } + } + } + + private static class SynchronizedSet extends SynchronizedCollection implements Set { + + SynchronizedSet(Set s, Object mutex) { + super(s, mutex); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + synchronized (mutex) { + return c.equals(o); + } + } + + @Override + public int hashCode() { + synchronized (mutex) { + return c.hashCode(); + } + } + } + + private static class SynchronizedSortedSet extends SynchronizedSet implements SortedSet { + + private final SortedSet ss; + + SynchronizedSortedSet(SortedSet s, Object mutex) { + super(s, mutex); + ss = s; + } + + @Override + public Comparator comparator() { + synchronized (mutex) { + return ss.comparator(); + } + } + + @Override + public SortedSet subSet(E fromElement, E toElement) { + synchronized (mutex) { + return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), mutex); + } + } + + @Override + public SortedSet headSet(E toElement) { + synchronized (mutex) { + return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex); + } + } + + @Override + public SortedSet tailSet(E fromElement) { + synchronized (mutex) { + return new SynchronizedSortedSet<>(ss.tailSet(fromElement), mutex); + } + } + + @Override + public E first() { + synchronized (mutex) { + return ss.first(); + } + } + + @Override + public E last() { + synchronized (mutex) { + return ss.last(); + } + } + } + + private static class SynchronizedMap implements Map, Serializable { + + private final Map m; + final Object mutex; + + SynchronizedMap(Map m, Object mutex) { + this.m = m; + this.mutex = mutex; + } + + public int size() { + synchronized (mutex) { + return m.size(); + } + } + + public boolean isEmpty() { + synchronized (mutex) { + return m.isEmpty(); + } + } + + public boolean containsKey(Object key) { + synchronized (mutex) { + return m.containsKey(key); + } + } + + public boolean containsValue(Object value) { + synchronized (mutex) { + return m.containsValue(value); + } + } + + public V get(Object key) { + synchronized (mutex) { + return m.get(key); + } + } + + public V put(K key, V value) { + synchronized (mutex) { + return m.put(key, value); + } + } + + public V remove(Object key) { + synchronized (mutex) { + return m.remove(key); + } + } + + public void putAll(Map map) { + synchronized (mutex) { + m.putAll(map); + } + } + + public void clear() { + synchronized (mutex) { + m.clear(); + } + } + + private transient Set keySet; + private transient Set> entrySet; + private transient Collection values; + + public Set keySet() { + synchronized (mutex) { + if (keySet == null) + keySet = new SynchronizedSet<>(m.keySet(), mutex); + return keySet; + } + } + + public Set> entrySet() { + synchronized (mutex) { + if (entrySet == null) + entrySet = new SynchronizedSet<>(m.entrySet(), mutex); + return entrySet; + } + } + + public Collection values() { + synchronized (mutex) { + if (values == null) + values = new SynchronizedCollection<>(m.values(), mutex); + return values; + } + } + + public boolean equals(Object o) { + if (this == o) + return true; + synchronized (mutex) { + return m.equals(o); + } + } + + public int hashCode() { + synchronized (mutex) { + return m.hashCode(); + } + } + + public String toString() { + synchronized (mutex) { + return m.toString(); + } + } + + @Override + public V getOrDefault(Object k, V defaultValue) { + synchronized (mutex) { + return m.getOrDefault(k, defaultValue); + } + } + + @Override + public void forEach(BiConsumer action) { + synchronized (mutex) { + m.forEach(action); + } + } + + @Override + public void replaceAll(BiFunction function) { + synchronized (mutex) { + m.replaceAll(function); + } + } + + @Override + public V putIfAbsent(K key, V value) { + synchronized (mutex) { + return m.putIfAbsent(key, value); + } + } + + @Override + public boolean remove(Object key, Object value) { + synchronized (mutex) { + return m.remove(key, value); + } + } + + @Override + public boolean replace(K key, V oldValue, V newValue) { + synchronized (mutex) { + return m.replace(key, oldValue, newValue); + } + } + + @Override + public V replace(K key, V value) { + synchronized (mutex) { + return m.replace(key, value); + } + } + + @Override + public V computeIfAbsent(K key, Function mappingFunction) { + synchronized (mutex) { + return m.computeIfAbsent(key, mappingFunction); + } + } + + @Override + public V computeIfPresent(K key, BiFunction remappingFunction) { + synchronized (mutex) { + return m.computeIfPresent(key, remappingFunction); + } + } + + @Override + public V compute(K key, BiFunction remappingFunction) { + synchronized (mutex) { + return m.compute(key, remappingFunction); + } + } + + @Override + public V merge(K key, V value, BiFunction remappingFunction) { + synchronized (mutex) { + return m.merge(key, value, remappingFunction); + } + } + + private void writeObject(ObjectOutputStream s) throws IOException { + synchronized (mutex) { + s.defaultWriteObject(); + } + } + } +}