Repository navigation
v4 overload minimalism: SortedSetRange, Expiration on RESTORE, GeoCenter - #3356
Merged
Merged
Conversation
The three findings from the v4 group-surface overload audit (notes/api-surface/overload-audit.md): - SortedSets: one method per operation - RangeAsync, RangeWithScoresAsync, RangeAndStoreAsync, RemoveRangeAsync, RangeLengthAsync - each taking a SortedSetRange operand (ByRank/ByScore/ByValue) instead of eleven per-axis methods; LengthAsync slims to bare ZCARD. The per-axis methods demote to internal, keeping the wire spelling and the legacy IDatabase adapter. Cells the server cannot spell (WITHSCORES over BYLEX, LIMIT or a count over ranks) throw rather than quietly answering a different question; a by-rank exclusivity is no longer representable at all. The operand store path also gains open lexical bounds and descending bound-swapping, which the SortedSetOrder-shaped legacy method left to the caller. - Keys.RestoreAsync takes an Expiration: relative stays positional milliseconds, absolute adds ABSTTL, KEEPTTL/PERSIST/ENX are rejected, and the TimeSpan.MaxValue-means-none wart survives only in the internal legacy sibling. - Geospatial: a GeoCenter operand (implicit from RedisValue/string/GeoPosition; deliberately not from a tuple - ValueTupleNotReferenced pins that) folds the member/lon-lat SearchAsync and SearchAndStoreAsync pairs 4 -> 2. En route: RangeByScoreCore and CombineCore accepted a CancellationToken from their public callers and dropped it before SendAsync; both now forward it. Geo's SearchCore has the same drop, left for a sweep of its own.
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.
Implements the three findings from the v4 group-surface overload audit (now checked in as
notes/api-surface/overload-audit.md, with an implementation postscript).1. SortedSets: one method per operation, the axis is data
A
SortedSetRangeoperand in theExpirationmould -ByRank(start, stop),ByScore(min, max, exclude),ByValue(min, max, exclude), withdefaultmeaning the whole set by rank - and five methods where there were eleven:LengthAsyncslims to bareZCARD(ZCOUNT/ZLEXCOUNTlive underRangeLengthAsync), and theSortedSetOrderaxis enum disappears fromRangeAndStoreAsync. The per-axis methods demote to internal - the wire spelling, bound-swapping and the legacyIDatabaseadapter all stay put.Where the server has no command for a cell, the dispatcher throws rather than quietly answering a different question:
WITHSCORESover a lexical range (every member of such a set shares one score - the audit originally mis-called this cell "arbitrarily missing"),LIMITover a rank range, and a count of a rank range. A by-rank exclusivity, which the old surface rejected at runtime, is now unrepresentable:ByRankhas no exclude parameter.Two things the operand store path gains over the legacy shape: open (
-/+) lexical bounds, and descending bound-swapping done for you (withREVthe server wants high-then-low, exclusivity travelling with its bound - the same normalization the reads have always applied).2.
Keys.RestoreAsynctakes anExpirationRESTOREhasABSTTL, so the operand that already spells relative/absolute/none is the right one. Relative renders as the positional millisecond ttl; absolute adds theABSTTLtrailer;KEEPTTL/PERSIST/ENX are rejected (a restored key has no expiry to keep). TheTimeSpan.MaxValue-means-none wart survives only in the internal sibling that serves the legacy surface.3.
GeoCenterfolds the geo search pairs 4 → 2SearchAsyncandSearchAndStoreAsynceach differed only in how the centre was spelled (member vs longitude/latitude).GeoCenteris that choice as data, implicit fromRedisValue/string/GeoPosition- not from a(double, double)tuple, which the full-suite run caught:SanityChecks.ValueTupleNotReferencedpins that this library never referencesSystem.ValueTuple(net461 only gets it from an extra package). Adefaultcentre is rejected rather than silently searching (0, 0).En route
RangeByScoreCoreandCombineCoreaccepted aCancellationTokenfrom their public callers and dropped it beforeSendAsync; both now forward it. Geo'sSearchCore(and possibly others) have the same drop - left alone here, worth a sweep of its own.Tests
Wire tests rewritten against the operand surface with identical byte expectations, plus new coverage: rank-axis dispatch, descending stores, the refusal matrix,
RESTORE's three expiry spellings, and the default-GeoCenterrejection. Full net10.0 suite: 7532 passed / 167 skipped; the only failures are the 8 known-environmentalSortedSetScanLargeones (dev-server btree ZSCAN duplicates, fixed in the server 8.12 branch). Docs (Groups.md,LegacyApi.mdmapping tables) updated.