package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2015 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 de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode; /** * Represents a node in a MkMax-Tree. * * @author Elke Achtert * @since 0.2 * * @apiviz.has MkTabEntry oneway - - contains * * @param object type */ class MkTabTreeNode extends AbstractMTreeNode, MkTabEntry> { private static final long serialVersionUID = 2; /** * Empty constructor for Externalizable interface. */ public MkTabTreeNode() { // empty constructor } /** * Creates a MkTabTreeNode object. * * @param capacity the capacity (maximum number of entries plus 1 for * overflow) of this node * @param isLeaf indicates whether this node is a leaf node */ public MkTabTreeNode(int capacity, boolean isLeaf) { super(capacity, isLeaf, MkTabEntry.class); } /** * Determines and returns the knn distance of this node as the maximum knn * distance of all entries. * * @return the knn distance of this node */ protected double[] kNNDistances() { int k = getEntry(0).getKnnDistances().length; double[] result = new double[k]; for(int i = 0; i < getNumEntries(); i++) { for(int j = 0; j < k; j++) { MkTabEntry entry = getEntry(i); result[j] = Math.max(result[j], entry.getKnnDistance(j + 1)); } } return result; } @Override public boolean adjustEntry(MkTabEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree, MkTabEntry, ?> mTree) { super.adjustEntry(entry, routingObjectID, parentDistance, mTree); // adjust knn distances entry.setKnnDistances(kNNDistances()); return true; // TODO: improve } /** * Tests, if the parameters of the entry representing this node, are correctly * set. Subclasses may need to overwrite this method. * * @param parent the parent holding the entry representing this node * @param index the index of the entry in the parents child array * @param mTree the underlying M-Tree */ @Override protected void integrityCheckParameters(MkTabEntry parentEntry, MkTabTreeNode parent, int index, AbstractMTree, MkTabEntry, ?> mTree) { super.integrityCheckParameters(parentEntry, parent, index, mTree); // test knn distances MkTabEntry entry = parent.getEntry(index); double[] knnDistances = kNNDistances(); if(!entry.getKnnDistances().equals(knnDistances)) { String soll = knnDistances.toString(); String ist = entry.getKnnDistances().toString(); throw new RuntimeException("Wrong knnDistances in node " + parent.getPageID() + " at index " + index + " (child " + entry + ")" + "\nsoll: " + soll + ",\n ist: " + ist); } } }