deps: build against differential-dataflow master-next and timely master - #38805
Draft
antiguru wants to merge 1 commit into
Draft
deps: build against differential-dataflow master-next and timely master#38805antiguru wants to merge 1 commit into
antiguru wants to merge 1 commit into
Conversation
Ports the tree to `TimelyDataflow/differential-dataflow` `master-next` at 229508dd, which pins timely by git, so timely master comes along. The point is to find out what the next differential costs us before it lands, and to have the adjustment written down rather than discovered under time pressure. Differential deleted `Batch` and `BatchReader`. A trace's batch is now bare `'static + Clone`, and the description that used to hang off it lives on the new `Span<T, B>`, whose batch is absent exactly when the interval carried no updates. `TraceReader` loses `cursor`/`cursor_through` in favour of `spans_through`/`batches_through` plus `trace::cursor::cursor_list`, and `map_batches` becomes `map_spans`. `SpineBatch` shrinks to `Time`, `Merger` and `len`, which takes a good deal of `ArcBatch` with it. `Builder` becomes `Default` + `push` + `done(self) -> Option<Output>`, with sealing moved out to `Sealer`. `Batcher` takes its input container as a trait parameter, owns its chunker, and returns `(Option<Output>, AntichainRef)` from `extract`. `MergeBatcher` therefore names chunker, merger and sealer together, which collapses `mz_arrange::<Chu, Ba, Bu, Tr>` to `mz_arrange::<Ba, Tr>`: the three parameters were always one unit, and differential now says so. The `Arrange` trait is retired in favour of inherent methods taking a batcher constructor, and this follows that shape everywhere a call site can name the batcher type. `MzArrangeCore`'s input container has to become a trait parameter rather than an associated type, because a batcher bound written through a projection does not normalize in the impl. Consolidation wants the chunks, not a trace batch built from them and taken apart again, so `ConsolidatingBatcher` is a `Batcher` whose output is the chain. `ColumnMergeBatcher` gains `extract_chain`, with its `Batcher::extract` being that plus a seal, which is what the upsert stash and the temporal-bucket store want. Three forks go away. `mz_join_core` existed to yield within keys; the differential join driver now owns a fuel budget and yields between output containers, so `join_core` covers it and `LinearJoinSpec` with it. Delta join's `build_halfjoin1` goes too, since upstream folded `half_join2` into `half_join`, and `half_join_internal_unsafe` takes the tie-break as a flag where this passed a comparison closure, which was already a bool one frame up. Storage's `UpsertFeedbackBatcher` wrapper existed only to inject the storage pager into a constructor the trait did not expose, and is now a closure at the call site. Timely's message capabilities carry a `Stamp`, a multiset. `InputCapability`'s `time`, `retain` and `Deref` panic unless it is a singleton, and nothing about that is visible at compile time. A `clippy.toml` entry for the first two found the sites, several of which reading the code had missed. `ArrangementFlatMap` and its ok-only twin hold a `CapabilitySet` now, so the `Session` alias is typed over one; `TopKIntraTimeThinning` buckets by the record's own time rather than the message's; `LimitProgress` keeps an antichain instead of one hand-picked capability. The remaining sites carry an allow explaining why their stamp is a singleton. Not merge-ready, and deliberately so: * `bin/lint` fails `cargo deny sources`, because `deny.toml` allows git dependencies only from the MaterializeInc organization. That is the right policy and should not be relaxed for this; the merge path is a published release or MaterializeInc forks, not a `branch =` reference, which is not reproducible either. * Recursive dataflows panic without a fix to differential's `leave_dynamic`, which reads a single time off a multi-capability message. The pull request carries the patch and the reproduction. * Wrapping builders can no longer size their inner builder, because `OrdValBuilder::with_capacity` and `OrdKeyBuilder::with_capacity` are private upstream. The six spine builders drop the counts they compute, which is an allocation regression to raise before this lands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Draft. Front-loads the adjustment to the next differential-dataflow, and records what it costs us, so the work is written down rather than discovered under time pressure when it lands. Not merge-ready, for reasons listed at the bottom.
Builds against
TimelyDataflow/differential-dataflowmaster-nextat229508dd, which pins timely by git, so timely master comes along. That is 70 differential commits of delta, of which roughly 40 are Corgi/DDIR/formal work with no effect here.What moved
BatchandBatchReaderare gone. A trace's batch is bare'static + Clone, and the description that used to hang off it lives on the newSpan<T, B>, whose batch is absent exactly when the interval carried no updates.TraceReaderlosescursor/cursor_throughforspans_through/batches_throughplustrace::cursor::cursor_list, andmap_batchesbecomesmap_spans.SpineBatchshrinks toTime,Merger,len, which takes a good deal ofArcBatchwith it.BuilderbecomesDefault+push+done(self) -> Option<Output>, sealing moves out toSealer, andBatchertakes its input container as a trait parameter, owns its chunker, and returns(Option<Output>, AntichainRef). SoMergeBatchernames chunker, merger and sealer together, andmz_arrange::<Chu, Ba, Bu, Tr>collapses tomz_arrange::<Ba, Tr>— those three parameters were always one unit, and differential now says so.Consolidation wants the chunks rather than a trace batch assembled from them and immediately taken apart, so
ConsolidatingBatcheris aBatcherwhose output is the chain, andColumnMergeBatchergrowsextract_chainwith itsBatcher::extractbeing that plus a seal.What it deletes
Net -734 lines. Three forks stop earning their keep:
mz_join_core, which existed to yield within keys. The differential join driver owns a fuel budget and yields between output containers, sojoin_corecovers it, andLinearJoinSpec/YieldSpecgo with it.build_halfjoin1in the delta join, since upstream foldedhalf_join2intohalf_join.half_join_internal_unsafenow takes the tie-break as a flag where we passed a comparison closure — which was already a bool one frame up, assource_precedes_lookup.UpsertFeedbackBatcher, a wrapper type whose only job was injecting the storage pager into a constructor the trait did not expose. Now a closure at thearrange_corecall site.That leaves
enable_mz_join_core,linear_join_yieldingandenable_half_join2with no readers. Removing the definitions is a follow-up.Timely's multi-capability stamps
A message's capabilities are a
Stamp, a multiset.InputCapability::time,retainandDerefpanic unless it is a singleton, and nothing about that is visible at compile time. Aclippy.tomldisallowed-methodsentry for the first two is the only mechanical guard, and it found sites that reading the code had missed, includingbuilder_async'sInputConnection::accept— the funnel every async operator's capability comes through.Non-singleton stamps have two sources: a partially ordered timestamp, where the antichain of capabilities an operator retires can hold more than one element; and a scope-boundary map, which
Stamp::map_pointwisemakes count-preserving on purpose, so collapsing inner times produce duplicates. AT: TotalOrderbound therefore does not imply a singleton on its own.Fixed here:
ArrangementFlatMapand its ok-only twin hold aCapabilitySet(so theSessionalias is typed over one),TopKIntraTimeThinningbuckets by the record's own time rather than the message's, andLimitProgresskeeps an antichain instead of one hand-picked capability. Every remaining site carries an allow saying why its stamp is a singleton.Tests
No new test files.
render/top_k.rs's intra-time thinning changed shape, sotopk.sltcovers it; the batcher and builder rewrites are covered by the existingmz-timely-util,mz-row-spineandmz-computeunit tests, whose helpers were rewritten for the newBuilder/BatcherAPIs.Why this is a draft
bin/lintfailscargo deny sources.deny.tomlallows git dependencies only from the MaterializeInc organization, with a rationale about shared maintainership and historical buildability. That policy is right and should not be relaxed for this. The merge path is a published release or MaterializeInc forks — and in any case abranch =reference is not reproducible and would need to become arev =.Recursive dataflows panic, on an upstream bug rather than anything here.
leave_dynamicreads a single time off a multi-capability message, in both implementations:differential-dataflow/src/dynamic/mod.rs:50differential-dataflow/src/columnar/collection/operators.rs:120A dynamic scope is exactly where non-singleton stamps arise, so the operator is unreachable rather than failing in a corner case.
distinct_arrangements.sltandchbench.sltpanic within seconds; with the patch below applied they run. The fix must minimize into aCapabilitySetrather than preserve counts —leave_dynamicis an ordinary operator acquiring fresh capabilities viadelayed, not a scope boundary, so minimizing is legitimate there, and downstream async operators depend on it.Patch against 229508dd
The same change applies to
columnar/collection/operators.rs:120.Wrapping builders can no longer pre-size.
OrdValBuilder::with_capacityandOrdKeyBuilder::with_capacityare private upstream, so the six spine builders compute their key/val/update counts and throw them away. That is an allocation regression and the main thing to raise with upstream alongside theleave_dynamicfix.Based on
ad7b551153; wants a rebase before it goes anywhere.🤖 Generated with Claude Code