Entry(K key, V object, ReferenceQueue<K> queue) { super(key, queue); isNull = key == null; hash = isNull ? 0 : Collections.secondaryHash(key); value = object; }
/** * Computes an identity hash code and applies a supplemental hash function to defend * against poor quality hash functions. This is critical because identity hash codes * are currently implemented as object addresses, which will have been aligned by the * underlying memory allocator causing all hash codes to have the same bottom bits. * @hide */ public static int secondaryIdentityHash(Object key) { return secondaryHash(System.identityHashCode(key)); }
/** * Computes a hash code and applies a supplemental hash function to defend * against poor quality hash functions. This is critical because HashMap * uses power-of-two length hash tables, that otherwise encounter collisions * for hash codes that do not differ in lower or upper bits. * Routine taken from java.util.concurrent.ConcurrentHashMap.hash(int). * @hide */ public static int secondaryHash(Object key) { return secondaryHash(key.hashCode()); }
/** * Returns true if this map contains the specified mapping. */ private synchronized boolean containsMapping(Object key, Object value) { int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; int index = hash & (tab.length - 1); for (HashtableEntry<K, V> e = tab[index]; e != null; e = e.next) { if (e.hash == hash && e.key.equals(key)) { return e.value.equals(value); } } return false; // No entry for key }
/** * Returns the value associated with the specified key in this * {@code Hashtable}. * * @param key * the key of the value returned. * @return the value associated with the specified key, or {@code null} if * the specified key does not exist. * @see #put */ public synchronized V get(Object key) { int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)]; e != null; e = e.next) { K eKey = e.key; if (eKey == key || (e.hash == hash && key.equals(eKey))) { return e.value; } } return null; }
/** * Returns true if this {@code Hashtable} contains the specified object as a * key of one of the key/value pairs. * * @param key * the object to look for as a key in this {@code Hashtable}. * @return {@code true} if object is a key in this {@code Hashtable}, * {@code false} otherwise. * @see #contains * @see java.lang.Object#equals */ public synchronized boolean containsKey(Object key) { int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)]; e != null; e = e.next) { K eKey = e.key; if (eKey == key || (e.hash == hash && key.equals(eKey))) { return true; } } return false; }
/** * Removes the key/value pair with the specified key from this * {@code Hashtable}. * * @param key * the key to remove. * @return the value associated with the specified key, or {@code null} if * the specified key did not exist. * @see #get * @see #put */ public synchronized V remove(Object key) { int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; int index = hash & (tab.length - 1); for (HashtableEntry<K, V> e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && key.equals(e.key)) { if (prev == null) { tab[index] = e.next; } else { prev.next = e.next; } modCount++; size--; return e.value; } } return null; }
/** * Removes the mapping from key to value and returns true if this mapping * exists; otherwise, returns does nothing and returns false. */ private synchronized boolean removeMapping(Object key, Object value) { int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; int index = hash & (tab.length - 1); for (HashtableEntry<K, V> e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key.equals(key)) { if (!e.value.equals(value)) { return false; // Map has wrong value for key } if (prev == null) { tab[index] = e.next; } else { prev.next = e.next; } modCount++; size--; return true; } } return false; // No entry for key }
/** * This method is just like put, except that it doesn't do things that * are inappropriate or unnecessary for constructors and pseudo-constructors * (i.e., clone, readObject). In particular, this method does not check to * ensure that capacity is sufficient, and does not increment modCount. */ private void constructorPut(K key, V value) { if (key == null) { throw new NullPointerException("key == null"); } else if (value == null) { throw new NullPointerException("value == null"); } int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; int index = hash & (tab.length - 1); HashtableEntry<K, V> first = tab[index]; for (HashtableEntry<K, V> e = first; e != null; e = e.next) { if (e.hash == hash && key.equals(e.key)) { e.value = value; return; } } // No entry for key is present; create one tab[index] = new HashtableEntry<K, V>(key, value, hash, first); size++; }
Entry<K, V> getEntry(Object key) { poll(); if (key != null) { int index = (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length; Entry<K, V> entry = elementData[index]; while (entry != null) { if (key.equals(entry.get())) { return entry; } entry = entry.next; } return null; } Entry<K, V> entry = elementData[0]; while (entry != null) { if (entry.isNull) { return entry; } entry = entry.next; } return null; }
poll(); if (key != null) { int index = (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length; Entry<K, V> entry = elementData[index]; while (entry != null) {
Entry<K, V> entry; if (key != null) { index = (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length; entry = elementData[index]; while (entry != null && !key.equals(entry.get())) { if (++elementCount > threshold) { rehash(); index = key == null ? 0 : (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length;
throw new NullPointerException("value == null"); int hash = Collections.secondaryHash(key); HashtableEntry<K, V>[] tab = table; int index = hash & (tab.length - 1);
Entry<K, V> entry, last = null; if (key != null) { index = (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length; entry = elementData[index]; while (entry != null && !key.equals(entry.get())) {
Entry(K key, V object, ReferenceQueue<K> queue) { super(key, queue); isNull = key == null; hash = isNull ? 0 : Collections.secondaryHash(key); value = object; }
Entry(K key, V object, ReferenceQueue<K> queue) { super(key, queue); isNull = key == null; hash = isNull ? 0 : Collections.secondaryHash(key); value = object; }
Entry(K key, V object, ReferenceQueue<K> queue) { super(key, queue); isNull = key == null; hash = isNull ? 0 : Collections.secondaryHash(key); value = object; }
/** * Computes a hash code and applies a supplemental hash function to defend * against poor quality hash functions. This is critical because HashMap * uses power-of-two length hash tables, that otherwise encounter collisions * for hash codes that do not differ in lower or upper bits. * Routine taken from java.util.concurrent.ConcurrentHashMap.hash(int). * @hide */ public static int secondaryHash(Object key) { return secondaryHash(key.hashCode()); }
/** * Computes an identity hash code and applies a supplemental hash function to defend * against poor quality hash functions. This is critical because identity hash codes * are currently implemented as object addresses, which will have been aligned by the * underlying memory allocator causing all hash codes to have the same bottom bits. * @hide */ public static int secondaryIdentityHash(Object key) { return secondaryHash(System.identityHashCode(key)); }
/** * Computes an identity hash code and applies a supplemental hash function to defend * against poor quality hash functions. This is critical because identity hash codes * are currently implemented as object addresses, which will have been aligned by the * underlying memory allocator causing all hash codes to have the same bottom bits. * @hide */ public static int secondaryIdentityHash(Object key) { return secondaryHash(System.identityHashCode(key)); }