FWIW this is also the implementation I used, also nicked from Knuth
(with credit), in my "Fast" set and map implementations. I also
believe it to be correct.

  private int find(long key) {
    int theHashCode = (int) key & 0x7FFFFFFF; // make sure it's positive
    long[] keys = this.keys;
    int hashSize = keys.length;
    int jump = 1 + theHashCode % (hashSize - 2);
    int index = theHashCode % hashSize;
    long currentKey = keys[index];
    while (currentKey != NULL && (currentKey == REMOVED || key != currentKey)) {
      if (index < jump) {
        index += hashSize - jump;
      } else {
        index -= jump;
      }
      currentKey = keys[index];
    }
    return index;
  }


On Wed, Jan 27, 2010 at 8:38 AM, Dawid Weiss <dawid.we...@gmail.com> wrote:
> The implementation in Colt is correct, it is double addressing, the
> value of the second hash is always relatively prime to the first one
> (and must not be zero). The colt's implementation can be rewritten as:
>
> const_increment = 1 + h % (m - 2);
>
> if you do a loop
>
> while (true)
> {
>  slot = (slot + const_increment) % m;
> }
>
> you will eventually iterate all slots between 0...m-1, no matter what
> const_increment's value was chosen. As far as I remember, Knuth also
> suggests to pick h2 (the second hash function) as a function of the
> first hash function, don't have the book with me right now though.
>
> D.
>

Reply via email to