Skip to content

Commit 1f92499

Browse files
committed
Infinite loop in XOR filter construction #29
1 parent 787dbbb commit 1f92499

File tree

5 files changed

+42
-4
lines changed

5 files changed

+42
-4
lines changed

fastfilter/src/main/java/org/fastfilter/xor/Xor16.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class Xor16 implements Filter {
1616

1717
private static final int BITS_PER_FINGERPRINT = 16;
1818
private static final int HASHES = 3;
19+
private static final int OFFSET = 32;
1920
private static final int FACTOR_TIMES_100 = 123;
2021
private final int blockLength;
2122
private long seed;
@@ -27,7 +28,7 @@ public long getBitCount() {
2728
}
2829

2930
private static int getArrayLength(int size) {
30-
return (int) (HASHES + (long) FACTOR_TIMES_100 * size / 100);
31+
return (int) (OFFSET + (long) FACTOR_TIMES_100 * size / 100);
3132
}
3233

3334
public static Xor16 construct(long[] keys) {

fastfilter/src/main/java/org/fastfilter/xor/Xor8.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class Xor8 implements Filter {
1818

1919
private static final int BITS_PER_FINGERPRINT = 8;
2020
private static final int HASHES = 3;
21+
private static final int OFFSET = 32;
2122
private static final int FACTOR_TIMES_100 = 123;
2223
private final int size;
2324
private final int arrayLength;
@@ -31,7 +32,7 @@ public long getBitCount() {
3132
}
3233

3334
private static int getArrayLength(int size) {
34-
return (int) (HASHES + (long) FACTOR_TIMES_100 * size / 100);
35+
return (int) (OFFSET + (long) FACTOR_TIMES_100 * size / 100);
3536
}
3637

3738
public static Xor8 construct(long[] keys) {

fastfilter/src/main/java/org/fastfilter/xorplus/XorPlus8.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class XorPlus8 implements Filter {
2727

2828
private static final int HASHES = 3;
2929

30+
private static final int OFFSET = 32;
31+
3032
// the table needs to be 1.23 times the number of keys to store
3133
// with 2 hashes, we would need 232 (factor 2.32) for a 50% chance,
3234
// 240 for 55%, 250 for a 60%, 264 for 65%, 282 for 67%, as for
@@ -63,13 +65,13 @@ public long getBitCount() {
6365
}
6466

6567
/**
66-
* Calculate the table (array) length. This is 1.23 times the size.
68+
* Calculate the table (array) length. This is 1.23 times the size, plus an offset of 32 (see paper, Fig. 1)
6769
*
6870
* @param size the number of entries
6971
* @return the table length
7072
*/
7173
private static int getArrayLength(int size) {
72-
return (int) (HASHES + (long) FACTOR_TIMES_100 * size / 100);
74+
return (int) (OFFSET + (long) FACTOR_TIMES_100 * size / 100);
7375
}
7476

7577
public static XorPlus8 construct(long[] keys) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.fastfilter.xor;
2+
3+
import org.junit.Test;
4+
5+
/**
6+
* Test small sets.
7+
*/
8+
9+
public class SmallSetTest {
10+
11+
@Test
12+
public void small() {
13+
Xor8.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
14+
Xor16.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
15+
XorBinaryFuse8.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
16+
XorSimple.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
17+
XorSimple2.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
18+
}
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.fastfilter.xorplus;
2+
3+
import org.junit.Test;
4+
5+
/**
6+
* Test small sets.
7+
*/
8+
9+
public class SmallSetTest {
10+
11+
@Test
12+
public void small() {
13+
XorPlus8.construct(new long[]{0xef9bddc5166c081cL, 0x33bf87adaa46dcfcL});
14+
}
15+
}

0 commit comments

Comments
 (0)