Skip to content
Snippets Groups Projects
Node.java 4.23 KiB
Newer Older
import cz.muni.fi.disa.similarityoperators.cover.AbstractRepresentation.PrecomputedDistances;
import cz.muni.fi.disa.similarityoperators.cover.HullOptimizedRepresentationV3;
import messif.buckets.BucketStorageException;
import messif.objects.LocalAbstractObject;

import java.io.Serializable;
David Procházka's avatar
David Procházka committed
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public abstract class Node implements Serializable {
    /**
     * Serialization ID
     */
    private static final long serialVersionUID = 420L;
    private final InsertType insertType;
    private final ObjectToNodeDistance objectToNodeDistance;

    private HullOptimizedRepresentationV3 hull;
    protected Node(PrecomputedDistances distances, InsertType insertType, ObjectToNodeDistance objectToNodeDistance) {
        this.hull = new HullOptimizedRepresentationV3(distances);
        this.hull.build();
        this.insertType = insertType;
        this.objectToNodeDistance = objectToNodeDistance;
    protected static InternalNode createParent(List<Node> nodes, PrecomputedDistances distances, InsertType insertType, ObjectToNodeDistance objectToNodeDistance, MergeType mergeType) {
        List<LocalAbstractObject> objects = nodes
                .stream()
                .map(mergeType == MergeType.OBJECT_BASED ? Node::getObjects : Node::getHullObjects)
                .flatMap(Collection::stream)
        if (nodes.size() == distances.getObjectCount()) {
            return new InternalNode(distances, insertType, objectToNodeDistance, nodes);
        }

        return new InternalNode(distances.getSubset(objects), insertType, objectToNodeDistance, nodes);
    /**
     * Returns a list of hull objects.
     *
     * @return a list of hull objects
     */
    public List<LocalAbstractObject> getHullObjects() {
        return hull.getHull();
    }

    /**
     * Returns true if the {@code object} is covered.
     *
     * @param object the object to be checked
     * @return true if the {@code object} is covered.
     */
    public boolean isCovered(LocalAbstractObject object) {
        return hull.isExternalCovered(object);
    }

    @Override
    public String toString() {
        return "Node{hull=" + hull + '}';
    }

    protected double getDistance(LocalAbstractObject object) {
        return objectToNodeDistance.getDistance(object, this);
    protected double getDistance(LocalAbstractObject object, PrecomputedDistances distances) {
        return objectToNodeDistance.getDistance(object, this, distances);
    }

    protected double getDistanceToNearest(LocalAbstractObject object) {
        return ObjectToNodeDistance.NEAREST.getDistance(object, this);
        return hull.getRepresentativesCount();
    protected void addObjectIntoHull(LocalAbstractObject object) {
        if (isCovered(object)) return;

        switch (insertType) {
            case GREEDY:
                insertGreedy(object);
                break;
            case INCREMENTAL:
                insertIncremental(object);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + insertType);
        }
    }

    protected abstract void addObject(LocalAbstractObject object) throws BucketStorageException;
    protected abstract List<LocalAbstractObject> getObjects();
    protected abstract void gatherNodes(List<Node> nodes);
    protected abstract void gatherLeafNodes(List<LeafNode> leafNodes);
    private void insertGreedy(LocalAbstractObject object) {
        List<LocalAbstractObject> objectsFromLeafNodes = getObjects();
        objectsFromLeafNodes.add(object);
        hull = new HullOptimizedRepresentationV3(objectsFromLeafNodes);
        hull.build();
    }
    private void insertIncremental(LocalAbstractObject object) {
        List<LocalAbstractObject> hullObjects = hull.getHull();
        hullObjects.add(object);
        hull = new HullOptimizedRepresentationV3(hullObjects);
        hull.build();