Skip to content

interop/tinkerpop: A2 lowering strategy (Gremlin → mask hop chain) - #90

Merged
AdaWorldAPI merged 1 commit into
mainfrom
ccr-70e679fa-9qvl9y
Oct 9, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
ccr-70e679fa-9qvl9y

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

Quick win A2, built on the A1 harness (#89).

LanceHopStrategy is a TinkerPop ProviderOptimizationStrategy:

GraphTraversalSource g = graph.traversal()
        .withStrategies(new LanceHopStrategy(store, Map.of("knows", Edge.KNOWS)));
long n = g.V(seeds).out("knows").out("knows").dedup().count().next();

It lowers exactly one shape, V(ids).out(label)^k.dedup().count() with k ≥ 1. The whole traversal becomes one LanceHopCountStep, which answers from the lance-graph-java mask hop chain when iterated. repeat(out(label)).times(k) reaches the same shape, because TinkerPop unrolls it before provider strategies run.

Any other root traversal is left to Gremlin, counted in fellBack(), with the reason in lastFallbackReason(). That covers:

  • walk counts without dedup();
  • has(), in(), unmapped labels, more than one label per hop;
  • V() without ids, or an id outside the row store;
  • as() labels.

Everything lives in interop/tinkerpop/. src/main is unchanged.

Measured

LoweringStrategyTest: 55 checks green. A1's TinkerParityTest stays at 25 green.

  • Parity: the lowered answer equals plain Gremlin for k = 1..3, through both out()^k and repeat(). Each traversal ran as one LanceHopCountStep.
  • Provenance: against an empty TinkerGraph, the lowered traversal still returns the row store's count, while plain Gremlin returns 0. So the answer comes from the mask chain, not from Gremlin.
  • Fallbacks: each of seven excluded shapes is counted once, and its answer matches Gremlin exactly.

Disable runs (each red, then green after restore)

  • dedup() guard removed: 6 checks go red. A walk count through barrier() gets lowered and returns the distinct count instead of the walk count.
  • Lowered step returns 0: 7 checks go red (every parity check plus provenance).

A finding from the first disable run: Gremlin rewrites out().count() into outE().count() before provider strategies run, so a plain walk count never reaches the dedup() guard. The barrier() case was added because it does reach the guard.

Not in this PR

  • A3: measuring lowered vs plain Gremlin.
  • A5: a Gremlin Server endpoint.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AhMhXd2gDhYzTgwKeHaWHB


Generated by Claude Code

LanceHopStrategy is a TinkerPop ProviderOptimizationStrategy. It rewrites
V(ids).out(label)^k.dedup().count() into one LanceHopCountStep answered by
the lance-graph-java mask hop chain; repeat(out()).times(k) reaches the same
shape. Every other root traversal is left to Gremlin, counted in fellBack()
with the reason in lastFallbackReason().

LoweringStrategyTest (55 checks): parity with plain Gremlin for k = 1..3;
provenance (an empty TinkerGraph still yields the row store's count when
lowered, 0 when not); seven fallback shapes counted and answering exactly as
Gremlin. Disable runs: removing the dedup() guard turns 6 checks red,
a lowered step answering 0 turns 7 red. run.sh now runs both mains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AhMhXd2gDhYzTgwKeHaWHB
@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 4746e274-3827-41ad-8f3c-cf3f5fd2e88f

📥 Commits

Reviewing files that changed from the base of the PR and between 0136005 and 673f58e.


📒 Files selected for processing (8)
  • .claude/board/LATEST_STATE.md
  • .claude/board/PR_ARC_INVENTORY.md
  • interop/tinkerpop/README.md
  • interop/tinkerpop/run.sh
  • interop/tinkerpop/src/com/adaworldapi/interop/tinkerpop/LanceHopCountStep.java
  • interop/tinkerpop/src/com/adaworldapi/interop/tinkerpop/LanceHopStrategy.java
  • interop/tinkerpop/src/com/adaworldapi/interop/tinkerpop/LoweringStrategyTest.java
  • interop/tinkerpop/src/com/adaworldapi/interop/tinkerpop/TinkerParityTest.java

 _____________________________
< The Da Vinci Code Reviewer. >
 -----------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands.

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 9, 2026 14:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T14:41:43.628664Z 673f58e Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@AdaWorldAPI
AdaWorldAPI merged commit 0b835f1 into main Oct 9, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants