blob: c56c6c4bd8a7ce155ee289f1a8acdadbd4d4a8d4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.datasketches.hash;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableMemory;
/**
* @author Lee Rhodes
*/
@SuppressWarnings("javadoc")
public class MurmurHash3v2Test {
@Test
public void offsetChecks() {
long seed = 12345;
int blocks = 6;
int cap = blocks * 16;
long[] hash1 = new long[2];
long[] hash2;
WritableMemory wmem = WritableMemory.allocate(cap);
for (int i = 0; i < cap; i++) { wmem.putByte(i, (byte)(-128 + i)); }
for (int offset = 0; offset < 16; offset++) {
int arrLen = cap - offset;
hash1 = MurmurHash3v2.hash(wmem, offset, arrLen, seed, hash1);
byte[] byteArr2 = new byte[arrLen];
wmem.getByteArray(offset, byteArr2, 0, arrLen);
hash2 = MurmurHash3.hash(byteArr2, seed);
assertEquals(hash1, hash2);
}
}
@Test
public void byteArrChecks() {
long seed = 0;
int offset = 0;
int bytes = 1024;
long[] hash2 = new long[2];
for (int j = 1; j < bytes; j++) {
byte[] in = new byte[bytes];
WritableMemory wmem = WritableMemory.writableWrap(in);
for (int i = 0; i < j; i++) { wmem.putByte(i, (byte) (-128 + i)); }
long[] hash1 = MurmurHash3.hash(in, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(in, seed);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
}
}
@Test
public void charArrChecks() {
long seed = 0;
int offset = 0;
int chars = 16;
int bytes = chars << 1;
long[] hash2 = new long[2];
for (int j = 1; j < chars; j++) {
char[] in = new char[chars];
WritableMemory wmem = WritableMemory.writableWrap(in);
for (int i = 0; i < j; i++) { wmem.putInt(i, i); }
long[] hash1 = MurmurHash3.hash(in, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(in, seed);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
}
}
@Test
public void intArrChecks() {
long seed = 0;
int offset = 0;
int ints = 16;
int bytes = ints << 2;
long[] hash2 = new long[2];
for (int j = 1; j < ints; j++) {
int[] in = new int[ints];
WritableMemory wmem = WritableMemory.writableWrap(in);
for (int i = 0; i < j; i++) { wmem.putInt(i, i); }
long[] hash1 = MurmurHash3.hash(in, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(in, seed);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
}
}
@Test
public void longArrChecks() {
long seed = 0;
int offset = 0;
int longs = 16;
int bytes = longs << 3;
long[] hash2 = new long[2];
for (int j = 1; j < longs; j++) {
long[] in = new long[longs];
WritableMemory wmem = WritableMemory.writableWrap(in);
for (int i = 0; i < j; i++) { wmem.putLong(i, i); }
long[] hash1 = MurmurHash3.hash(in, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(in, seed);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
}
}
@Test
public void longCheck() {
long seed = 0;
int offset = 0;
int bytes = 8;
long[] hash2 = new long[2];
long[] in = { 1 };
WritableMemory wmem = WritableMemory.writableWrap(in);
long[] hash1 = MurmurHash3.hash(in, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(in, seed);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
}
@Test
public void checkEmptiesNulls() {
long seed = 123;
long[] hashOut = new long[2];
Memory mem = Memory.wrap(new long[0]);
long hash0 = MurmurHash3v2.hash(mem, 0, 0, seed, hashOut)[0]; //mem empty
mem = null;
assertEquals(MurmurHash3v2.hash(mem, 0, 0, seed, hashOut)[0], hash0); //mem null
String s = "";
assertEquals(MurmurHash3v2.hash(s, seed, hashOut)[0], hash0); //string empty
s = null;
assertEquals(MurmurHash3v2.hash(s, seed, hashOut)[0], hash0); //string null
byte[] barr = new byte[0];
assertEquals(MurmurHash3v2.hash(barr, seed)[0], hash0); //byte[] empty
barr = null;
assertEquals(MurmurHash3v2.hash(barr, seed)[0], hash0); //byte[] null
char[] carr = new char[0];
assertEquals(MurmurHash3v2.hash(carr, seed)[0], hash0); //char[] empty
carr = null;
assertEquals(MurmurHash3v2.hash(carr, seed)[0], hash0); //char[] null
int[] iarr = new int[0];
assertEquals(MurmurHash3v2.hash(iarr, seed)[0], hash0); //int[] empty
iarr = null;
assertEquals(MurmurHash3v2.hash(iarr, seed)[0], hash0); //int[] null
long[] larr = new long[0];
assertEquals(MurmurHash3v2.hash(larr, seed)[0], hash0); //long[] empty
larr = null;
assertEquals(MurmurHash3v2.hash(larr, seed)[0], hash0); //long[] empty
}
@Test
public void checkStringLong() {
long seed = 123;
long[] hashOut = new long[2];
String s = "123";
assertTrue(MurmurHash3v2.hash(s, seed, hashOut)[0] != 0);
long v = 123;
assertTrue(MurmurHash3v2.hash(v, seed, hashOut)[0] != 0);
}
@Test
public void doubleCheck() {
long[] hash1 = checkDouble(-0.0);
long[] hash2 = checkDouble(0.0);
assertEquals(hash1, hash2);
hash1 = checkDouble(Double.NaN);
long nan = (0x7FFL << 52) + 1L;
hash2 = checkDouble(Double.longBitsToDouble(nan));
assertEquals(hash1, hash2);
checkDouble(1.0);
}
private static long[] checkDouble(double dbl) {
long seed = 0;
int offset = 0;
int bytes = 8;
long[] hash2 = new long[2];
final double d = (dbl == 0.0) ? 0.0 : dbl; // canonicalize -0.0, 0.0
final long data = Double.doubleToLongBits(d);// canonicalize all NaN forms
final long[] dataArr = { data };
WritableMemory wmem = WritableMemory.writableWrap(dataArr);
long[] hash1 = MurmurHash3.hash(dataArr, 0);
hash2 = MurmurHash3v2.hash(wmem, offset, bytes, seed, hash2);
long[] hash3 = MurmurHash3v2.hash(dbl, seed, hash2);
assertEquals(hash1, hash2);
assertEquals(hash1, hash3);
return hash1;
}
}