X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Futil%2FIdentityHashSet.java;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Futil%2FIdentityHashSet.java;h=333c6d1700e4a34e6dee8310dc7758ba22aa4a22;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/util/IdentityHashSet.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/util/IdentityHashSet.java new file mode 100644 index 000000000..333c6d170 --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/util/IdentityHashSet.java @@ -0,0 +1,200 @@ +package org.simantics.databoard.util; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Set; + +public class IdentityHashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable +{ +static final long serialVersionUID = -5024744406713321676L; + +private transient IdentityHashMap map; + +// Dummy value to associate with an Object in the backing Map +private static final Object PRESENT = new Object(); + +/** + * Constructs a new, empty set; the backing HashMap instance has + * default initial capacity (16) and load factor (0.75). + */ +public IdentityHashSet() { +map = new IdentityHashMap(); +} + +/** + * Constructs a new set containing the elements in the specified + * collection. The HashMap is created with default load factor + * (0.75) and an initial capacity sufficient to contain the elements in + * the specified collection. + * + * @param c the collection whose elements are to be placed into this set + * @throws NullPointerException if the specified collection is null + */ +public IdentityHashSet(Collection c) { +map = new IdentityHashMap(Math.max((int) (c.size()/.75f) + 1, 16)); +addAll(c); +} + + +/** + * Constructs a new, empty set; the backing HashMap instance has + * the specified initial capacity and default load factor (0.75). + * + * @param initialCapacity the initial capacity of the hash table + * @throws IllegalArgumentException if the initial capacity is less + * than zero + */ +public IdentityHashSet(int initialCapacity) { +map = new IdentityHashMap(initialCapacity); +} + +/** + * Returns an iterator over the elements in this set. The elements + * are returned in no particular order. + * + * @return an Iterator over the elements in this set + * @see ConcurrentModificationException + */ +public Iterator iterator() { +return map.keySet().iterator(); +} + +/** + * Returns the number of elements in this set (its cardinality). + * + * @return the number of elements in this set (its cardinality) + */ +public int size() { +return map.size(); +} + +/** + * Returns true if this set contains no elements. + * + * @return true if this set contains no elements + */ +public boolean isEmpty() { +return map.isEmpty(); +} + +/** + * Returns true if this set contains the specified element. + * More formally, returns true if and only if this set + * contains an element e such that + * (o==null ? e==null : o.equals(e)). + * + * @param o element whose presence in this set is to be tested + * @return true if this set contains the specified element + */ +public boolean contains(Object o) { +return map.containsKey(o); +} + +/** + * Adds the specified element to this set if it is not already present. + * More formally, adds the specified element e to this set if + * this set contains no element e2 such that + * (e==null ? e2==null : e.equals(e2)). + * If this set already contains the element, the call leaves the set + * unchanged and returns false. + * + * @param e element to be added to this set + * @return true if this set did not already contain the specified + * element + */ +public boolean add(E e) { +return map.put(e, PRESENT)==null; +} + +/** + * Removes the specified element from this set if it is present. + * More formally, removes an element e such that + * (o==null ? e==null : o.equals(e)), + * if this set contains such an element. Returns true if + * this set contained the element (or equivalently, if this set + * changed as a result of the call). (This set will not contain the + * element once the call returns.) + * + * @param o object to be removed from this set, if present + * @return true if the set contained the specified element + */ +public boolean remove(Object o) { +return map.remove(o)==PRESENT; +} + +/** + * Removes all of the elements from this set. + * The set will be empty after this call returns. + */ +public void clear() { +map.clear(); +} + +/** + * Returns a shallow copy of this HashSet instance: the elements + * themselves are not cloned. + * + * @return a shallow copy of this set + */ +@SuppressWarnings("unchecked") +public Object clone() { +try { + IdentityHashSet newSet = (IdentityHashSet) super.clone(); + newSet.map = (IdentityHashMap) map.clone(); + return newSet; +} catch (CloneNotSupportedException e) { + throw new InternalError(); +} +} + +/** + * Save the state of this HashSet instance to a stream (that is, + * serialize it). + * + * @serialData The capacity of the backing HashMap instance + * (int), and its load factor (float) are emitted, followed by + * the size of the set (the number of elements it contains) + * (int), followed by all of its elements (each an Object) in + * no particular order. + */ +private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { +// Write out any hidden serialization magic +s.defaultWriteObject(); + + // Write out size + s.writeInt(map.size()); + +// Write out all elements in the proper order. +for (Iterator i=map.keySet().iterator(); i.hasNext(); ) + s.writeObject(i.next()); +} + +/** + * Reconstitute the HashSet instance from a stream (that is, + * deserialize it). + */ +@SuppressWarnings("unchecked") +private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { +// Read in any hidden serialization magic +s.defaultReadObject(); + +// Read in size + int size = s.readInt(); + + // Read in HashMap capacity and load factor and create backing HashMap + map = new IdentityHashMap(size); + + +// Read in all elements in the proper order. +for (int i=0; i