blob: 8f2e32c7fbfa7722f50623472e1c42727080e606 [file] [log] [blame]
package edu.uci.ics.hyracks.data.std.accessors;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunction;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFamily;
public class MurmurHash3BinaryHashFunctionFamily implements IBinaryHashFunctionFamily {
private static final long serialVersionUID = 1L;
private static final int C1 = 0xcc9e2d51;
private static final int C2 = 0x1b873593;
private static final int C3 = 5;
private static final int C4 = 0xe6546b64;
private static final int C5 = 0x85ebca6b;
private static final int C6 = 0xc2b2ae35;
@Override
public IBinaryHashFunction createBinaryHashFunction(final int seed) {
return new IBinaryHashFunction() {
@Override
public int hash(byte[] bytes, int offset, int length) {
int h = seed;
int p = offset;
int remain = length;
while (remain > 4) {
int k = ((int) bytes[p]) | (((int) bytes[p + 1]) << 8) | (((int) bytes[p + 2]) << 16)
| (((int) bytes[p + 3]) << 24);
k *= C1;
k = Integer.rotateLeft(k, 15);
k *= C2;
h ^= k;
h = Integer.rotateLeft(h, 13);
h = h * C3 + C4;
p += 4;
remain -= 4;
}
int k = 0;
switch (remain) {
case 3:
k = bytes[p++];
case 2:
k = (k << 8) | bytes[p++];
case 1:
k = (k << 8) | bytes[p++];
k *= C1;
k = Integer.rotateLeft(k, 15);
k *= C2;
h ^= k;
h = Integer.rotateLeft(h, 13);
h = h * C3 + C4;
}
h ^= length;
h ^= (h >>> 16);
h *= C5;
h ^= (h >>> 13);
h *= C6;
h ^= (h >>> 16);
return h;
}
};
}
}