Skip to content

Commit bb2c2e8

Browse files
committed
Fixed ClassCastException, see #40
1 parent d3033b3 commit bb2c2e8

File tree

9 files changed

+112
-267
lines changed

9 files changed

+112
-267
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
## Unreleased
44

5+
- Fixed ClassCastExceptionin HD tree.
6+
[#40](https://github.com/tzaeschke/phtree/pull/40)
57
- getStats() for empty trees fails. [#36](https://github.com/tzaeschke/phtree/pull/36)
68
- Fix some warnings. [#37](https://github.com/tzaeschke/phtree/pull/37)
7-
- UPdated some dependencies. [#38](https://github.com/tzaeschke/phtree/pull/38)
9+
- Updated some dependencies. [#38](https://github.com/tzaeschke/phtree/pull/38)
810

911
## 2.8.0 - 2023-07-29
1012

src/main/java/ch/ethz/globis/phtree/PhDistanceL.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ public double dist(long[] v1, long[] v2) {
3737
// would be absolutely precise and unlikely to overflow.
3838
//The dl*dl can be done as 'double', which is always safe.
3939
for (int i = 0; i < v1.length; i++) {
40-
//double dl = (double)v1[i] - (double)v2[i];
41-
long dl = Math.subtractExact(v1[i], v2[i]);
42-
d += Math.multiplyExact(dl, dl);
43-
// double dl = Math.subtractExact(v1[i], v2[i]);
44-
// d += dl*dl;
40+
double dl = (double)v1[i] - (double)v2[i];
41+
// long dl = Math.subtractExact(v1[i], v2[i]);
42+
// d += Math.multiplyExact(dl, dl);
43+
// double dl = Math.subtractExact(v1[i], v2[i]);
44+
d += dl*dl;
4545
}
4646
return Math.sqrt(d);
4747
}

src/main/java/ch/ethz/globis/phtree/util/Refs.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,6 @@ public static <T> T[] read(ObjectInput in) throws IOException {
302302
return ret;
303303
}
304304

305-
@SuppressWarnings("unchecked")
306-
public static <T> T[] newArray(int size) {
307-
return (T[]) new Object[size];
308-
}
309-
310305
@SuppressWarnings("unchecked")
311306
public static <T> T[] newArray(Class<T> c, int size) {
312307
return (T[]) Array.newInstance(c, size);

src/main/java/ch/ethz/globis/phtree/v13SynchedPool/PhQueryKnnMbbPPList.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import ch.ethz.globis.phtree.PhFilterDistance;
1515
import ch.ethz.globis.phtree.PhTree.PhExtent;
1616
import ch.ethz.globis.phtree.PhTree.PhKnnQuery;
17+
import ch.ethz.globis.phtree.util.Refs;
1718

1819
import java.util.Arrays;
1920
import java.util.NoSuchElementException;
@@ -304,7 +305,7 @@ void reset(int newSize, long[] center) {
304305
this.center = center;
305306
maxDistance = Double.MAX_VALUE;
306307
if (data == null) {
307-
data = (PhEntryDist[]) new Object[newSize];
308+
data = Refs.newArray(PhEntryDist.class, newSize);
308309
distData = new double[newSize];
309310
for (int i = 0; i < data.length; i++) {
310311
data[i] = createEntry();

src/main/java/ch/ethz/globis/phtree/v16hd/NodeIteratorListReuse.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.List;
2222

2323
import ch.ethz.globis.phtree.PhEntry;
24+
import ch.ethz.globis.phtree.util.Refs;
2425
import ch.ethz.globis.phtree.v16hd.Node.BSTEntry;
2526
import ch.ethz.globis.phtree.v16hd.bst.BSTIteratorMask;
2627

@@ -41,8 +42,7 @@
4142
public class NodeIteratorListReuse<T, R> {
4243

4344
private class PhIteratorStack {
44-
@SuppressWarnings("unchecked")
45-
private final NodeIterator[] stack = (NodeIteratorListReuse.NodeIterator[]) new Object[64];
45+
private final NodeIterator[] stack = Refs.newArray(NodeIteratorListReuse.NodeIterator.class, 64);
4646
private int size = 0;
4747

4848

src/main/java/ch/ethz/globis/phtree/v8/Node.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private static final boolean NI_THRESHOLD(int subCnt, int postCnt) {
7878
protected Node(Node<T> original, int dim) {
7979
if (original.subNRef != null) {
8080
int size = original.subNRef.length;
81-
this.subNRef = (Node[]) new Object[size];
81+
this.subNRef = Refs.newArray(Node.class, size);
8282
System.arraycopy(original.subNRef, 0, this.subNRef, 0, size);
8383
}
8484
if (original.values != null) {

src/test/java/ch/ethz/globis/phtree/hd/TestHighDimensions.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
import static org.junit.Assert.assertTrue;
1414

1515
import java.util.Iterator;
16+
import java.util.List;
1617
import java.util.Random;
1718

19+
import ch.ethz.globis.phtree.PhEntry;
20+
import ch.ethz.globis.phtree.PhEntryDist;
1821
import org.junit.Test;
1922

2023
import ch.ethz.globis.phtree.PhTree;
@@ -34,6 +37,9 @@ public class TestHighDimensions {
3437
private PhTree<long[]> create(int dim) {
3538
return TestUtil.newTreeHD(dim);
3639
}
40+
private PhTree<Integer> createInt(int dim) {
41+
return TestUtil.newTreeHD(dim);
42+
}
3743

3844
@Test
3945
public void testHighD64Neg() {
@@ -248,4 +254,96 @@ public void testQueryHighD64Neg() {
248254
assertTrue(n2 < n);
249255
}
250256
}
257+
258+
@Test
259+
public void smokeTest() {
260+
final int N = 1000;
261+
for (int DIM : DIMS) {
262+
smokeTest(N, DIM, 0);
263+
}
264+
}
265+
266+
private void smokeTest(int N, int DIM, long SEED) {
267+
Random R = new Random(SEED);
268+
PhTree<Integer> ind = createInt(DIM);
269+
long[][] keys = new long[N][DIM];
270+
for (int i = 0; i < N; i++) {
271+
for (int d = 0; d < DIM; d++) {
272+
keys[i][d] = R.nextInt(); //INT!
273+
}
274+
if (ind.contains(keys[i])) {
275+
i--;
276+
continue;
277+
}
278+
//build
279+
assertNull(ind.put(keys[i], i));
280+
//System.out.println("key=" + Bits.toBinary(keys[i], 64));
281+
//System.out.println(ind);
282+
assertTrue("i="+ i, ind.contains(keys[i]));
283+
assertEquals(i, (int)ind.get(keys[i]));
284+
}
285+
286+
287+
//first check
288+
for (int i = 0; i < N; i++) {
289+
assertTrue(ind.contains(keys[i]));
290+
assertEquals(i, (int)ind.get(keys[i]));
291+
}
292+
293+
//update
294+
for (int i = 0; i < N; i++) {
295+
assertEquals(i, (int)ind.put(keys[i], -i));
296+
assertTrue(ind.contains(keys[i]));
297+
assertEquals(-i, (int)ind.get(keys[i]));
298+
}
299+
300+
//check again
301+
for (int i = 0; i < N; i++) {
302+
assertTrue(ind.contains(keys[i]));
303+
assertEquals(-i, (int)ind.get(keys[i]));
304+
}
305+
306+
// query
307+
for (int i = 0; i < N; i++) {
308+
PhTree.PhQuery<Integer> q = ind.query(keys[i], keys[i]);
309+
assertTrue(q.hasNext());
310+
assertEquals(-i, (int)q.next());
311+
assertFalse(q.hasNext());
312+
}
313+
314+
// query all
315+
for (int i = 0; i < N; i++) {
316+
List<PhEntry<Integer>> q = ind.queryAll(keys[i], keys[i]);
317+
assertEquals(1, q.size());
318+
assertEquals(-i, (int)q.get(0).getValue());
319+
}
320+
321+
// extent
322+
PhTree.PhExtent<Integer> extent = ind.queryExtent();
323+
int nExtent = 0;
324+
while (extent.hasNext()) {
325+
extent.next();
326+
nExtent++;
327+
}
328+
329+
// query kNN
330+
for (int i = 0; i < N; i++) {
331+
PhTree.PhKnnQuery<Integer> q = ind.nearestNeighbour(1, keys[i]);
332+
assertTrue(q.hasNext());
333+
PhEntryDist<Integer> e = q.nextEntryReuse();
334+
assertEquals(-i, (int)e.getValue());
335+
assertEquals(0, e.dist(), 0);
336+
}
337+
338+
//delete
339+
for (int i = 0; i < N; i++) {
340+
//System.out.println("Removing: " + Bits.toBinary(keys[i], 64));
341+
//System.out.println("Tree: \n" + ind);
342+
assertEquals(-i, (int)ind.remove(keys[i]));
343+
assertFalse(ind.contains(keys[i]));
344+
assertNull(ind.get(keys[i]));
345+
}
346+
347+
assertEquals(0, ind.size());
348+
}
251349
}

0 commit comments

Comments
 (0)