
com.carrotsearch.hppcrt.hash.PhiMix Maven / Gradle / Ivy
package com.carrotsearch.hppcrt.hash;
/**
* Quickly mixes the bits of integers.
*
* Those methods mixes the bits of the argument by multiplying by the golden
* ratio and xorshifting the result.
*
* It is borrowed from Koloboke, and it has slightly
* worse behaviour than {@link MurmurHash3} (in open-addressing hash tables the
* average number of probes is slightly larger), but it's much faster.
*
* Reciprocal mixing functions are borrowed from fastutil.
*/
public final class PhiMix
{
/**
* 232 · φ, φ = (√5 − 1)/2. (package
* visibility)
*/
static final int INT_PHI = 0x9E3779B9;
/**
* 264 · φ, φ = (√5 − 1)/2. (package
* visibility)
*/
static final long LONG_PHI = 0x9E3779B97F4A7C15L;
/**
* The reciprocal of {@link #INT_PHI} modulo 232.
*/
private static final int INV_INT_PHI = 0x144cbc89;
/**
* The reciprocal of {@link #LONG_PHI} modulo 264.
*/
private static final long INV_LONG_PHI = 0xf1de83e19937733dL;
/**
* = hash((int)0)
*/
public static final int HASH_0 = 0;
/**
* = hash((int)1)
*/
public static final int HASH_1 = 1640556430;
private PhiMix() {
// no instances.
}
/**
* Hashes a 4-byte sequence (Java int).
*
* @param x
* an integer.
* @return a hash value obtained by mixing the bits of {@code x}.
*/
public static int mix32(final int x) {
final int h = x * PhiMix.INT_PHI;
return h ^ (h >> 16);
}
/**
* The inverse of {@link #mix32(int)}. This method is mainly useful to create
* unit tests.
*
* @param x
* an integer.
* @return a value that passed through {@link #mix32(int)} would give {@code x}
* .
*/
public static int invMix32(final int x) {
return (x ^ x >>> 16) * PhiMix.INV_INT_PHI;
}
/**
* Hashes an 8-byte sequence (Java long).
*
* @param x
* a long integer.
* @return a hash value obtained by mixing the bits of {@code x}.
*/
public static long mix64(final long x) {
long h = x * PhiMix.LONG_PHI;
h ^= h >> 32;
return h ^ (h >> 16);
}
/**
* The inverse of {@link #mix64(long)}. This method is mainly useful to create
* unit tests.
*
* @param x
* a long integer.
* @return a value that passed through {@link #mix64(long)} would give
* {@code x}.
*/
public static long invMix64(long x) {
x ^= x >>> 32;
x ^= x >>> 16;
return (x ^ x >>> 32) * PhiMix.INV_LONG_PHI;
}
}