package DataStructures; /** *

A probing hash table implementation of a LookupTable * with collisions resolved by double hashing.

* *

Tables may be constructed, for example, by *

 *      LookupTable<String,Integer> t = new QuadraticProbingTable<String,Integer>();
 *      t.add("one", 1);
 *      t.add("two", 2);
 *      t.add("three", 3);
 * 
*

To retrieve a value use for example: *

 *      try {
 *        System.out.println(t.lookup("two"));
 *      } catch (NoSuchElementException e) {
 *        System.err.println(e);
 *      }
 * 
* *

Entries can be read in sequence as follows: *

 *      for (LookupTable.Entry<String,Integer> entry : t) {
 *          System.out.println(entry);
 *      }
 *
 * @see LookupTable
 * @see ProbingHashTable
 * @param  the type of objects serving as keys
 * @param  the type of objects serving as values
 * 
 * @author Peter Williams
 */

public class DoubleHashingTable extends ProbingHashTable {
    /*
     * default values of size and load factor
     */
    private static final int SIZE = 1;
    private static final double LOADFACTOR = 0.5;
  
    /**
     * Constructs a hash table initially capable of holding the given 
     * number of entries subject to the give loadfactor.
     * The table will grow if necessary to ensure the load factor is not
     * exceeded.  The specified load factor must lie between 0 and 1.
     * @param size the number of entries to be made initially
     * @param loadFactor the maximum loading before the table must grow
     * @exception IllegalArgumentException if the specified load factor is
     * out of range
     */  
    public DoubleHashingTable(int size, double loadFactor) {
        super(size, loadFactor);
    }
  
    /**
     * Constructs a hash table with specified initial size and default load factor.
     * @param size the number of entries to be made initially
     */  
    public DoubleHashingTable(int size) {
        super(size, LOADFACTOR);
    }
    
    /**
     * Constructs a hash table with default initial size and load factor.
     */  
    public DoubleHashingTable() {
        super(SIZE, LOADFACTOR);
    }
    
    /**
     * Method returning the index in ProbingHashTable.table of a key, 
     * if present, or the index at which to insert it, if absent.
     * Uses a version of double hashing.
     * @param key the key to search for
     * @return the position where the search terminates
     */
    protected final int findIndex(K key) {
        int code = key.hashCode() & Integer.MAX_VALUE;
        int length = table.length;
        int index = code % length;
        int probe = 1 + (code % (length - 1));
        while (table[index] != null && !(table[index].key.equals(key))) {
	    index += probe;
	    if (index >= length) {
		index -= length;
	    }
	}
	return index;
    }
}