Repository navigation
fix(list): bound LTRIM work by list length - #3775
PoisonGodv wants to merge 4 commits into
Conversation
|
Hi @PoisonGodv, Thank you for your pull request. Please review our Contributing Guide. Please make sure you understand your changes and explain your reasoning in this pull request. Low-quality pull requests may be closed. |
|
Could a maintainer please approve the two pending workflows for the current head 7dd48c2? CI (https://github.com/apache/kvrocks/actions/runs/43001672485) and Compatibility Tests (https://github.com/apache/kvrocks/actions/runs/43001672745) are both action_required, so the test suites have not run yet. Thank you! |
|
@aleksraiden, could you please approve the two pending workflows for the refreshed head |
Title: fix(list): bound LTRIM work by list length
Problem
For a string of indices where
start == stopandstartis beyond the list end,List::Trimdoes not take the existing empty-range fast path. Its left-delete loop instead runs frommetadata.headtometadata.head + start, without being bounded bymetadata.tail. On a one-element list this creates point deletes for nonexistent list subkeys.Minimal example:
The expected result is a prompt
OKwithkremoved. On the unpatched base, the regression client exceeded a one-second deadline.A temporary diagnostic counter measured the behavior without allowing an uncontrolled write batch:
LTRIM k 1000000 1000000on a one-element list completed after exactly 1,000,000 left-sideDeletecalls (0.48 seconds in the local ASAN run).Deletecalls in 0.27 seconds before the diagnostic deliberately stopped it. The maximum-input run was not allowed to continue, so this is not a claim that billions of completions were observed.Valkey source
aa7545348b688b469d073a01ce4836ed637577f9returnsOKimmediately and deletes the key. Its implementation explicitly treatsstart >= lengthas an empty range.Fix
After negative-index normalization, use the existing metadata-deletion path when
start >= metadata.size. This is the same result as trimming to an empty list, but avoids constructing deletes for indices that cannot exist. The existingstart > stopbehavior and retained-range loops are unchanged.Tests
Add
TestLTRIM/LTRIM_with_maximum_start_index, usingmath.MaxInt32for both indices and a one-second client deadline. The regression verifies that the resulting list length is zero, the key no longer exists, its TTL is removed (TTL == -2), and the key can be recreated with the expected contents.Verification on macOS arm64 with Xcode Clang 21 and ASAN:
84e883225ec2a2de4ed59f86a0f431377face2f2: FAIL (context deadline exceeded). An external watchdog only terminated the test server during cleanup after the client deadline.txn-context-enabledconfigurations.tests/gocase/unit/type/listpackage: PASS (TEST_EXIT=0).go vet ./unit/type/list: PASS../x.py check format: PASS.Not run