Skip to content

Commit d1c7490

Browse files
committed
Performance: use a byte array to count hits when possible
1 parent 504589b commit d1c7490

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.klibisz.elastiknn.search;
2+
3+
import org.apache.lucene.search.KthGreatest;
4+
5+
public class ByteArrayHitCounter implements HitCounter {
6+
7+
public final byte[] counts;
8+
private int numHits;
9+
private int minKey;
10+
private int maxKey;
11+
12+
13+
public ByteArrayHitCounter(int capacity) {
14+
counts = new byte[capacity];
15+
numHits = 0;
16+
minKey = capacity;
17+
maxKey = 0;
18+
}
19+
20+
@Override
21+
public void increment(int key) {
22+
if (counts[key]++ == 0) {
23+
numHits++;
24+
minKey = Math.min(key, minKey);
25+
maxKey = Math.max(key, maxKey);
26+
}
27+
}
28+
29+
@Override
30+
public void increment(int key, short count) {
31+
if ((counts[key] += count) == count) {
32+
numHits++;
33+
minKey = Math.min(key, minKey);
34+
maxKey = Math.max(key, maxKey);
35+
}
36+
}
37+
38+
@Override
39+
public boolean isEmpty() {
40+
return numHits == 0;
41+
}
42+
43+
@Override
44+
public short get(int key) {
45+
return counts[key];
46+
}
47+
48+
@Override
49+
public int numHits() {
50+
return numHits;
51+
}
52+
53+
@Override
54+
public int capacity() {
55+
return counts.length;
56+
}
57+
58+
@Override
59+
public int minKey() {
60+
return minKey;
61+
}
62+
63+
@Override
64+
public int maxKey() {
65+
return maxKey;
66+
}
67+
68+
@Override
69+
public KthGreatest.Result kthGreatest(int k) {
70+
// Find the min and max values.
71+
int max = counts[0] & 0xFF;
72+
int min = max;
73+
for (byte b: counts) {
74+
if ((b & 0xFF) > max) max = b & 0xFF;
75+
else if ((b & 0xFF) < min) min = b % 0xFF;
76+
}
77+
78+
// Build and populate a histogram for non-zero values.
79+
int[] hist = new int[max - min + 1];
80+
int numNonZero = 0;
81+
for (short a: arr) {
82+
hist[a - min] += 1;
83+
if (a > 0) numNonZero++;
84+
}
85+
86+
// Find the kth largest value by iterating from the end of the histogram.
87+
int numGreaterEqual = 0;
88+
short kthGreatest = max;
89+
while (kthGreatest >= min) {
90+
numGreaterEqual += hist[kthGreatest - min];;
91+
if (numGreaterEqual > k) break;
92+
else kthGreatest--;
93+
}
94+
int numGreater = numGreaterEqual - hist[kthGreatest - min];
95+
96+
return new KthGreatest.Result(kthGreatest, numGreater, numNonZero);
97+
98+
99+
return null;
100+
}
101+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.klibisz.elastiknn.search;
2+
3+
public class Test {
4+
5+
public static void main(String[] args) {
6+
byte[] b = new byte[3];
7+
b[0]++;
8+
b[0]++;
9+
b[0]+=5;
10+
System.out.println((int) (b[0] % 0xFF));
11+
}
12+
}

0 commit comments

Comments
 (0)