Unify Hash : Hash Code « Development Class « Java






Unify Hash

        
/* UnifyHash Copyright (C) 1999-2002 Jochen Hoenicke.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; see the file COPYING.LESSER.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: UnifyHash.java.in,v 1.3.2.2 2002/05/28 17:34:24 hoenicke Exp $
 */

///#ifdef JDK12
import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;
///#endif

import java.util.Comparator;
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.ConcurrentModificationException;
import java.lang.UnsupportedOperationException;

public class UnifyHash extends AbstractCollection {
    /** 
     * the default capacity
     */
    private static final int DEFAULT_CAPACITY = 11;

    /** the default load factor of a HashMap */
    private static final float DEFAULT_LOAD_FACTOR = 0.75F;

///#ifdef JDK12
    private ReferenceQueue queue = new ReferenceQueue();
///#endif

    static class Bucket
///#ifdef JDK12
  extends WeakReference
///#endif
    {
///#ifdef JDK12
  public Bucket(Object o, ReferenceQueue q) {
      super(o, q);
  }
///#else
/// public Bucket(Object o) {
///     this.obj = o;
/// }
///
/// Object obj;
///
/// public Object get() {
///     return obj;
/// }
///#endif

  int hash;
  Bucket next;
    }

    private Bucket[] buckets;
    int modCount = 0;
    int size = 0;
    int threshold;
    float loadFactor;

    public UnifyHash(int initialCapacity, float loadFactor) {
  this.loadFactor = loadFactor;
  buckets = new Bucket[initialCapacity];
  threshold = (int) (loadFactor * initialCapacity);
    }

    public UnifyHash(int initialCapacity) {
  this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    public UnifyHash() {
  this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
    }

    private void grow() {
  Bucket[] oldBuckets = buckets;
  int newCap = buckets.length * 2 + 1;
  threshold = (int) (loadFactor * newCap);
  buckets = new Bucket[newCap];
  for (int i = 0; i < oldBuckets.length; i++) {
      Bucket nextBucket;
      for (Bucket b = oldBuckets[i]; b != null; b = nextBucket) {
    if (i != Math.abs(b.hash % oldBuckets.length))
        throw new RuntimeException(""+i+", hash: "+b.hash+", oldlength: "+oldBuckets.length);
    int newSlot = Math.abs(b.hash % newCap);
    nextBucket = b.next;
    b.next = buckets[newSlot];
    buckets[newSlot] = b;
      }
  }
    }

///#ifdef JDK12
    public final void cleanUp() {
  Bucket died;
  while ((died = (Bucket)queue.poll()) != null) {
      int diedSlot = Math.abs(died.hash % buckets.length);
      if (buckets[diedSlot] == died)
    buckets[diedSlot] = died.next;
      else {
    Bucket b = buckets[diedSlot];
    while (b.next != died)
        b = b.next;
    b.next = died.next;
      }
      size--;
  }
    }
///#endif


    public int size() {
  return size;
    }

    public Iterator iterator() {
///#ifdef JDK12
  cleanUp();
///#endif

  return new Iterator() {
      private int bucket = 0;
      private int known = modCount;
      private Bucket nextBucket;
      private Object nextVal;

      {
    internalNext();
      }

      private void internalNext() {
    while (true) {
        while (nextBucket == null) {
      if (bucket == buckets.length)
          return;
      nextBucket = buckets[bucket++];
        }
        
        nextVal = nextBucket.get();
        if (nextVal != null)
      return;

        nextBucket = nextBucket.next;
    }
      }

      public boolean hasNext() {
    return nextBucket != null;
      }

      public Object next() {
    if (known != modCount)
        throw new ConcurrentModificationException();
    if (nextBucket == null)
        throw new NoSuchElementException();
    Object result = nextVal;
    nextBucket = nextBucket.next;
    internalNext();
    return result;
      }

      public void remove() {
    throw new UnsupportedOperationException();
      }
  };
    }

    public Iterator iterateHashCode(final int hash) {
///#ifdef JDK12
  cleanUp();
///#endif
  return new Iterator() {
      private int known = modCount;
      private Bucket nextBucket
    = buckets[Math.abs(hash % buckets.length)];
      private Object nextVal;

      {
    internalNext();
      }

      private void internalNext() {
    while (nextBucket != null) {
        if (nextBucket.hash == hash) {
      nextVal = nextBucket.get();
      if (nextVal != null)
          return;
        }

        nextBucket = nextBucket.next;
    }
      }

      public boolean hasNext() {
    return nextBucket != null;
      }

      public Object next() {
    if (known != modCount)
        throw new ConcurrentModificationException();
    if (nextBucket == null)
        throw new NoSuchElementException();
    Object result = nextVal;
    nextBucket = nextBucket.next;
    internalNext();
    return result;
      }

      public void remove() {
    throw new UnsupportedOperationException();
      }
  };
    }

    public void put(int hash, Object o) {
  if (size++ > threshold)
      grow();
  modCount++;

  int slot = Math.abs(hash % buckets.length);
///#ifdef JDK12
  Bucket b = new Bucket(o, queue);
///#else
/// Bucket b = new Bucket(o);
///#endif
  b.hash = hash;
  b.next = buckets[slot];
  buckets[slot] = b;
    }

    public Object unify(Object o, int hash, Comparator comparator) {
///#ifdef JDK12
  cleanUp();
///#endif
  int slot = Math.abs(hash % buckets.length);
  for (Bucket b = buckets[slot]; b != null; b = b.next) {
      Object old = b.get();
      if (old != null && comparator.compare(o, old) == 0)
    return old;
  }

  put(hash, o);
  return o;
    }
}

   
    
    
    
    
    
    
    
  








Related examples in the same category

1.Computing hash codes
2.A hash-code generator and a collection of static hash-code generation methods.
3.MD5 hash generator
4.Hash 32 String
5.Hash 64 String
6.MD5 hashing: Encodes a string
7.MD5 String
8.Hash Code BuilderHash Code Builder
9.HashCode generationHashCode generation
10.Get hash code for primitive data types
11.Return as hash code for the given object
12.Null Safe Hash Code
13.A very efficient java hash algorithm, based on the BuzHash algoritm
14.Easy implementation of hashCode
15.An implementation of the HMACT64 keyed hashing algorithm
16.Gets the hash code of an object returning zero when the object is null
17.Secure Hash
18.FNV Hash
19.Jenkins Hash
20.Concurrent Cuckoo hashing using lock striping. Uses R/W locks for resizing. Exercise solution.
21.Concurrent Cuckoo hashing using lock striping.
22.encode Hex
23.Fowler/Noll/Vo hash algorhythm
24.Produces 32-bit hash for hash table lookup. (Jenkins Hash Function)
25.Key Value Hash
26.Paul Hsieh's Hash Function.
27.An extension of WeakReference that implements a sane equals and hashcode method.
28.Dual Key Hash Map
29.A hash map with int key and int values.
30.null Safe Equals and Hash
31.Generates a hash code for a given source code.
32.AtkinsonHash utility class implements the hash algorithm used by HyperCard's ask password command.
33.Hash Code AssistHash Code Assist
34.This is a very fast, non-cryptographic hash suitable for general hash-based lookup.
35.An advanced hash table supporting configurable garbage collection semantics of keys and values
36.Hash string