Skip to content

Commit

Permalink
Fixes #8695
Browse files Browse the repository at this point in the history
Fixes #8825
  • Loading branch information
original-brownbear authored and andrewvc committed Dec 11, 2017
1 parent a5462f5 commit adc848d
Show file tree
Hide file tree
Showing 13 changed files with 2,154 additions and 85 deletions.
4 changes: 2 additions & 2 deletions logstash-core/src/main/java/org/logstash/config/ir/DSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ public static PluginVertex gPlugin(PluginDefinition.Type type, String pluginName


public static IfVertex gIf(SourceWithMetadata meta, BooleanExpression expression) {
return new IfVertex(meta, expression);
return new IfVertex(expression);
}

public static IfVertex gIf(BooleanExpression expression) {
return new IfVertex(null, expression);
return new IfVertex(expression);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
public final class PipelineIR implements Hashable {

private String uniqueHash;
private final String uniqueHash;

public Graph getGraph() {
return graph;
Expand Down
60 changes: 39 additions & 21 deletions logstash-core/src/main/java/org/logstash/config/ir/graph/Edge.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
package org.logstash.config.ir.graph;

import org.logstash.config.ir.SourceComponent;
import org.logstash.config.ir.InvalidIRException;
import org.logstash.common.SourceWithMetadata;

import java.util.stream.Stream;
import org.logstash.common.SourceWithMetadata;
import org.logstash.config.ir.InvalidIRException;
import org.logstash.config.ir.SourceComponent;

/**
* Created by andrewvc on 9/15/16.
*/
public abstract class Edge implements SourceComponent {

private final Vertex from;

private final Vertex to;

private Graph graph;

protected Edge(Vertex from, Vertex to) throws InvalidIRException {
this.from = from;
this.to = to;

if (this.from == this.to) {
throw new InvalidIRException("Cannot create a cyclic vertex! " + to);
}

if (!this.from.acceptsOutgoingEdge(this)) {
throw new Vertex.InvalidEdgeTypeException(String.format("Invalid outgoing edge %s for edge %s", this.from, this));
}
}

public void setGraph(Graph graph) {
if (this.graph == graph) {
return;
Expand All @@ -22,15 +39,29 @@ public void setGraph(Graph graph) {
}
}

@Override
public final int hashCode() {
return 37 * from.hashCode() + to.hashCode();
}

@Override
public final boolean equals(final Object other) {
if (this == other) {
return true;
}
if (this.getClass() != other.getClass()) {
return false;
}
final Edge that = (Edge) other;
return this.from.equals(that.from) && this.to.equals(that.to);
}

public abstract Edge copy(Vertex from, Vertex to) throws InvalidIRException;

public static abstract class EdgeFactory {
public abstract static class EdgeFactory {
public abstract Edge make(Vertex from, Vertex to) throws InvalidIRException;
}

private final Vertex from;
private final Vertex to;

public Stream<Edge> ancestors() {
// Without all the distinct calls this can be slow
return Stream.concat(this.from.incomingEdges(), this.from.incomingEdges().flatMap(Edge::ancestors).distinct()).distinct();
Expand All @@ -45,19 +76,6 @@ public Stream<Edge> lineage() {
return Stream.concat(Stream.concat(ancestors(), Stream.of(this)), descendants());
}

public Edge(Vertex from, Vertex to) throws InvalidIRException {
this.from = from;
this.to = to;

if (this.from == this.to) {
throw new InvalidIRException("Cannot create a cyclic vertex! " + to);
}

if (!this.from.acceptsOutgoingEdge(this)) {
throw new Vertex.InvalidEdgeTypeException(String.format("Invalid outgoing edge %s for edge %s", this.from, this));
}
}

public Vertex getTo() {
return to;
}
Expand Down
47 changes: 23 additions & 24 deletions logstash-core/src/main/java/org/logstash/config/ir/graph/Graph.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
/**
* Created by andrewvc on 9/15/16.
*/
public class Graph implements SourceComponent, Hashable {
public final Set<Vertex> vertices = new HashSet<>();
private final Set<Edge> edges = new HashSet<>();
private Map<Vertex, Integer> vertexRanks = new HashMap<>();
private final Map<Vertex,Set<Edge>> outgoingEdgeLookup = new HashMap<>();
private final Map<Vertex,Set<Edge>> incomingEdgeLookup = new HashMap<>();
public final class Graph implements SourceComponent, Hashable {
private final Set<Vertex> vertices = new LinkedHashSet<>();
private final Set<Edge> edges = new LinkedHashSet<>();
private Map<Vertex, Integer> vertexRanks = new LinkedHashMap<>();
private final Map<Vertex,Set<Edge>> outgoingEdgeLookup = new LinkedHashMap<>();
private final Map<Vertex,Set<Edge>> incomingEdgeLookup = new LinkedHashMap<>();
private List<Vertex> sortedVertices;

// Builds a graph that has the specified vertices and edges
Expand Down Expand Up @@ -79,14 +79,16 @@ public Vertex getVertexById(String id) {
}

private Graph addEdge(Edge e, boolean doRefresh) throws InvalidIRException {
if (!(this.getVertices().contains(e.getFrom()) && this.getVertices().contains(e.getTo()))) {
if (!(vertices.contains(e.getFrom()) && vertices.contains(e.getTo()))) {
throw new InvalidIRException("Attempted to add edge referencing vertices not in this graph!");
}

this.edges.add(e);

BiFunction<Vertex, Set<Edge>, Set<Edge>> lookupComputeFunction = (vertex, edgeSet) -> {
if (edgeSet == null) edgeSet = new HashSet<>();
final BiFunction<Vertex, Set<Edge>, Set<Edge>> lookupComputeFunction = (vertex, edgeSet) -> {
if (edgeSet == null) {
edgeSet = new LinkedHashSet<>();
}
edgeSet.add(e);
return edgeSet;
};
Expand Down Expand Up @@ -114,11 +116,11 @@ public Graph copy() throws InvalidIRException {
// Returns a new graph that is the union of all provided graphs.
// If a single graph is passed in this will return a copy of it
public static GraphCombinationResult combine(Graph... graphs) throws InvalidIRException {
Map<Vertex, Vertex> oldToNewVertices = new HashMap<>();
Map<Edge,Edge> oldToNewEdges = new HashMap<>();
Map<Vertex, Vertex> oldToNewVertices = new LinkedHashMap<>();
Map<Edge,Edge> oldToNewEdges = new LinkedHashMap<>();

for (Graph graph : graphs) {
graph.vertices().forEach(v -> oldToNewVertices.put(v, v.copy()));
graph.vertices().forEachOrdered(v -> oldToNewVertices.put(v, v.copy()));

for (Edge e : graph.getEdges()) {
Edge copy = e.copy(oldToNewVertices.get(e.getFrom()), oldToNewVertices.get(e.getTo()));
Expand Down Expand Up @@ -147,7 +149,7 @@ public static final class GraphCombinationResult {
the other graph's root
*/
public Graph chain(Graph otherGraph) throws InvalidIRException {
if (otherGraph.getVertices().size() == 0) return this.copy();
if (otherGraph.vertices.isEmpty()) return this.copy();
if (this.isEmpty()) return otherGraph.copy();

GraphCombinationResult combineResult = Graph.combine(this, otherGraph);
Expand Down Expand Up @@ -305,7 +307,7 @@ public Collection<Vertex> getRoots() {
// Vertices which are partially leaves in that they support multiple
// outgoing edge types but only have one or fewer attached
public Stream<Vertex> allLeaves() {
return vertices.stream().filter(Vertex::isPartialLeaf);
return vertices().filter(Vertex::isPartialLeaf);
}

// Get all leaves whether partial or not
Expand All @@ -314,7 +316,7 @@ public Collection<Vertex> getAllLeaves() {
}

public Stream<Vertex> leaves() {
return vertices.stream().filter(Vertex::isLeaf);
return vertices().filter(Vertex::isLeaf);
}

public Collection<Vertex> getLeaves() {
Expand All @@ -325,13 +327,13 @@ public Set<Vertex> getVertices() {
return vertices;
}

public Set<Edge> getEdges() {
public Collection<Edge> getEdges() {
return edges;
}

public String toString() {
final Stream<Edge> edgesToFormat = sortedEdges();
String edgelessVerticesStr;
final String edgelessVerticesStr;
if (this.isolatedVertices().count() > 0) {
edgelessVerticesStr = "\n== Vertices Without Edges ==\n" +
this.isolatedVertices().map(Vertex::toString).collect(Collectors.joining("\n"));
Expand All @@ -348,7 +350,7 @@ public String toString() {
}

public Stream<Vertex> isolatedVertices() {
return this.getVertices().stream().filter(v -> v.getOutgoingEdges().isEmpty() && v.getIncomingEdges().isEmpty());
return vertices().filter(v -> v.getOutgoingEdges().isEmpty() && v.getIncomingEdges().isEmpty());
}

public List<Vertex> getSortedVertices() {
Expand All @@ -369,11 +371,8 @@ public List<Vertex> getSortedVerticesAfter(Vertex start) {
}

public List<Vertex> getSortedVerticesBetween(Vertex start, Vertex end) {
List<Vertex> sortedVertices = getSortedVertices();

int startIndex = start == null ? 0 : sortedVertices.indexOf(start);
int endIndex = end == null ? sortedVertices.size() : sortedVertices.indexOf(end);

return sortedVertices.subList(startIndex+1, endIndex);
}

Expand All @@ -391,11 +390,11 @@ public boolean sourceComponentEquals(SourceComponent sourceComponent) {

// returns true if this graph has a .sourceComponentEquals equivalent edge
public boolean hasEquivalentEdge(Edge otherE) {
return this.getEdges().stream().anyMatch(e -> e.sourceComponentEquals(otherE));
return edges().anyMatch(e -> e.sourceComponentEquals(otherE));
}

public boolean hasEquivalentVertex(Vertex otherV) {
return this.getVertices().stream().anyMatch(v -> v.sourceComponentEquals(otherV));
return vertices().anyMatch(v -> v.sourceComponentEquals(otherV));
}

@Override
Expand All @@ -404,7 +403,7 @@ public SourceWithMetadata getSourceWithMetadata() {
}

public boolean isEmpty() {
return (this.getVertices().size() == 0);
return vertices.isEmpty();
}

public Stream<Vertex> vertices() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public BooleanExpression getBooleanExpression() {

private final BooleanExpression booleanExpression;

public IfVertex(SourceWithMetadata meta, BooleanExpression booleanExpression) {
super(meta);
public IfVertex(BooleanExpression booleanExpression) {
super();
this.booleanExpression = booleanExpression;
}

Expand Down Expand Up @@ -72,8 +72,8 @@ public Collection<BooleanEdge> getOutgoingBooleanEdges() {
return getOutgoingEdges().stream().map(e -> (BooleanEdge) e).collect(Collectors.toList());
}

public Collection<BooleanEdge> getOutgoingBooleanEdgesByType(Boolean edgeType) {
return getOutgoingBooleanEdges().stream().filter(e -> e.getEdgeType().equals(edgeType)).collect(Collectors.toList());
public Collection<BooleanEdge> getOutgoingBooleanEdgesByType(boolean edgeType) {
return getOutgoingBooleanEdges().stream().filter(e -> e.getEdgeType() == edgeType).collect(Collectors.toList());
}

// The easiest readable version of this for a human.
Expand All @@ -89,7 +89,7 @@ public String humanReadableExpression() {

@Override
public IfVertex copy() {
return new IfVertex(getSourceWithMetadata(),getBooleanExpression());
return new IfVertex(booleanExpression);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public SourceWithMetadata getSourceWithMetadata() {

public PluginVertex(SourceWithMetadata meta, PluginDefinition pluginDefinition) {
// We know that if the ID value exists it will be as a string
super(meta, (String) pluginDefinition.getArguments().get("id"));
super((String) pluginDefinition.getArguments().get("id"));
this.meta = meta;
this.pluginDefinition = pluginDefinition;
}
Expand All @@ -50,7 +50,7 @@ public String calculateIndividualHashSource() {

@Override
public PluginVertex copy() {
return new PluginVertex(meta, getPluginDefinition());
return new PluginVertex(meta, pluginDefinition);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
/**
* Created by andrewvc on 9/15/16.
*/
public class QueueVertex extends Vertex {
public QueueVertex() {
super(null);
}
public final class QueueVertex extends Vertex {

@Override
public String getId() {
Expand All @@ -32,7 +29,6 @@ public QueueVertex copy() {

@Override
public boolean sourceComponentEquals(SourceComponent other) {
if (other == null) return false;
return other instanceof QueueVertex;
}

Expand Down
Loading

0 comments on commit adc848d

Please sign in to comment.