From 877ddd82bdd2990800d871cc8929a87a3e78d54f Mon Sep 17 00:00:00 2001 From: Nikhil Mittal Date: Thu, 19 Feb 2026 22:53:28 +0530 Subject: [PATCH 1/2] static rule optimization by batching --- .vscode/launch.json | 31 +++++++++++++++++ .../salesforce/rules/AbstractStaticRule.java | 33 +++++++++++++++---- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 12be9252..c2f22e1f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,6 +50,37 @@ "/**" ] }, + { + "type": "java", + "request": "attach", + "name": "Attach to SFGE Java (port 5005)", + "hostName": "localhost", + "port": 5005 + }, + { + "type": "node", + "request": "launch", + "name": "Debug SFGE Full Flow (single test)", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/node_modules/.bin/jest", + "args": [ + "packages/code-analyzer-sfge-engine/test/engine.test.ts", + "-t", + "When only one of several selected rules is violated", + "--runInBand", + "--coverage=false", + "--testTimeout=600000000" + ], + "env": { + "NODE_OPTIONS": "--experimental-vm-modules" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "skipFiles": [ + "/**" + ], + "timeout": 300000 + }, { "type": "node", "request": "launch", diff --git a/packages/code-analyzer-sfge-engine/sfge/src/main/java/com/salesforce/rules/AbstractStaticRule.java b/packages/code-analyzer-sfge-engine/sfge/src/main/java/com/salesforce/rules/AbstractStaticRule.java index 595b816d..6a1f931e 100644 --- a/packages/code-analyzer-sfge-engine/sfge/src/main/java/com/salesforce/rules/AbstractStaticRule.java +++ b/packages/code-analyzer-sfge-engine/sfge/src/main/java/com/salesforce/rules/AbstractStaticRule.java @@ -8,20 +8,41 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; public abstract class AbstractStaticRule extends AbstractRule implements StaticRule { + @Override public final List run(GraphTraversalSource g) { return run(g, new ArrayList<>()); } + /** + * TinkerGraph's .union() operator degrades non-linearly when given thousands of + * sub-traversals. Splitting targets into batches of this size keeps each .union() + * manageable and avoids the performance cliff. + */ + private static final int BATCH_SIZE = 500; + public final List run( GraphTraversalSource g, List targets) { - GraphTraversal eligibleVertices = buildBaseTraversal(g, targets); - return _run(g, eligibleVertices); - } + if (targets.size() <= BATCH_SIZE) { + GraphTraversal eligibleVertices = + TraversalUtil.ruleTargetTraversal(g, targets); + return _run(g, eligibleVertices); + } - private GraphTraversal buildBaseTraversal( - GraphTraversalSource g, List targets) { - return TraversalUtil.ruleTargetTraversal(g, targets); + int totalBatches = (targets.size() + BATCH_SIZE - 1) / BATCH_SIZE; + List allViolations = new ArrayList<>(); + + for (int batchNum = 0; batchNum < totalBatches; batchNum++) { + int fromIndex = batchNum * BATCH_SIZE; + int toIndex = Math.min(fromIndex + BATCH_SIZE, targets.size()); + List batch = targets.subList(fromIndex, toIndex); + + GraphTraversal batchTraversal = + TraversalUtil.ruleTargetTraversal(g, batch); + List batchViolations = _run(g, batchTraversal); + allViolations.addAll(batchViolations); + } + return allViolations; } /** From 50e11e46e4054d6d85bc96f52eeee832007e5b0f Mon Sep 17 00:00:00 2001 From: Nikhil Mittal Date: Mon, 23 Feb 2026 09:07:47 +0530 Subject: [PATCH 2/2] Revert launch.json changes --- .vscode/launch.json | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c2f22e1f..12be9252 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,37 +50,6 @@ "/**" ] }, - { - "type": "java", - "request": "attach", - "name": "Attach to SFGE Java (port 5005)", - "hostName": "localhost", - "port": 5005 - }, - { - "type": "node", - "request": "launch", - "name": "Debug SFGE Full Flow (single test)", - "cwd": "${workspaceFolder}", - "program": "${workspaceFolder}/node_modules/.bin/jest", - "args": [ - "packages/code-analyzer-sfge-engine/test/engine.test.ts", - "-t", - "When only one of several selected rules is violated", - "--runInBand", - "--coverage=false", - "--testTimeout=600000000" - ], - "env": { - "NODE_OPTIONS": "--experimental-vm-modules" - }, - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "skipFiles": [ - "/**" - ], - "timeout": 300000 - }, { "type": "node", "request": "launch",