Fowler/Noll/Vo hash algorhythm
/*
* Copyright 2008-2010 the T2 Project ant the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//package org.t2framework.commons.util;
/**
* Fowler/Noll/Vo hash algorhythm.
*
* This one is originally from http://www.isthe.com/chongo/tech/comp/fnv, and is
* taken from project voldemort.
*
* The basic theory is:
*
* <pre>
* hash = basis
* for each octet_of_data to be hashed
* hash = hash * FNV_prime
* hash = hash xor octet_of_data
* return hash
* </pre>
*
* @see http://www.isthe.com/chongo/tech/comp/fnv
* @see http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param
*
*/
public class FnvHashFunction extends AbstractHashFunction {
private static final long FNV_BASIS = 0x811c9dc5;
// for 32bit
private static final long FNV_PRIME = (1 << 24) + 0x193;
public int hash(byte[] bytes, int length, int initval) {
long hash = FNV_BASIS;
for (int i = 0; i < bytes.length; i++) {
hash ^= 0xFF & bytes[i];
hash *= FNV_PRIME;
}
return (int) hash;
}
}
abstract class AbstractHashFunction implements HashFunction {
public int hash(byte[] bytes, int initval) {
return hash(bytes, bytes.length, initval);
}
public int hash(byte[] bytes) {
return hash(bytes, bytes.length, -1);
}
}
interface HashFunction {
int hash(byte[] bytes);
int hash(byte[] bytes, int initval);
int hash(byte[] bytes, int length, int initval);
}
---------------
package org.t2framework.commons.util;
import junit.framework.TestCase;
public class FnvHashFunctionTest extends TestCase {
public void test1() throws Exception {
FnvHashFunction fnv = new FnvHashFunction();
int numIterations = 1000000;
int numBuckets = 5;
int[] buckets = new int[numBuckets];
long start = System.currentTimeMillis();
for (int i = 0; i < numIterations; i++) {
int val = fnv.hash(Integer.toString(i).getBytes());
buckets[Math.abs(val) % numBuckets] += 1;
}
System.out.println(System.currentTimeMillis() - start);
double expected = numIterations / (double) numBuckets;
for (int i = 0; i < numBuckets; i++) {
System.out.println(i + " " + buckets[i] + " "
+ (buckets[i] / expected));
}
}
public void test2() throws Exception {
MurmurHashFunction mur = new MurmurHashFunction();
int numIterations = 1000000;
int numBuckets = 5;
int[] buckets = new int[numBuckets];
long start = System.currentTimeMillis();
for (int i = 0; i < numIterations; i++) {
int val = mur.hash(Integer.toString(i).getBytes());
buckets[Math.abs(val) % numBuckets] += 1;
}
System.out.println(System.currentTimeMillis() - start);
double expected = numIterations / (double) numBuckets;
for (int i = 0; i < numBuckets; i++) {
System.out.println(i + " " + buckets[i] + " "
+ (buckets[i] / expected));
}
}
public void test3() throws Exception {
JenkinsHashFunction jenkins = new JenkinsHashFunction();
int numIterations = 1000000;
int numBuckets = 5;
int[] buckets = new int[numBuckets];
long start = System.currentTimeMillis();
for (int i = 0; i < numIterations; i++) {
int val = jenkins.hash(Integer.toString(i).getBytes());
buckets[Math.abs(val) % numBuckets] += 1;
}
System.out.println(System.currentTimeMillis() - start);
double expected = numIterations / (double) numBuckets;
for (int i = 0; i < numBuckets; i++) {
System.out.println(i + " " + buckets[i] + " "
+ (buckets[i] / expected));
}
}
}
Related examples in the same category