* @param knnLists a map containing the knn lists for each query objects
*/
protected void batchNN(AbstractRStarTreeNode<?, ?> node, Map<DBID, KNNHeap<DoubleDistance>> knnLists) {
if(node.isLeaf()) {
for(int i = 0; i < node.getNumEntries(); i++) {
SpatialEntry p = node.getEntry(i);
for(Entry<DBID, KNNHeap<DoubleDistance>> ent : knnLists.entrySet()) {
final DBID q = ent.getKey();
final KNNHeap<DoubleDistance> knns_q = ent.getValue();
DoubleDistance knn_q_maxDist = knns_q.getKNNDistance();
DBID pid = ((LeafEntry) p).getDBID();
// FIXME: objects are NOT accessible by DBID in a plain rtree context!
DoubleDistance dist_pq = distanceFunction.distance(relation.get(pid), relation.get(q));
tree.distanceCalcs++;
if(dist_pq.compareTo(knn_q_maxDist) <= 0) {
knns_q.add(dist_pq, pid);
}
}
}
}
else {
ModifiableDBIDs ids = DBIDUtil.newArray(knnLists.size());
for(DBID id : knnLists.keySet()) {
ids.add(id);
}
List<DoubleDistanceEntry> entries = getSortedEntries(node, ids);
for(DoubleDistanceEntry distEntry : entries) {
double minDist = distEntry.distance;
for(Entry<DBID, KNNHeap<DoubleDistance>> ent : knnLists.entrySet()) {
final KNNHeap<DoubleDistance> knns_q = ent.getValue();
double knn_q_maxDist = knns_q.getKNNDistance().doubleValue();
if(minDist <= knn_q_maxDist) {
SpatialEntry entry = distEntry.entry;
AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry) entry).getPageID());
batchNN(child, knnLists);
break;
}
}