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) 2012 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.DBIDs; 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.AbstractMTree; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTree; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MetricalIndexKNNQuery; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MetricalIndexRangeQuery; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MkTreeRKNNQuery; import de.lmu.ifi.dbs.elki.persistent.PageFile; import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages; /** * 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 distanceQuery Distance query * @param distanceFunction Distance function * @param k_max Maximum value of k supported * @param p Parameter p * @param log Logspace flag */ public MkAppTreeIndex(Relation relation, PageFile> pageFile, DistanceQuery distanceQuery, DistanceFunction distanceFunction, int k_max, int p, boolean log) { super(pageFile, distanceQuery, distanceFunction, k_max, p, log); this.relation = relation; this.initialize(); } /** * 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, D parentDistance) { return new MkAppLeafEntry(id, parentDistance, null); } @Override public void insert(DBID id) { throw new UnsupportedOperationException("Insertion of single objects is not supported!"); } @Override public void insertAll(DBIDs ids) { List> objs = new ArrayList>(ids.size()); for(DBID id : ids) { final O object = relation.get(id); objs.add(createNewLeafEntry(id, object, getDistanceFactory().undefinedDistance())); } insertAll(objs); } /** * Throws an UnsupportedOperationException since deletion of objects is not * yet supported by an M-Tree. * * @throws UnsupportedOperationException thrown, since deletions aren't * implemented yet. */ @Override public final boolean delete(DBID id) { throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET); } /** * Throws an UnsupportedOperationException since deletion of objects is not * yet supported by an M-Tree. * * @throws UnsupportedOperationException thrown, since deletions aren't * implemented yet. */ @Override public void deleteAll(DBIDs ids) { throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET); } @SuppressWarnings("unchecked") @Override public > KNNQuery getKNNQuery(DistanceQuery distanceQuery, Object... hints) { // Query on the relation we index if(distanceQuery.getRelation() != relation) { return null; } DistanceFunction distanceFunction = distanceQuery.getDistanceFunction(); if(!this.distanceFunction.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; } } AbstractMTree idx = (AbstractMTree) this; DistanceQuery dq = distanceFunction.instantiate(relation); return new MetricalIndexKNNQuery(idx, dq); } @SuppressWarnings("unchecked") @Override public > RangeQuery getRangeQuery(DistanceQuery distanceQuery, Object... hints) { // Query on the relation we index if(distanceQuery.getRelation() != relation) { return null; } DistanceFunction distanceFunction = distanceQuery.getDistanceFunction(); if(!this.distanceFunction.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; } } AbstractMTree idx = (AbstractMTree) this; DistanceQuery dq = distanceFunction.instantiate(relation); return new MetricalIndexRangeQuery(idx, dq); } @SuppressWarnings("unchecked") @Override public > RKNNQuery getRKNNQuery(DistanceQuery distanceQuery, Object... hints) { 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; } } AbstractMkTree idx = (AbstractMkTree) this; DistanceQuery dq = distanceFunction.instantiate(relation); return new MkTreeRKNNQuery(idx, dq); } @Override public String getLongName() { return "MkApp-Tree"; } @Override public String getShortName() { return "mkapptree"; } }