package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import java.util.ArrayList; import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery; import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.index.KNNIndex; import de.lmu.ifi.dbs.elki.index.RKNNIndex; import de.lmu.ifi.dbs.elki.index.RangeIndex; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeQueryUtil; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MkTreeRKNNQuery; import de.lmu.ifi.dbs.elki.persistent.PageFile; /** * MkAppTree used as database index. * * @author Erich Schubert * * @param Object type * @param Distance type */ public class MkAppTreeIndex> extends MkAppTree implements RangeIndex, KNNIndex, RKNNIndex { /** * The relation indexed */ private Relation relation; /** * Constructor. * * @param relation Relation to index * @param pageFile Page file * @param settings Tree settings */ public MkAppTreeIndex(Relation relation, PageFile> pageFile, MkAppTreeSettings settings) { super(relation, pageFile, settings); this.relation = relation; } /** * Creates a new leaf entry representing the specified data object in the * specified subtree. * * @param object the data object to be represented by the new entry * @param parentDistance the distance from the object to the routing object of * the parent node */ protected MkAppEntry createNewLeafEntry(DBID id, O object, double parentDistance) { return new MkAppLeafEntry(id, parentDistance, null); } @Override public void initialize() { super.initialize(); List objs = new ArrayList<>(relation.size()); for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) { DBID id = DBIDUtil.deref(iter); final O object = relation.get(id); objs.add(createNewLeafEntry(id, object, Double.NaN)); } insertAll(objs); } @SuppressWarnings("unchecked") @Override public > KNNQuery getKNNQuery(DistanceQuery distanceQuery, Object... hints) { // Query on the relation we index if (distanceQuery.getRelation() != relation) { return null; } DistanceFunction distanceFunction = (DistanceFunction) distanceQuery.getDistanceFunction(); if (!this.getDistanceFunction().equals(distanceFunction)) { if (getLogger().isDebugging()) { getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!"); } return null; } // Bulk is not yet supported for (Object hint : hints) { if (hint == DatabaseQuery.HINT_BULK) { return null; } } DistanceQuery dq = distanceFunction.instantiate(relation); return (KNNQuery) MTreeQueryUtil.getKNNQuery(this, dq, hints); } @SuppressWarnings("unchecked") @Override public > RangeQuery getRangeQuery(DistanceQuery distanceQuery, Object... hints) { // Query on the relation we index if (distanceQuery.getRelation() != relation) { return null; } DistanceFunction distanceFunction = (DistanceFunction) distanceQuery.getDistanceFunction(); if (!this.getDistanceFunction().equals(distanceFunction)) { if (getLogger().isDebugging()) { getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!"); } return null; } // Bulk is not yet supported for (Object hint : hints) { if (hint == DatabaseQuery.HINT_BULK) { return null; } } DistanceQuery dq = distanceFunction.instantiate(relation); return (RangeQuery) MTreeQueryUtil.getRangeQuery(this, dq, hints); } @SuppressWarnings("unchecked") @Override public > RKNNQuery getRKNNQuery(DistanceQuery distanceQuery, Object... hints) { DistanceFunction distanceFunction = (DistanceFunction) distanceQuery.getDistanceFunction(); if (!this.getDistanceFunction().equals(distanceFunction)) { if (getLogger().isDebugging()) { getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!"); } return null; } // Bulk is not yet supported for (Object hint : hints) { if (hint == DatabaseQuery.HINT_BULK) { return null; } } DistanceQuery dq = distanceFunction.instantiate(relation); return (RKNNQuery) new MkTreeRKNNQuery<>(this, dq); } @Override public String getLongName() { return "MkApp-Tree"; } @Override public String getShortName() { return "mkapptree"; } }