Skip to content

load cascade child once per ref in fk cascade delete#64

Merged
fabracht merged 2 commits into
mainfrom
perf/23-cascade-single-read
May 20, 2026
Merged

load cascade child once per ref in fk cascade delete#64
fabracht merged 2 commits into
mainfrom
perf/23-cascade-single-read

Conversation

@fabracht
Copy link
Copy Markdown
Contributor

Summary

Closes #23. In FK cascade-delete, each referencing child entity was read from storage twice: once inside is_cross_owned to check the owner field, then again in collect_delete_operations to deserialize for recursive cascade. Both reads used identical keys.

Replaced is_cross_owned with classify_cascade_child, which loads the record once and returns a three-variant CascadeChild enum:

  • Skip — cross-owned, don't recurse, don't push a Cascade op
  • Missing — record gone (e.g. concurrent delete), push Cascade op without recurse
  • Recurse(Entity) — proceed with cascade using the already-loaded entity

The caller pattern-matches and only needs to push the Cascade op (and recurse when applicable); no second storage.get / Entity::deserialize per child.

Per-child read counts:

case before after
no ownership context 1 1
admin sender 1 1
entity not owner-tracked 1 1
same-owner child 2 1
cross-owned child 1 1
record missing (with ctx) 2 1

Saves one read per same-owner child (the common path under ownership-aware cascade) and per missing-record-with-ctx.

Test plan

  • cargo make clippy — clean (pedantic, all targets + wasm)
  • cargo test -p mqdb-agent --test constraint_test — 34/34 pass, including all owner-aware cascade scenarios (same-owner deletes, cross-owner survives, admin bypass, no-sender blind, mixed-ownership multilevel)
  • Pre-commit hook (format-check + clippy) passed on the commit

@fabracht fabracht merged commit 9d7678b into main May 20, 2026
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.

double storage read for same-owner entities during cascade delete

1 participant