package mhtree; import cz.muni.fi.disa.similarityoperators.cover.AbstractRepresentation.PrecomputedDistances; import messif.objects.LocalAbstractObject; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; /** * Represents an internal node in MH-Tree. */ class InternalNode extends Node implements Serializable { /** * Serialization ID */ private static final long serialVersionUID = 2L; private final List<Node> children; protected InternalNode(PrecomputedDistances distances, InsertType insertType, ObjectToNodeDistance objectToNodeDistance, List<Node> children) { super(distances, insertType, objectToNodeDistance); this.children = children; } /** * Returns the list of child nodes. * * @return the list of child nodes */ protected List<Node> getChildren() { return children; } /** * Returns the nearest child to the {@code object}. * * @param object object to which the distance is measured * @return the nearest child to the {@code object} */ protected Node getNearestChild(LocalAbstractObject object) { Node nearestChild = children.get(0); double minDistance = nearestChild.getDistance(object); for (int i = 1; i < children.size(); i++) { double distance = children.get(i).getDistance(object); if (distance < minDistance) { minDistance = distance; nearestChild = children.get(i); } } return nearestChild; } /** * Adds {@code object} into this node. * * @param object object to be added */ protected void addObject(LocalAbstractObject object) { addObjectIntoHull(object); } /** * Returns the list of objects stored in node's descendants. * * @return the list of objects stored in node's descendants */ protected List<LocalAbstractObject> getObjects() { return children .stream() .map(Node::getObjects) .flatMap(Collection::stream) .collect(Collectors.toList()); } /** * Returns the height of this node. * * @return the height of this node */ protected int getHeight() { return children .stream() .mapToInt(Node::getHeight) .summaryStatistics() .getMax() + 1; } /** * Adds this node and this node's descendants into {@code nodes}. * * @param nodes list of nodes */ protected void gatherNodes(List<Node> nodes) { nodes.add(this); nodes.addAll(children); } /** * Calls {@code gatherLeafNodes} on every child. * * @param leafNodes list of leaf nodes */ protected void gatherLeafNodes(List<LeafNode> leafNodes) { children.forEach(child -> child.gatherLeafNodes(leafNodes)); } }