Mega Code Archive

 
Categories / Java / Development Class
 

This is a very fast, non-cryptographic hash suitable for general hash-based lookup

/*  * 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; /**  * This is a very fast, non-cryptographic hash suitable for general hash-based  * lookup. See http://murmurhash.googlepages.com/ for more details.  *   * <p>  * The C version of MurmurHash 2.0 found at that site was ported to Java by  * Andrzej Bialecki (ab at getopt org).  * </p>  *   * This is suitable for 32bit application, if 64bit we need to improve it.  *   * @see http://murmurhash.googlepages.com/  */ public class MurmurHashFunction extends AbstractHashFunction {   public int hash(byte[] data, int length, int seed) {     int m = 0x5bd1e995;     int r = 24;     int h = seed ^ length;     int len_4 = length >> 2;     for (int i = 0; i < len_4; i++) {       int i_4 = i << 2;       int k = data[i_4 + 3];       k = k << 8;       k = k | (data[i_4 + 2] & 0xff);       k = k << 8;       k = k | (data[i_4 + 1] & 0xff);       k = k << 8;       k = k | (data[i_4 + 0] & 0xff);       k *= m;       k ^= k >>> r;       k *= m;       h *= m;       h ^= k;     }     // avoid calculating modulo     int len_m = len_4 << 2;     int left = length - len_m;     if (left != 0) {       if (left >= 3) {         h ^= (int) data[length - 3] << 16;       }       if (left >= 2) {         h ^= (int) data[length - 2] << 8;       }       if (left >= 1) {         h ^= (int) data[length - 1];       }       h *= m;     }     h ^= h >>> 13;     h *= m;     h ^= h >>> 15;     return h;   } } 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); }