/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.openjpa.lib.util.concurrent;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Set;

import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength;
import org.apache.openjpa.lib.util.ReferenceMap;
import org.apache.openjpa.lib.util.SizedMap;

/**
 * This class implements a HashMap which has limited synchronization
 * and reference keys or values(but not both). In particular mutators are
 * generally synchronized while accessors are generally not. Additionally the
 * Iterators returned by this class are not "fail-fast", but instead try to
 * continue to iterate over the data structure after changes have been
 * made. Finally purging of the reference queue is only done inside mutators.
 * Null keys are not supported if keys use references. Null values are not
 * supported if values use references.
 * This class is based heavily on the WeakHashMap class in the Java
 * collections package.
 */
public class ConcurrentReferenceHashMap extends AbstractMap
    implements ConcurrentMap, ReferenceMap, SizedMap, Cloneable {

    /**
     * Cache of random numbers used in "random" methods, since generating them
     * is expensive. We hope each map changes enough between cycling through
     * this list that the overall effect is random enough.
     */
    static final double[] RANDOMS = new double[1000];

    static {
        Random random = new Random();
        for (int i = 0; i < RANDOMS.length; i++)
            RANDOMS[i] = random.nextDouble();
    }

    /**
     * The hash table data.
     */
    private transient Entry[] table;

    /**
     * The total number of entries in the hash table.
     */
    private transient int count;

    /**
     * Rehashes the table when count exceeds this threshold.
     */
    private int threshold;

    /**
     * The load factor for the HashMap.
     */
    private float loadFactor;

    /**
     * The key reference type.
     */
    private ReferenceStrength keyType;

    /**
     * The value reference type.
     */
    private ReferenceStrength valueType;

    /**
     * Reference queue for cleared Entries
     */
    private final ReferenceQueue queue = new ReferenceQueue();

    /**
     * Spread "random" removes and iteration.
     */
    private int randomEntry = 0;

    /**
     * Maximum entries.
     */
    private int maxSize = Integer.MAX_VALUE;

    /**
     * Compare two objects. These might be keys, values, or Entry instances.
     * This implementation uses a normal null-safe object equality algorithm.
     *
     * @since 1.0.0
     */
    protected boolean eq(Object x, Object y) {
        return x == y || (x != null && x.equals(y));
    }

    /**
     * Obtain the hashcode of an object. The object might be a key, a value,
     * or an Entry. This implementation just delegates to
     * {@link Object#hashCode}
     *
     * @since 1.0.0
     */
    protected int hc(Object o) {
        return o == null ? 0 : o.hashCode();
    }

    /**
     * Constructs a new, empty HashMap with the specified initial
     * capacity and the specified load factor.
     *
     * @param keyType the reference type of map keys
     * @param valueType the reference type of map values
     * @param initialCapacity the initial capacity of the HashMap.
     * @param loadFactor a number between 0.0 and 1.0.
     * @throws IllegalArgumentException if neither keys nor values use hard
     * references, if the initial capacity is less than or equal to zero, or if
     * the load factor is less than or equal to zero
     */
    public ConcurrentReferenceHashMap(ReferenceStrength keyType, ReferenceStrength valueType,
        int initialCapacity, float loadFactor) {
        if (initialCapacity < 0) {
            throw new IllegalArgumentException("Illegal Initial Capacity: " +
                initialCapacity);
        }
        if ((loadFactor > 1) || (loadFactor <= 0)) {
            throw new IllegalArgumentException("Illegal Load factor: " +
                loadFactor);
        }
        if (keyType != ReferenceStrength.HARD && valueType != ReferenceStrength.HARD) {
            throw new IllegalArgumentException("Either keys or values must " +
                "use hard references.");
        }
        this.keyType = keyType;
        this.valueType = valueType;
        this.loadFactor = loadFactor;
        table = new Entry[initialCapacity];
        threshold = (int) (initialCapacity * loadFactor);
    }

    /**
     * Constructs a new, empty HashMap with the specified initial capacity
     * and default load factor.
     *
     * @param keyType the reference type of map keys
     * @param valueType the reference type of map values
     * @param initialCapacity the initial capacity of the HashMap.
     */
    public ConcurrentReferenceHashMap(ReferenceStrength keyType, ReferenceStrength valueType,
        int initialCapacity) {
        this(keyType, valueType, initialCapacity, 0.75f);
    }

    /**
     * Constructs a new, empty HashMap with a default capacity and load factor.
     *
     * @param keyType the reference type of map keys
     * @param valueType the reference type of map values
     */
    public ConcurrentReferenceHashMap(ReferenceStrength keyType, ReferenceStrength valueType) {
        this(keyType, valueType, 11, 0.75f);
    }

    /**
     * Constructs a new HashMap with the same mappings as the given
     * Map. The HashMap is created with a capacity of thrice the number
     * of entries in the given Map or 11 (whichever is greater), and a
     * default load factor.
     *
     * @param keyType the reference type of map keys
     * @param valueType the reference type of map values
     */
    public ConcurrentReferenceHashMap(ReferenceStrength keyType, ReferenceStrength valueType, Map t) {
        this(keyType, valueType, Math.max(3 * t.size(), 11), 0.75f);
        putAll(t);
    }

    @Override
    public int getMaxSize() {
        return maxSize;
    }

    @Override
    public void setMaxSize(int maxSize) {
        this.maxSize = (maxSize < 0) ? Integer.MAX_VALUE : maxSize;
        if (this.maxSize != Integer.MAX_VALUE)
            removeOverflow(this.maxSize);
    }

    @Override
    public boolean isFull() {
        return maxSize != Integer.MAX_VALUE && size() >= maxSize;
    }

    @Override
    public void overflowRemoved(Object key, Object value) {
    }

    /**
     * Returns the number of key-value mappings in this Map. This
     * result is a snapshot, and may not reflect unprocessed entries
     * that will be removed before next attempted access because they
     * are no longer referenced.
     */
    @Override
    public int size() {
        return count;
    }

    /**
     * Returns true if this Map contains no key-value mappings. This
     * result is a snapshot, and may not reflect unprocessed entries
     * that will be removed before next attempted access because they
     * are no longer referenced.
     */
    @Override
    public boolean isEmpty() {
        return count == 0;
    }

    /**
     * Returns true if this HashMap maps one or more keys to the specified
     * value.
     *
     * @param value value whose presence in this Map is to be tested.
     */
    @Override
    public boolean containsValue(Object value) {
        Entry[] tab = table;

        if (value == null) {
            if (valueType != ReferenceStrength.HARD)
                return false;
            for (int i = tab.length; i-- > 0;)
                for (Entry e = tab[i]; e != null; e = e.getNext())
                    if (e.getValue() == null)
                        return true;
        } else {
            for (int i = tab.length; i-- > 0;)
                for (Entry e = tab[i]; e != null; e = e.getNext())
                    if (eq(value, e.getValue()))
                        return true;
        }
        return false;
    }

    /**
     * Returns true if this HashMap contains a mapping for the specified key.
     *
     * @param key key whose presence in this Map is to be tested.
     */
    @Override
    public boolean containsKey(Object key) {
        if (key == null && keyType != ReferenceStrength.HARD)
            return false;

        Entry[] tab = table;
        int hash = hc(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry e = tab[index]; e != null; e = e.getNext())
            if (e.getHash() == hash && eq(key, e.getKey()))
                return true;
        return false;
    }

    /**
     * Returns the value to which this HashMap maps the specified key.
     * Returns null if the HashMap contains no mapping for this key.
     *
     * @param key key whose associated value is to be returned.
     */
    @Override
    public Object get(Object key) {
        if (key == null && keyType != ReferenceStrength.HARD)
            return null;

        Entry[] tab = table;
        int hash = hc(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry e = tab[index]; e != null; e = e.getNext())
            if ((e.getHash() == hash) && eq(key, e.getKey()))
                return e.getValue();

        return null;
    }

    /**
     * Rehashes the contents of the HashMap into a HashMap with a
     * larger capacity. This method is called automatically when the
     * number of keys in the HashMap exceeds this HashMap's capacity
     * and load factor.
     */
    private void rehash() {
        int oldCapacity = table.length;
        Entry oldMap[] = table;

        int newCapacity = oldCapacity * 2 + 1;
        Entry newMap[] = new Entry[newCapacity];

        for (int i = oldCapacity; i-- > 0;) {
            for (Entry old = oldMap[i]; old != null;) {
                if ((keyType != ReferenceStrength.HARD && old.getKey() == null)
                    || valueType != ReferenceStrength.HARD && old.getValue() == null) {
                    Entry e = old;
                    old = old.getNext();
                    e.setNext(null);
                    count--;
                } else {
                    Entry e = (Entry) old.clone(queue);
                    old = old.getNext();

                    int index = (e.getHash() & 0x7FFFFFFF) % newCapacity;
                    e.setNext(newMap[index]);
                    newMap[index] = e;
                }
            }
        }

        threshold = (int) (newCapacity * loadFactor);
        table = newMap;
    }

    /**
     * Associates the specified value with the specified key in this HashMap.
     * If the HashMap previously contained a mapping for this key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated.
     * @param value value to be associated with the specified key.
     * @return previous value associated with specified key, or null if there
     * was no mapping for key. A null return can also indicate that
     * the HashMap previously associated null with the specified key.
     */
    @Override
    public Object put(Object key, Object value) {
        if ((key == null && keyType != ReferenceStrength.HARD)
            || (value == null && valueType != ReferenceStrength.HARD))
            throw new IllegalArgumentException("Null references not supported");

        int hash = hc(key);
        synchronized (this) {
            expungeStaleEntries();

            Entry[] tab = table;
            int index = 0;

            index = (hash & 0x7FFFFFFF) % tab.length;
            for (Entry e = tab[index], prev = null; e != null; prev = e,
                e = e.getNext()) {
                if ((e.getHash() == hash) && eq(key, e.getKey())) {
                    Object old = e.getValue();
                    if (valueType == ReferenceStrength.HARD)
                        e.setValue(value);
                    else {
                        e = newEntry(hash, e.getKey(), value, e.getNext());
                        if (prev == null)
                            tab[index] = e;
                        else
                            prev.setNext(e);
                    }
                    return old;
                }
            }

            if (count >= threshold) {
                // Rehash the table if the threshold is exceeded
                rehash();

                tab = table;
                index = (hash & 0x7FFFFFFF) % tab.length;
            }

            if (maxSize != Integer.MAX_VALUE)
                removeOverflow(maxSize - 1);
            tab[index] = newEntry(hash, key, value, tab[index]);
            count++;
        }
        return null;
    }

    /**
     * Creates a new entry.
     */
    private Entry newEntry(int hash, Object key, Object value, Entry next) {
        ReferenceStrength refType = (keyType != ReferenceStrength.HARD) ? keyType : valueType;
        switch (refType) {
            case WEAK:
                return new WeakEntry(hash, key, value, refType == keyType, next,
                    queue);
            case SOFT:
                return new SoftEntry(hash, key, value, refType == keyType, next,
                    queue);
            default:
                return new HardEntry(hash, key, value, next);
        }
    }

    /**
     * Remove any entries equal to or over the max size.
     */
    private void removeOverflow(int maxSize) {
        while (count > maxSize) {
            Map.Entry entry = removeRandom();
            if (entry == null)
                break;
            overflowRemoved(entry.getKey(), entry.getValue());
        }
    }

    /**
     * Removes the mapping for this key from this HashMap if present.
     *
     * @param key key whose mapping is to be removed from the Map.
     * @return previous value associated with specified key, or null if there
     * was no mapping for key. A null return can also indicate that
     * the HashMap previously associated null with the specified key.
     */
    @Override
    public Object remove(Object key) {
        if (key == null && keyType != ReferenceStrength.HARD)
            return null;

        int hash = hc(key);
        synchronized (this) {
            expungeStaleEntries();

            Entry[] tab = table;

            int index = (hash & 0x7FFFFFFF) % tab.length;
            for (Entry e = tab[index], prev = null; e != null;
                prev = e, e = e.getNext()) {
                if ((e.getHash() == hash) && eq(key, e.getKey())) {
                    if (prev != null)
                        prev.setNext(e.getNext());
                        // otherwise put the bucket after us
                    else
                        tab[index] = e.getNext();

                    count--;
                    return e.getValue();
                }
            }
        }
        return null;
    }

    @Override
    public void removeExpired() {
        synchronized (this) {
            expungeStaleEntries();
        }
    }

    @Override
    public void keyExpired(Object value) {
    }

    @Override
    public void valueExpired(Object key) {
    }

    /**
     * Return an arbitrary entry index.
     */
    private int randomEntryIndex() {
        if (randomEntry == RANDOMS.length)
            randomEntry = 0;
        return (int) (RANDOMS[randomEntry++] * table.length);
    }

    @Override
    public Map.Entry removeRandom() {
        synchronized (this) {
            expungeStaleEntries();
            if (count == 0)
                return null;

            int random = randomEntryIndex();
            int index = findEntry(random, random % 2 == 0, false);
            if (index == -1)
                return null;
            Entry rem = table[index];
            table[index] = rem.getNext();
            count--;
            return rem;
        }
    }

    /**
     * Find the index of the entry nearest the given index, starting in the
     * given direction.
     */
    private int findEntry(int start, boolean forward, boolean searchedOther) {
        if (forward) {
            for (int i = start; i < table.length; i++)
                if (table[i] != null)
                    return i;
            return (searchedOther || start == 0) ? -1
                : findEntry(start - 1, false, true);
        } else {
            for (int i = start; i >= 0; i--)
                if (table[i] != null)
                    return i;
            return (searchedOther || start == table.length - 1) ? -1
                : findEntry(start + 1, true, true);
        }
    }

    @Override
    public Iterator randomEntryIterator() {
        // pass index so calculated before iterator refs table, in case table
        // gets replace with a larger one
        return new HashIterator(ENTRIES, randomEntryIndex());
    }

    /**
     * Copies all of the mappings from the specified Map to this HashMap
     * These mappings will replace any mappings that this HashMap had for any
     * of the keys currently in the specified Map.
     *
     * @param t Mappings to be stored in this Map.
     */
    @Override
    public void putAll(Map t) {
        Iterator i = t.entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry e = (Map.Entry) i.next();
            put(e.getKey(), e.getValue());
        }
    }

    /**
     * Removes all mappings from this HashMap.
     */
    @Override
    public synchronized void clear() {
        // clear out ref queue. We don't need to expunge entries
        // since table is getting cleared.
        while (queue.poll() != null)
            ;
        table = new Entry[table.length];
        count = 0;
        // Allocation of array may have caused GC, which may have caused
        // additional entries to go stale.    Removing these entries from
        // the reference queue will make them eligible for reclamation.
        while (queue.poll() != null)
            ;
    }

    /**
     * Returns a shallow copy of this HashMap. The keys and values
     * themselves are not cloned.
     */
    @Override
    public synchronized Object clone() {
        try {
            expungeStaleEntries();

            ConcurrentReferenceHashMap t = (ConcurrentReferenceHashMap)
                super.clone();
            t.table = new Entry[table.length];
            for (int i = table.length; i-- > 0;) {
                Entry e = table[i];
                if (e != null) {
                    t.table[i] = (Entry) e.clone(t.queue);
                    e = e.getNext();
                    for (Entry k = t.table[i]; e != null; e = e.getNext()) {
                        k.setNext((Entry) e.clone(t.queue));
                        k = k.getNext();
                    }
                }
            }
            t.keySet = null;
            t.entrySet = null;
            t.values = null;
            return t;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError();
        }
    }

    // Views

    private transient Set keySet = null;
    private transient Set entrySet = null;
    private transient Collection values = null;

    /**
     * Returns a Set view of the keys contained in this HashMap. The Set is
     * backed by the HashMap, so changes to the HashMap are reflected in the
     * Set, and vice-versa. The Set supports element removal, which removes
     * the corresponding mapping from the HashMap, via the Iterator.remove,
     * Set.remove, removeAll retainAll, and clear operations. It does not
     * support the add or addAll operations.
     */
    @Override
    public Set keySet() {
        if (keySet == null) {
            keySet = new java.util.AbstractSet() {
                @Override
                public Iterator iterator() {
                    return new HashIterator(KEYS, table.length - 1);
                }

                @Override
                public int size() {
                    return count;
                }

                @Override
                public boolean contains(Object o) {
                    return containsKey(o);
                }

                @Override
                public boolean remove(Object o) {
                    return ConcurrentReferenceHashMap.this.remove(o) != null;
                }

                @Override
                public void clear() {
                    ConcurrentReferenceHashMap.this.clear();
                }
            };
        }
        return keySet;
    }

    /**
     * Returns a Collection view of the values contained in this HashMap.
     * The Collection is backed by the HashMap, so changes to the HashMap are
     * reflected in the Collection, and vice-versa. The Collection supports
     * element removal, which removes the corresponding mapping from the
     * HashMap, via the Iterator.remove, Collection.remove, removeAll,
     * retainAll and clear operations. It does not support the add or addAll
     * operations.
     */
    @Override
    public Collection values() {
        if (values == null) {
            values = new java.util.AbstractCollection() {
                @Override
                public Iterator iterator() {
                    return new HashIterator(VALUES, table.length - 1);
                }

                @Override
                public int size() {
                    return count;
                }

                @Override
                public boolean contains(Object o) {
                    return containsValue(o);
                }

                @Override
                public void clear() {
                    ConcurrentReferenceHashMap.this.clear();
                }
            };
        }
        return values;
    }

    /**
     * Returns a Collection view of the mappings contained in this HashMap.
     * Each element in the returned collection is a Map.Entry. The Collection
     * is backed by the HashMap, so changes to the HashMap are reflected in the
     * Collection, and vice-versa. The Collection supports element removal,
     * which removes the corresponding mapping from the HashMap, via the
     * Iterator.remove, Collection.remove, removeAll, retainAll and clear
     * operations. It does not support the add or addAll operations.
     *
     * @see Map.Entry
     */
    @Override
    public Set entrySet() {
        if (entrySet == null) {
            entrySet = new java.util.AbstractSet() {
                @Override
                public Iterator iterator() {
                    return new HashIterator(ENTRIES, table.length - 1);
                }

                @Override
                public boolean contains(Object o) {
                    if (!(o instanceof Map.Entry))
                        return false;
                    Map.Entry entry = (Map.Entry) o;
                    Object key = entry.getKey();
                    Entry[] tab = table;
                    int hash = hc(key);
                    int index = (hash & 0x7FFFFFFF) % tab.length;

                    for (Entry e = tab[index]; e != null; e = e.getNext())
                        if (e.getHash() == hash && eq(e, entry))
                            return true;
                    return false;
                }

                @Override
                public boolean remove(Object o) {
                    if (!(o instanceof Map.Entry))
                        return false;
                    Map.Entry entry = (Map.Entry) o;
                    Object key = entry.getKey();
                    synchronized (ConcurrentReferenceHashMap.this) {
                        Entry[] tab = table;
                        int hash = hc(key);
                        int index = (hash & 0x7FFFFFFF) % tab.length;

                        for (Entry e = tab[index], prev = null; e != null;
                            prev = e, e = e.getNext()) {
                            if (e.getHash() == hash && eq(e, entry)) {
                                if (prev != null)
                                    prev.setNext(e.getNext());
                                else
                                    tab[index] = e.getNext();

                                count--;
                                return true;
                            }
                        }
                        return false;
                    }
                }

                @Override
                public int size() {
                    return count;
                }

                @Override
                public void clear() {
                    ConcurrentReferenceHashMap.this.clear();
                }
            };
        }

        return entrySet;
    }

    /**
     * Expunge stale entries from the table.
     */
    private void expungeStaleEntries() {
        Object r;
        while ((r = queue.poll()) != null) {
            Entry entry = (Entry) r;
            int hash = entry.getHash();
            Entry[] tab = table;
            int index = (hash & 0x7FFFFFFF) % tab.length;

            for (Entry e = tab[index], prev = null; e != null;
                prev = e, e = e.getNext()) {
                if (e == entry) {
                    if (prev != null)
                        prev.setNext(e.getNext());
                        // otherwise put the bucket after us
                    else
                        tab[index] = e.getNext();

                    count--;
                    if (keyType == ReferenceStrength.HARD)
                        valueExpired(e.getKey());
                    else
                        keyExpired(e.getValue());
                }
            }
        }
    }

    /**
     * HashMap collision list entry.
     */
    private interface Entry extends Map.Entry {

        int getHash();

        Entry getNext();

        void setNext(Entry next);

        Object clone(ReferenceQueue queue);
    }

    /**
     * Hard entry.
     */
    private class HardEntry implements Entry {

        private int hash;
        private Object key;
        private Object value;
        private Entry next;

        HardEntry(int hash, Object key, Object value, Entry next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @Override
        public int getHash() {
            return hash;
        }

        @Override
        public Entry getNext() {
            return next;
        }

        @Override
        public void setNext(Entry next) {
            this.next = next;
        }

        @Override
        public Object clone(ReferenceQueue queue) {
            // It is the callers responsibility to set the next field
            // correctly.
            return new HardEntry(hash, key, value, null);
        }

        // Map.Entry Ops

        @Override
        public Object getKey() {
            return key;
        }

        @Override
        public Object getValue() {
            return value;
        }

        @Override
        public Object setValue(Object value) {
            Object oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry)) return false;
            Map.Entry e = (Map.Entry) o;

            Object k1 = key;
            Object k2 = e.getKey();

            return (k1 == null ? k2 == null : eq(k1, k2)) &&
                (value == null ? e.getValue() == null
                    : eq(value, e.getValue()));
        }

        @Override
        public int hashCode() {
            return hash ^ (value == null ? 0 : value.hashCode());
        }

        @Override
        public String toString() {
            return key + "=" + value.toString();
        }
    }

    /**
     * Weak entry.
     */
    private class WeakEntry extends WeakReference implements Entry {

        private int hash;
        private Object hard;
        private boolean keyRef;
        private Entry next;

        WeakEntry(int hash, Object key, Object value, boolean keyRef,
            Entry next, ReferenceQueue queue) {
            super((keyRef) ? key : value, queue);
            this.hash = hash;
            this.hard = (keyRef) ? value : key;
            this.keyRef = keyRef;
            this.next = next;
        }

        @Override
        public int getHash() {
            return hash;
        }

        @Override
        public Entry getNext() {
            return next;
        }

        @Override
        public void setNext(Entry next) {
            this.next = next;
        }

        @Override
        public Object clone(ReferenceQueue queue) {
            // It is the callers responsibility to set the next field
            // correctly.
            return new WeakEntry(hash, getKey(), getValue(), keyRef, null,
                queue);
        }

        // Map.Entry Ops

        @Override
        public Object getKey() {
            return (keyRef) ? super.get() : hard;
        }

        @Override
        public Object getValue() {
            return (keyRef) ? hard : super.get();
        }

        @Override
        public Object setValue(Object value) {
            if (!keyRef)
                throw new Error("Attempt to reset reference value.");

            Object oldValue = hard;
            hard = value;
            return oldValue;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry)) return false;
            Map.Entry e = (Map.Entry) o;
            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
        }

        @Override
        public int hashCode() {
            Object val = getValue();
            return hash ^ (val == null ? 0 : val.hashCode());
        }

        @Override
        public String toString() {
            return getKey() + "=" + getValue();
        }
    }

    /**
     * Soft entry.
     */
    private class SoftEntry extends SoftReference implements Entry {

        private int hash;
        private Object hard;
        private boolean keyRef;
        private Entry next;

        SoftEntry(int hash, Object key, Object value, boolean keyRef,
            Entry next, ReferenceQueue queue) {
            super((keyRef) ? key : value, queue);
            this.hash = hash;
            this.hard = (keyRef) ? value : key;
            this.keyRef = keyRef;
            this.next = next;
        }

        @Override
        public int getHash() {
            return hash;
        }

        @Override
        public Entry getNext() {
            return next;
        }

        @Override
        public void setNext(Entry next) {
            this.next = next;
        }

        @Override
        public Object clone(ReferenceQueue queue) {
            // It is the callers responsibility to set the next field
            // correctly.
            return new SoftEntry(hash, getKey(), getValue(), keyRef, null,
                queue);
        }

        // Map.Entry Ops

        @Override
        public Object getKey() {
            return (keyRef) ? super.get() : hard;
        }

        @Override
        public Object getValue() {
            return (keyRef) ? hard : super.get();
        }

        @Override
        public Object setValue(Object value) {
            if (!keyRef)
                throw new Error("Attempt to reset reference value.");

            Object oldValue = hard;
            hard = value;
            return oldValue;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry)) return false;
            Map.Entry e = (Map.Entry) o;
            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
        }

        @Override
        public int hashCode() {
            Object val = getValue();
            return hash ^ (val == null ? 0 : val.hashCode());
        }

        @Override
        public String toString() {
            return getKey() + "=" + getValue();
        }
    }

    // Types of Enumerations/Iterations
    private static final int KEYS = 0;
    private static final int VALUES = 1;
    private static final int ENTRIES = 2;

    /**
     * Map iterator.
     */
    private class HashIterator implements Iterator {

        final Entry[] table = ConcurrentReferenceHashMap.this.table;
        final int type;
        int startIndex;
        int stopIndex = 0;
        int index;
        Entry entry = null;
        Entry lastReturned = null;

        HashIterator(int type, int startIndex) {
            this.type = type;
            this.startIndex = startIndex;
            index = startIndex;
        }

        @Override
        public boolean hasNext() {
            if (entry != null) {
                return true;
            }
            while (index >= stopIndex) {
                if ((entry = table[index--]) != null) {
                    return true;
                }
            }
            if (stopIndex == 0) {
                index = table.length - 1;
                stopIndex = startIndex + 1;
                while (index >= stopIndex) {
                    if ((entry = table[index--]) != null) {
                        return true;
                    }
                }
            }
            return false;
        }

        @Override
        public Object next() {
            if (!hasNext())
                throw new NoSuchElementException();
            Entry e = lastReturned = entry;
            entry = e.getNext();
            return type == KEYS ? e.getKey()
                : (type == VALUES ? e.getValue() : e);
        }

        @Override
        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            synchronized (ConcurrentReferenceHashMap.this) {
                Entry[] tab = ConcurrentReferenceHashMap.this.table;
                int index = (lastReturned.getHash() & 0x7FFFFFFF) % tab.length;

                for (Entry e = tab[index], prev = null; e != null;
                    prev = e, e = e.getNext()) {
                    if (e == lastReturned) {
                        if (prev == null)
                            tab[index] = e.getNext();
                        else
                            prev.setNext(e.getNext());
                        count--;
                        lastReturned = null;
                        return;
                    }
                }
                throw new Error("Iterated off table when doing remove");
            }
        }
    }

    int capacity() {
        return table.length;
    }

    float loadFactor() {
        return loadFactor;
    }
}
