Conversation
A traversal scope such as group -> items -> attributes expanded one parent at a time, so a cold scope of a few hundred parents waited for a few hundred adjacency reads in turn. Parents' neighbour reads now overlap through the request's shared index-read budget, in parent order, keeping each parent's point reads (adjacency values are merge operands) and the first error in parent order. Pull-mode expansion stays lazy.
…d read Property projections read each row's record with its own point read, so a cold top-50 projection over search results waited for 50 serial fetches. Values, selected value maps and item projections now resolve a record batch with one shared resolver, prefetching through the overlapped multi-get the records that per-row resolution will read. record_read, which row_property now uses for its own record read, decides which those are, so a prefetch never reads a record the per-row path would skip; expressions stay lazy.
…ojections Whole-value expansion takes parents a record batch at a time and drops them once expanded, instead of keeping every input row alive until the end. The resolver and projection docs state the batch-scoped cache and error precedence. Tests cover Values and selected value maps over several batches, projection deadlines, and expansion across windows.
The batched prefetch future (an overlapped multi-get) sat inline in every projection future, and evaluation that recurses through projections nested them deeply enough to overflow a test thread's stack in randomized_recursive_counts_match_the_materialized_row_oracle.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked on #1158. Two more serial cold-read chains on the search path become overlapped.
1. Projections read one record per row. A top-50 projection over search results (for example
owner,$distance) waited for 50 serial cold reads. Values, selected value maps and item projections now:RowValueResolverper record batch;multi_get_raw, only the records per-row resolution would read.record_readdecides which records those are, androw_propertynow uses the same function for its own record read, so the two can't drift apart. Expressions stay lazy.2. Whole-value expansion read one parent at a time. A traversal scope like group → items → attributes waited for one adjacency read per parent. Parents are now read concurrently through the request's shared index-read budget (
read_children), in windows of one record batch so consumed parents are freed. Each parent keeps its point reads, because adjacency values are merge operands. Parent order, child order and first-error order are preserved, and pull-mode expansion stays lazy.Results
Embedded bench, cold first query (5% fixture, 20 ms injected per GET), PR #1158 alone vs with this PR:
Warm latency improves slightly too (20% fixture, group+kind-B p50: 12–14 ms before, 7–9 ms after).
Behaviour notes
Tests
record_readmatches whatrow_propertyreads for node, edge, empty and virtual-property rows and for edge endpoint paths;Project,ValuesandValueMap(Selected)over more than one record batch: full output in order, no per-row point reads, one read per distinct record;The PR appears safe to merge, though edge endpoint-property projections retain a serial cold-read path.
Summary
This PR overlaps whole-value expansion reads across parent rows and batch-prefetches stored records for selected property projections while retaining ordered results.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A[Projection rows] --> B[Record batch] B --> C[Classify property reads] C --> D[Prefetch current-element records] D --> E[Resolve rows in order] F[Expansion rows] --> G[Parent window] G --> H[Bounded concurrent reads] H --> I[Emit children in parent order]Reviews (1) · Last reviewed commit: "perf(db): box the projection prefetch so..."