package rpi.goldsd.container;

/**
 * The <tt>Hashable</tt> interface defines two versions of the
 * <tt>hash()</tt> method for those objects that are to be stored
 * in a hashtable or other associative container.  Note that this
 * interface extends the <tt>Comparable</tt> interface in order to
 * ensure that the <tt>isEqualTo()</tt> method is defined for
 * elements implementing this interface.
 *
 * @see Comparable
 * @see Table
 * @see AssociativeContainer
 * @version 1.0, 3/17/98
 * @author David Goldschmidt
 */
public interface Hashable extends Comparable
{
  /**
   * Returns an integer representation of the object implementing
   * the <tt>Hashable</tt> interface.  The hash value must be a valid Java
   * integer, and its generation must adhere to the following rules:
   * <p>
   * <ol start="1">
   * <li> The <tt>hash()</tt> method must perform in constant time
   *      <b>O(1)</b>.
   * <li> For a given object, the hash value must not change during
   *      the lifetime of the object.  In other words, each call to
   *      the <tt>hash()</tt> method for a given object must always return
   *      the same integer value.
   * <li> Two objects that are deemed equal according to the
   *      <tt>isEqualTo()</tt> method of the <tt>Comparable</tt> interface
   *      must have identical hash values.  In other words, calls
   *      to the <tt>hash()</tt> method of the equal objects must produce
   *      the same integer value.
   * </ol>
   * <p>
   * Ideally, the <tt>hash()</tt> method should generate hash values that
   * are fairly random.  To take advantage of the performance gains
   * of associative hashtable structures, the hash values should
   * be evenly distributed over the size of the hashtable.  When
   * the size of the hashtable is known, the second <tt>hash()</tt> method
   * defined next should be used.
   * @return the hash value representing the corresponding object.
   */
  public int hash();


  /**
   * Generates a valid hash value and will typically call the
   * no-argument <tt>hash()</tt> method described above.  The single
   * argument to this version of the <tt>hash()</tt> method is an integer
   * value representing the size of the associative hashtable that will
   * make use of the generated hash value.  This value should be
   * used in the generation of the hash value for the given object.
   * <p>
   * The generation of the hash value must adhere to the same
   * three requirements detailed in the previous description;
   * however, requirements (2) and (3) should be adhered to only
   * for calls to the <tt>hash()</tt> method in which the <tt>tableSize</tt>
   * argument is the same.  For example, if this <tt>hash()</tt> method is
   * repeatedly called with a <tt>tableSize</tt> of 101, the resulting hash
   * values must all be the same.  If a <tt>tableSize</tt> of 203 is then
   * used, the resulting hash value may be different from that obtained
   * with a <tt>tableSize</tt> of 101.
   * <p>
   * A fourth requirement is also expected when using this version
   * of the <tt>hash()</tt> method:
   * <p>
   * <ol start="4">
   * <li> The resulting hash value must be in the inclusive range
   *      <tt>0..(tableSize-1)</tt>.
   * </ol>
   * <p>
   * If nothing else, this method should be implemented as follows:
   * <pre>
   *   public int hash( int tableSize )
   *   {
   *     // restrict hash value to 0..(tableSize-1)
   *     return ( Math.abs( hash() ) % tableSize );
   *   }
   * </pre>
   * @return the hash value representing the corresponding object
   *         in the inclusive range <tt>0..(tableSize-1)</tt>.
   */
  public int hash( int tableSize );
}

