in hyracks/hyracks-storage-am-rtree/src/main/java/org/apache/hyracks/storage/am/rtree/frames/RStarTreePolicy.java [262:358]
public int findBestChildPosition(ITreeIndexFrame frame, ITupleReference tuple, ITreeIndexTupleReference frameTuple,
MultiComparator cmp) throws HyracksDataException {
cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
frameTuple.setFieldCount(cmp.getKeyFieldCount());
int bestChild = 0;
double minEnlargedArea = Double.MAX_VALUE;
// the children pointers in the node point to leaves
if (frame.getLevel() == 1) {
// find least overlap enlargement, use minimum enlarged area to
// break tie, if tie still exists use minimum area to break it
for (int i = 0; i < frame.getTupleCount(); ++i) {
frameTuple.resetByTupleIndex(frame, i);
double enlargedArea = RTreeComputationUtils.enlargedArea(frameTuple, tuple, cmp, keyValueProviders);
tupleEntries1.add(i, enlargedArea);
if (enlargedArea < minEnlargedArea) {
minEnlargedArea = enlargedArea;
bestChild = i;
}
}
if (minEnlargedArea < RTreeNSMFrame.doubleEpsilon() || minEnlargedArea > RTreeNSMFrame.doubleEpsilon()) {
minEnlargedArea = Double.MAX_VALUE;
int k;
if (frame.getTupleCount() > nearMinimumOverlapFactor) {
// sort the entries based on their area enlargement needed
// to include the object
tupleEntries1.sort(EntriesOrder.ASCENDING, frame.getTupleCount());
k = nearMinimumOverlapFactor;
} else {
k = frame.getTupleCount();
}
double minOverlap = Double.MAX_VALUE;
int id = 0;
for (int i = 0; i < k; ++i) {
double difference = 0.0;
for (int j = 0; j < frame.getTupleCount(); ++j) {
frameTuple.resetByTupleIndex(frame, j);
cmpFrameTuple.resetByTupleIndex(frame, tupleEntries1.get(i).getTupleIndex());
int c = ((RTreeNSMInteriorFrame) frame).pointerCmp(frameTuple, cmpFrameTuple, cmp);
if (c != 0) {
double intersection = RTreeComputationUtils.overlappedArea(frameTuple, tuple,
cmpFrameTuple, cmp, keyValueProviders);
if (intersection != 0.0) {
difference += intersection
- RTreeComputationUtils.overlappedArea(frameTuple, null, cmpFrameTuple, cmp,
keyValueProviders);
}
} else {
id = j;
}
}
double enlargedArea = RTreeComputationUtils.enlargedArea(cmpFrameTuple, tuple, cmp,
keyValueProviders);
if (difference < minOverlap) {
minOverlap = difference;
minEnlargedArea = enlargedArea;
bestChild = id;
} else if (difference == minOverlap) {
if (enlargedArea < minEnlargedArea) {
minEnlargedArea = enlargedArea;
bestChild = id;
} else if (enlargedArea == minEnlargedArea) {
double area = RTreeComputationUtils.area(cmpFrameTuple, cmp, keyValueProviders);
frameTuple.resetByTupleIndex(frame, bestChild);
double minArea = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
if (area < minArea) {
bestChild = id;
}
}
}
}
}
} else { // find minimum enlarged area, use minimum area to break tie
for (int i = 0; i < frame.getTupleCount(); i++) {
frameTuple.resetByTupleIndex(frame, i);
double enlargedArea = RTreeComputationUtils.enlargedArea(frameTuple, tuple, cmp, keyValueProviders);
if (enlargedArea < minEnlargedArea) {
minEnlargedArea = enlargedArea;
bestChild = i;
} else if (enlargedArea == minEnlargedArea) {
double area = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
frameTuple.resetByTupleIndex(frame, bestChild);
double minArea = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
if (area < minArea) {
bestChild = i;
}
}
}
}
tupleEntries1.clear();
return bestChild;
}