All Downloads are FREE. Search and download functionalities are using the official Maven repository.

graphql.schema.diffing.EditorialCostForMapping Maven / Gradle / Ivy

There is a newer version: 230521-nf-execution
Show newest version
package graphql.schema.diffing;

import graphql.Internal;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

@Internal
public class EditorialCostForMapping {
    /**
     * @param mapping     the mapping
     * @param sourceGraph the source graph
     * @param targetGraph the target graph
     *
     * @return the editorial cost
     *
     * @see #baseEditorialCostForMapping(Mapping, SchemaGraph, SchemaGraph, List)
     */
    public static int baseEditorialCostForMapping(Mapping mapping, // can be a partial mapping
                                                  SchemaGraph sourceGraph, // the whole graph
                                                  SchemaGraph targetGraph // the whole graph
    ) {
        return baseEditorialCostForMapping(mapping, sourceGraph, targetGraph, new ArrayList<>());
    }

    /**
     * Gets the "editorial cost for mapping" for the base mapping.
     * 

* Use this is as base cost when invoking * {@link #editorialCostForMapping(int, Mapping, SchemaGraph, SchemaGraph)} * as it heavily speeds up performance. * * @param mapping the mapping * @param sourceGraph the source graph * @param targetGraph the target graph * @param editOperationsResult the list of edit operations * * @return the editorial cost */ public static int baseEditorialCostForMapping(Mapping mapping, // can be a partial mapping SchemaGraph sourceGraph, // the whole graph SchemaGraph targetGraph, // the whole graph List editOperationsResult) { int cost = 0; for (int i = 0; i < mapping.size(); i++) { Vertex sourceVertex = mapping.getSource(i); Vertex targetVertex = mapping.getTarget(i); // Vertex changing (relabeling) boolean equalNodes = sourceVertex.getType().equals(targetVertex.getType()) && sourceVertex.getProperties().equals(targetVertex.getProperties()); if (!equalNodes) { if (sourceVertex.isIsolated()) { editOperationsResult.add(EditOperation.insertVertex("Insert" + targetVertex, sourceVertex, targetVertex)); } else if (targetVertex.isIsolated()) { editOperationsResult.add(EditOperation.deleteVertex("Delete " + sourceVertex, sourceVertex, targetVertex)); } else { editOperationsResult.add(EditOperation.changeVertex("Change " + sourceVertex + " to " + targetVertex, sourceVertex, targetVertex)); } cost++; } } // edge deletion or relabeling for (Edge sourceEdge : sourceGraph.getEdges()) { // only edges relevant to the subgraph if (!mapping.containsSource(sourceEdge.getFrom()) || !mapping.containsSource(sourceEdge.getTo())) { continue; } Vertex targetFrom = mapping.getTarget(sourceEdge.getFrom()); Vertex targetTo = mapping.getTarget(sourceEdge.getTo()); Edge targetEdge = targetGraph.getEdge(targetFrom, targetTo); if (targetEdge == null) { editOperationsResult.add(EditOperation.deleteEdge("Delete edge " + sourceEdge, sourceEdge)); cost++; } else if (!sourceEdge.getLabel().equals(targetEdge.getLabel())) { editOperationsResult.add(EditOperation.changeEdge("Change " + sourceEdge + " to " + targetEdge, sourceEdge, targetEdge)); cost++; } } for (Edge targetEdge : targetGraph.getEdges()) { // only subgraph edges if (!mapping.containsTarget(targetEdge.getFrom()) || !mapping.containsTarget(targetEdge.getTo())) { continue; } Vertex sourceFrom = mapping.getSource(targetEdge.getFrom()); Vertex sourceTo = mapping.getSource(targetEdge.getTo()); if (sourceGraph.getEdge(sourceFrom, sourceTo) == null) { editOperationsResult.add(EditOperation.insertEdge("Insert edge " + targetEdge, targetEdge)); cost++; } } return cost; } /** * Calculates the "editorial cost for mapping" for the non-fixed targets in a {@link Mapping}. *

* The {@code baseCost} argument should be the cost for the fixed mapping from * {@link #baseEditorialCostForMapping(Mapping, SchemaGraph, SchemaGraph)}. *

* The sum of the non-fixed costs and the fixed costs is total editorial cost for mapping. * * @param baseCost the starting base cost * @param mapping the mapping * @param sourceGraph the source graph * @param targetGraph the target graph * * @return the editorial cost */ public static int editorialCostForMapping(int baseCost, Mapping mapping, // can be a partial mapping SchemaGraph sourceGraph, // the whole graph SchemaGraph targetGraph // the whole graph ) { AtomicInteger cost = new AtomicInteger(baseCost); Set seenEdges = new LinkedHashSet<>(); // Tells us whether the edge should be visited. We need to avoid counting edges more than once Predicate visitEdge = (data) -> { if (seenEdges.contains(data)) { return false; } else { seenEdges.add(data); return true; } }; // Look through mapping.forEachNonFixedSourceAndTarget((sourceVertex, targetVertex) -> { // Vertex changing (relabeling) boolean equalNodes = sourceVertex.getType().equals(targetVertex.getType()) && sourceVertex.getProperties().equals(targetVertex.getProperties()); if (!equalNodes) { cost.getAndIncrement(); } for (Edge sourceEdge : sourceGraph.getAdjacentEdgesAndInverseNonCopy(sourceVertex)) { if (!visitEdge.test(sourceEdge)) { continue; } // only edges relevant to the subgraph if (!mapping.containsSource(sourceEdge.getFrom()) || !mapping.containsSource(sourceEdge.getTo())) { continue; } Vertex targetFrom = mapping.getTarget(sourceEdge.getFrom()); Vertex targetTo = mapping.getTarget(sourceEdge.getTo()); Edge targetEdge = targetGraph.getEdge(targetFrom, targetTo); if (targetEdge == null) { cost.getAndIncrement(); } else if (!sourceEdge.getLabel().equals(targetEdge.getLabel())) { cost.getAndIncrement(); } } for (Edge targetEdge : targetGraph.getAdjacentEdgesAndInverseNonCopy(targetVertex)) { if (!visitEdge.test(targetEdge)) { continue; } // only edges relevant to the subgraph if (!mapping.containsTarget(targetEdge.getFrom()) || !mapping.containsTarget(targetEdge.getTo())) { continue; } Vertex sourceFrom = mapping.getSource(targetEdge.getFrom()); Vertex sourceTo = mapping.getSource(targetEdge.getTo()); Edge sourceEdge = sourceGraph.getEdge(sourceFrom, sourceTo); if (sourceEdge == null) { cost.getAndIncrement(); } } }); return cost.get(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy