use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class EuclideanRStarTreeRangeQuery method getRangeForObject.
@Override
public void getRangeForObject(O object, double range, ModifiableDoubleDBIDList result) {
tree.statistics.countRangeQuery();
final double sqepsilon = range * range;
// Processing queue.
int[] pq = new int[101];
int ps = 0;
pq[ps++] = tree.getRootID();
// search in tree
while (ps > 0) {
// Pop last.
int pqNode = pq[--ps];
AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode);
final int numEntries = node.getNumEntries();
if (node.isLeaf()) {
for (int i = 0; i < numEntries; i++) {
SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
double distance = SQUARED.minDist(object, entry);
tree.statistics.countDistanceCalculation();
if (distance <= sqepsilon) {
result.add(FastMath.sqrt(distance), entry.getDBID());
}
}
} else {
for (int i = 0; i < numEntries; i++) {
SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
double distance = SQUARED.minDist(object, entry);
if (distance <= sqepsilon) {
if (ps == pq.length) {
// Resize:
pq = Arrays.copyOf(pq, pq.length + (pq.length >>> 1));
}
pq[ps++] = entry.getPageID();
}
}
}
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class RStarTreeRangeQuery method getRangeForObject.
@Override
public void getRangeForObject(O obj, double range, ModifiableDoubleDBIDList result) {
tree.statistics.countRangeQuery();
// Processing queue.
int[] pq = new int[101];
int ps = 0;
pq[ps++] = tree.getRootID();
// search in tree
while (ps > 0) {
// Pop last.
int pqNode = pq[--ps];
AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode);
final int numEntries = node.getNumEntries();
if (node.isLeaf()) {
for (int i = 0; i < numEntries; i++) {
SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
double distance = distanceFunction.minDist(obj, entry);
tree.statistics.countDistanceCalculation();
if (distance <= range) {
result.add(distance, entry.getDBID());
}
}
} else {
for (int i = 0; i < numEntries; i++) {
SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
double distance = distanceFunction.minDist(obj, entry);
if (distance <= range) {
if (ps == pq.length) {
pq = Arrays.copyOf(pq, pq.length + (pq.length >>> 1));
}
pq[ps++] = entry.getPageID();
}
}
}
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class AbstractRStarTree method initializeCapacities.
@Override
protected void initializeCapacities(E exampleLeaf) {
/* Simulate the creation of a leaf page to get the page capacity */
try {
int cap = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
SpatialPointLeafEntry sl = new SpatialPointLeafEntry(DBIDUtil.importInteger(0), new double[exampleLeaf.getDimensionality()]);
while (baos.size() <= getPageSize()) {
sl.writeExternal(oos);
oos.flush();
cap++;
}
// the last one caused the page to overflow.
leafCapacity = cap - 1;
} catch (IOException e) {
throw new AbortException("Error determining page sizes.", e);
}
/* Simulate the creation of a directory page to get the capacity */
try {
int cap = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
ModifiableHyperBoundingBox hb = new ModifiableHyperBoundingBox(new double[exampleLeaf.getDimensionality()], new double[exampleLeaf.getDimensionality()]);
SpatialDirectoryEntry sl = new SpatialDirectoryEntry(0, hb);
while (baos.size() <= getPageSize()) {
sl.writeExternal(oos);
oos.flush();
cap++;
}
dirCapacity = cap - 1;
} catch (IOException e) {
throw new AbortException("Error determining page sizes.", e);
}
if (dirCapacity <= 2) {
throw new IllegalArgumentException("Node size of " + getPageSize() + " bytes is chosen too small!");
}
final Logging log = getLogger();
if (dirCapacity < 10) {
log.warning("Page size is choosen very small! Maximum number of entries in a directory node = " + dirCapacity);
}
// minimum entries per directory node
dirMinimum = (int) Math.floor(dirCapacity * settings.relativeMinFill);
if (dirMinimum < 1) {
dirMinimum = 1;
}
if (leafCapacity <= 2) {
throw new IllegalArgumentException("Node size of " + getPageSize() + " bytes is chosen too small!");
}
if (leafCapacity < 10) {
log.warning("Page size is choosen very small! Maximum number of entries in a leaf node = " + leafCapacity);
}
// minimum entries per leaf node
leafMinimum = (int) Math.floor(leafCapacity * settings.relativeMinFill);
if (leafMinimum < 1) {
leafMinimum = 1;
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class AbstractRStarTreeNode method adjustEntry.
/**
* Adjusts the parameters of the entry representing this node.
*
* @param entry the entry representing this node
*/
public boolean adjustEntry(E entry) {
final SpatialDirectoryEntry se = (SpatialDirectoryEntry) entry;
final ModifiableHyperBoundingBox mbr = computeMBR();
boolean changed = false;
if (se.hasMBR()) {
final int dim = se.getDimensionality();
// Test for changes
for (int i = 0; i < dim; i++) {
if (Math.abs(se.getMin(i) - mbr.getMin(i)) > Float.MIN_NORMAL) {
changed = true;
break;
}
if (Math.abs(se.getMax(i) - mbr.getMax(i)) > Float.MIN_NORMAL) {
changed = true;
break;
}
}
} else {
// No preexisting MBR.
changed = true;
}
if (changed) {
se.setMBR(mbr);
}
return changed;
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class AbstractRStarTreeNode method readExternal.
/**
* Reads the id of this node, the numEntries and the entries array from the
* specified stream.
*
* @param in the stream to read data from in order to restore the object
* @throws java.io.IOException if I/O errors occur
* @throws ClassNotFoundException If the class for an object being restored
* cannot be found.
*/
@Override
@SuppressWarnings("unchecked")
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
// TODO: do we need to write/read the capacity?
final int capacity = in.readInt();
if (isLeaf()) {
entries = (E[]) new SpatialPointLeafEntry[capacity];
for (int i = 0; i < numEntries; i++) {
SpatialPointLeafEntry s = new SpatialPointLeafEntry();
s.readExternal(in);
entries[i] = (E) s;
}
} else {
entries = (E[]) new SpatialDirectoryEntry[capacity];
for (int i = 0; i < numEntries; i++) {
SpatialDirectoryEntry s = new SpatialDirectoryEntry();
s.readExternal(in);
entries[i] = (E) s;
}
}
}
Aggregations