Skip to content

Commit

Permalink
Fixed ClassCastException, see #40
Browse files Browse the repository at this point in the history
  • Loading branch information
tzaeschke committed Jan 23, 2025
1 parent d3033b3 commit bb2c2e8
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 267 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

## Unreleased

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

## 2.8.0 - 2023-07-29

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/ch/ethz/globis/phtree/PhDistanceL.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public double dist(long[] v1, long[] v2) {
// would be absolutely precise and unlikely to overflow.
//The dl*dl can be done as 'double', which is always safe.
for (int i = 0; i < v1.length; i++) {
//double dl = (double)v1[i] - (double)v2[i];
long dl = Math.subtractExact(v1[i], v2[i]);
d += Math.multiplyExact(dl, dl);
// double dl = Math.subtractExact(v1[i], v2[i]);
// d += dl*dl;
double dl = (double)v1[i] - (double)v2[i];
// long dl = Math.subtractExact(v1[i], v2[i]);
// d += Math.multiplyExact(dl, dl);
// double dl = Math.subtractExact(v1[i], v2[i]);
d += dl*dl;
}
return Math.sqrt(d);
}
Expand Down
5 changes: 0 additions & 5 deletions src/main/java/ch/ethz/globis/phtree/util/Refs.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,6 @@ public static <T> T[] read(ObjectInput in) throws IOException {
return ret;
}

@SuppressWarnings("unchecked")
public static <T> T[] newArray(int size) {
return (T[]) new Object[size];
}

@SuppressWarnings("unchecked")
public static <T> T[] newArray(Class<T> c, int size) {
return (T[]) Array.newInstance(c, size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import ch.ethz.globis.phtree.PhFilterDistance;
import ch.ethz.globis.phtree.PhTree.PhExtent;
import ch.ethz.globis.phtree.PhTree.PhKnnQuery;
import ch.ethz.globis.phtree.util.Refs;

import java.util.Arrays;
import java.util.NoSuchElementException;
Expand Down Expand Up @@ -304,7 +305,7 @@ void reset(int newSize, long[] center) {
this.center = center;
maxDistance = Double.MAX_VALUE;
if (data == null) {
data = (PhEntryDist[]) new Object[newSize];
data = Refs.newArray(PhEntryDist.class, newSize);
distData = new double[newSize];
for (int i = 0; i < data.length; i++) {
data[i] = createEntry();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;

import ch.ethz.globis.phtree.PhEntry;
import ch.ethz.globis.phtree.util.Refs;
import ch.ethz.globis.phtree.v16hd.Node.BSTEntry;
import ch.ethz.globis.phtree.v16hd.bst.BSTIteratorMask;

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

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


Expand Down
2 changes: 1 addition & 1 deletion src/main/java/ch/ethz/globis/phtree/v8/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private static final boolean NI_THRESHOLD(int subCnt, int postCnt) {
protected Node(Node<T> original, int dim) {
if (original.subNRef != null) {
int size = original.subNRef.length;
this.subNRef = (Node[]) new Object[size];
this.subNRef = Refs.newArray(Node.class, size);
System.arraycopy(original.subNRef, 0, this.subNRef, 0, size);
}
if (original.values != null) {
Expand Down
98 changes: 98 additions & 0 deletions src/test/java/ch/ethz/globis/phtree/hd/TestHighDimensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
import static org.junit.Assert.assertTrue;

import java.util.Iterator;
import java.util.List;
import java.util.Random;

import ch.ethz.globis.phtree.PhEntry;
import ch.ethz.globis.phtree.PhEntryDist;
import org.junit.Test;

import ch.ethz.globis.phtree.PhTree;
Expand All @@ -34,6 +37,9 @@ public class TestHighDimensions {
private PhTree<long[]> create(int dim) {
return TestUtil.newTreeHD(dim);
}
private PhTree<Integer> createInt(int dim) {
return TestUtil.newTreeHD(dim);
}

@Test
public void testHighD64Neg() {
Expand Down Expand Up @@ -248,4 +254,96 @@ public void testQueryHighD64Neg() {
assertTrue(n2 < n);
}
}

@Test
public void smokeTest() {
final int N = 1000;
for (int DIM : DIMS) {
smokeTest(N, DIM, 0);
}
}

private void smokeTest(int N, int DIM, long SEED) {
Random R = new Random(SEED);
PhTree<Integer> ind = createInt(DIM);
long[][] keys = new long[N][DIM];
for (int i = 0; i < N; i++) {
for (int d = 0; d < DIM; d++) {
keys[i][d] = R.nextInt(); //INT!
}
if (ind.contains(keys[i])) {
i--;
continue;
}
//build
assertNull(ind.put(keys[i], i));
//System.out.println("key=" + Bits.toBinary(keys[i], 64));
//System.out.println(ind);
assertTrue("i="+ i, ind.contains(keys[i]));
assertEquals(i, (int)ind.get(keys[i]));
}


//first check
for (int i = 0; i < N; i++) {
assertTrue(ind.contains(keys[i]));
assertEquals(i, (int)ind.get(keys[i]));
}

//update
for (int i = 0; i < N; i++) {
assertEquals(i, (int)ind.put(keys[i], -i));
assertTrue(ind.contains(keys[i]));
assertEquals(-i, (int)ind.get(keys[i]));
}

//check again
for (int i = 0; i < N; i++) {
assertTrue(ind.contains(keys[i]));
assertEquals(-i, (int)ind.get(keys[i]));
}

// query
for (int i = 0; i < N; i++) {
PhTree.PhQuery<Integer> q = ind.query(keys[i], keys[i]);
assertTrue(q.hasNext());
assertEquals(-i, (int)q.next());
assertFalse(q.hasNext());
}

// query all
for (int i = 0; i < N; i++) {
List<PhEntry<Integer>> q = ind.queryAll(keys[i], keys[i]);
assertEquals(1, q.size());
assertEquals(-i, (int)q.get(0).getValue());
}

// extent
PhTree.PhExtent<Integer> extent = ind.queryExtent();
int nExtent = 0;
while (extent.hasNext()) {
extent.next();
nExtent++;
}

// query kNN
for (int i = 0; i < N; i++) {
PhTree.PhKnnQuery<Integer> q = ind.nearestNeighbour(1, keys[i]);
assertTrue(q.hasNext());
PhEntryDist<Integer> e = q.nextEntryReuse();
assertEquals(-i, (int)e.getValue());
assertEquals(0, e.dist(), 0);
}

//delete
for (int i = 0; i < N; i++) {
//System.out.println("Removing: " + Bits.toBinary(keys[i], 64));
//System.out.println("Tree: \n" + ind);
assertEquals(-i, (int)ind.remove(keys[i]));
assertFalse(ind.contains(keys[i]));
assertNull(ind.get(keys[i]));
}

assertEquals(0, ind.size());
}
}
Loading

0 comments on commit bb2c2e8

Please sign in to comment.