|
8 | 8 | import org.apache.tinkerpop.gremlin.structure.Vertex; |
9 | 9 |
|
10 | 10 | public abstract class AbstractStaticRule extends AbstractRule implements StaticRule { |
| 11 | + |
11 | 12 | @Override |
12 | 13 | public final List<Violation> run(GraphTraversalSource g) { |
13 | 14 | return run(g, new ArrayList<>()); |
14 | 15 | } |
15 | 16 |
|
| 17 | + /** |
| 18 | + * TinkerGraph's .union() operator degrades non-linearly when given thousands of |
| 19 | + * sub-traversals. Splitting targets into batches of this size keeps each .union() |
| 20 | + * manageable and avoids the performance cliff. |
| 21 | + */ |
| 22 | + private static final int BATCH_SIZE = 500; |
| 23 | + |
16 | 24 | public final List<Violation> run( |
17 | 25 | GraphTraversalSource g, List<AbstractRuleRunner.RuleRunnerTarget> targets) { |
18 | | - GraphTraversal<Vertex, Vertex> eligibleVertices = buildBaseTraversal(g, targets); |
19 | | - return _run(g, eligibleVertices); |
20 | | - } |
| 26 | + if (targets.size() <= BATCH_SIZE) { |
| 27 | + GraphTraversal<Vertex, Vertex> eligibleVertices = |
| 28 | + TraversalUtil.ruleTargetTraversal(g, targets); |
| 29 | + return _run(g, eligibleVertices); |
| 30 | + } |
21 | 31 |
|
22 | | - private GraphTraversal<Vertex, Vertex> buildBaseTraversal( |
23 | | - GraphTraversalSource g, List<AbstractRuleRunner.RuleRunnerTarget> targets) { |
24 | | - return TraversalUtil.ruleTargetTraversal(g, targets); |
| 32 | + int totalBatches = (targets.size() + BATCH_SIZE - 1) / BATCH_SIZE; |
| 33 | + List<Violation> allViolations = new ArrayList<>(); |
| 34 | + |
| 35 | + for (int batchNum = 0; batchNum < totalBatches; batchNum++) { |
| 36 | + int fromIndex = batchNum * BATCH_SIZE; |
| 37 | + int toIndex = Math.min(fromIndex + BATCH_SIZE, targets.size()); |
| 38 | + List<AbstractRuleRunner.RuleRunnerTarget> batch = targets.subList(fromIndex, toIndex); |
| 39 | + |
| 40 | + GraphTraversal<Vertex, Vertex> batchTraversal = |
| 41 | + TraversalUtil.ruleTargetTraversal(g, batch); |
| 42 | + List<Violation> batchViolations = _run(g, batchTraversal); |
| 43 | + allViolations.addAll(batchViolations); |
| 44 | + } |
| 45 | + return allViolations; |
25 | 46 | } |
26 | 47 |
|
27 | 48 | /** |
|
0 commit comments