提交 74462788 authored 作者: Thomas Mueller's avatar Thomas Mueller

A minimal perfect hash function tool: use universal hashing callback (with sample implementations)

上级 912789cb
...@@ -5,11 +5,15 @@ ...@@ -5,11 +5,15 @@
*/ */
package org.h2.test.unit; package org.h2.test.unit;
import java.util.BitSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import org.h2.dev.hash.MinimalPerfectHash; import org.h2.dev.hash.MinimalPerfectHash;
import org.h2.dev.hash.MinimalPerfectHash.LongHash;
import org.h2.dev.hash.MinimalPerfectHash.StringHash;
import org.h2.dev.hash.MinimalPerfectHash.UniversalHash;
import org.h2.dev.hash.PerfectHash; import org.h2.dev.hash.PerfectHash;
import org.h2.test.TestBase; import org.h2.test.TestBase;
...@@ -25,8 +29,8 @@ public class TestPerfectHash extends TestBase { ...@@ -25,8 +29,8 @@ public class TestPerfectHash extends TestBase {
*/ */
public static void main(String... a) throws Exception { public static void main(String... a) throws Exception {
TestPerfectHash test = (TestPerfectHash) TestBase.createCaller().init(); TestPerfectHash test = (TestPerfectHash) TestBase.createCaller().init();
test.test();
test.measure(); test.measure();
test.test();
} }
/** /**
...@@ -34,9 +38,16 @@ public class TestPerfectHash extends TestBase { ...@@ -34,9 +38,16 @@ public class TestPerfectHash extends TestBase {
*/ */
public void measure() { public void measure() {
int size = 1000000; int size = 1000000;
int s;
int s = testMinimal(size); long time = System.currentTimeMillis();
System.out.println((double) s / size + " bits/key (minimal)"); s = testMinimal(size);
time = System.currentTimeMillis() - time;
System.out.println((double) s / size + " bits/key (minimal) in " + time + " ms");
time = System.currentTimeMillis();
s = testMinimalWithString(size);
time = System.currentTimeMillis() - time;
System.out.println((double) s / size + " bits/key (minimal; String keys) in " + time + " ms");
s = test(size, true); s = test(size, true);
System.out.println((double) s / size + " bits/key (minimal old)"); System.out.println((double) s / size + " bits/key (minimal old)");
...@@ -97,27 +108,41 @@ public class TestPerfectHash extends TestBase { ...@@ -97,27 +108,41 @@ public class TestPerfectHash extends TestBase {
private int testMinimal(int size) { private int testMinimal(int size) {
Random r = new Random(size); Random r = new Random(size);
HashSet<Integer> set = new HashSet<Integer>(); HashSet<Long> set = new HashSet<Long>();
while (set.size() < size) { while (set.size() < size) {
set.add(r.nextInt()); set.add((long) r.nextInt());
} }
byte[] desc = MinimalPerfectHash.generate(set); LongHash hf = new LongHash();
int max = testMinimal(desc, set); byte[] desc = MinimalPerfectHash.generate(set, hf);
int max = testMinimal(desc, set, hf);
assertEquals(size - 1, max);
return desc.length * 8;
}
private int testMinimalWithString(int size) {
Random r = new Random(size);
HashSet<String> set = new HashSet<String>();
while (set.size() < size) {
set.add("x " + r.nextDouble());
}
StringHash hf = new StringHash();
byte[] desc = MinimalPerfectHash.generate(set, hf);
int max = testMinimal(desc, set, hf);
assertEquals(size - 1, max); assertEquals(size - 1, max);
return desc.length * 8; return desc.length * 8;
} }
private int testMinimal(byte[] desc, Set<Integer> set) { private <K> int testMinimal(byte[] desc, Set<K> set, UniversalHash<K> hf) {
int max = -1; int max = -1;
HashSet<Integer> test = new HashSet<Integer>(); BitSet test = new BitSet();
MinimalPerfectHash hash = new MinimalPerfectHash(desc); MinimalPerfectHash<K> hash = new MinimalPerfectHash<K>(desc, hf);
for (int x : set) { for (K x : set) {
int h = hash.get(x); int h = hash.get(x);
assertTrue(h >= 0); assertTrue(h >= 0);
assertTrue(h <= set.size() * 3); assertTrue(h <= set.size() * 3);
max = Math.max(max, h); max = Math.max(max, h);
assertFalse(test.contains(h)); assertFalse(test.get(h));
test.add(h); test.set(h);
} }
return max; return max;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论