diff options
Diffstat (limited to 'src/main/java/org/elasticsearch/common/collect/IdentityHashSet.java')
-rw-r--r-- | src/main/java/org/elasticsearch/common/collect/IdentityHashSet.java | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/main/java/org/elasticsearch/common/collect/IdentityHashSet.java b/src/main/java/org/elasticsearch/common/collect/IdentityHashSet.java new file mode 100644 index 0000000..20110eb --- /dev/null +++ b/src/main/java/org/elasticsearch/common/collect/IdentityHashSet.java @@ -0,0 +1,193 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common.collect; + +import java.util.*; + +/** + * + */ +public class IdentityHashSet<E> + extends AbstractSet<E> + implements Set<E>, Cloneable, java.io.Serializable { + + static final long serialVersionUID = -5024744406713321677L; + + private transient IdentityHashMap<E, Object> map; + + // Dummy value to associate with an Object in the backing Map + private static final Object PRESENT = new Object(); + + public IdentityHashSet() { + map = new IdentityHashMap<E, Object>(); + } + + public IdentityHashSet(Collection<? extends E> c) { + map = new IdentityHashMap<E, Object>(Math.max((int) (c.size() / .75f) + 1, 16)); + addAll(c); + } + + public IdentityHashSet(int expectedSize) { + map = new IdentityHashMap<E, Object>(expectedSize); + } + + /** + * 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<E> 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 <tt>true</tt> if this set contains no elements. + * + * @return <tt>true</tt> if this set contains no elements + */ + public boolean isEmpty() { + return map.isEmpty(); + } + + /** + * Returns <tt>true</tt> if this set contains the specified element. + * More formally, returns <tt>true</tt> if and only if this set + * contains an element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>. + * + * @param o element whose presence in this set is to be tested + * @return <tt>true</tt> 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 <tt>e</tt> to this set if + * this set contains no element <tt>e2</tt> such that + * <tt>(e==null ? e2==null : e.equals(e2))</tt>. + * If this set already contains the element, the call leaves the set + * unchanged and returns <tt>false</tt>. + * + * @param e element to be added to this set + * @return <tt>true</tt> 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 <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>, + * if this set contains such an element. Returns <tt>true</tt> 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 <tt>true</tt> 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 <tt>HashSet</tt> instance: the elements + * themselves are not cloned. + * + * @return a shallow copy of this set + */ + public Object clone() { + try { + IdentityHashSet<E> newSet = (IdentityHashSet<E>) super.clone(); + newSet.map = (IdentityHashMap<E, Object>) map.clone(); + return newSet; + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + } + + /** + * Index the state of this <tt>HashSet</tt> instance to a stream (that is, + * serialize it). + * + * @serialData The capacity of the backing <tt>HashMap</tt> 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 <tt>HashSet</tt> instance from a stream (that is, + * deserialize it). + */ + 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(); + + map = new IdentityHashMap<E, Object>(size); + + // Read in all elements in the proper order. + for (int i = 0; i < size; i++) { + E e = (E) s.readObject(); + map.put(e, PRESENT); + } + } +} + |