-
Notifications
You must be signed in to change notification settings - Fork 645
Description
Describe the bug
Summary
In v2.0beta3, calling IterateLookup after a Upsert → Delete → Upsert sequence causes either a freeze or missing records, depending on the device type. The same logic works correctly in v1.1.
Steps to Reproduce
- Upsert keys 0–252 (253 records total)
- Delete all keys 0–252
- Upsert keys 0–252 again
- Call
IterateLookupin a loop withresetCursor:false; in theReadercallback, returnCursorRecordResult.Accept | CursorRecordResult.EndBatchwhen the batch count reaches 64 (MaxCount)
Expected Behavior (v1.1)
All 253 records (keys 0–252) are returned. The loop exits naturally with TotalCount == 253.
Actual Behavior (v2.0beta3)
Two distinct failure modes are observed depending on the device type.
① LocalMemoryDevice: freeze / infinite loop
IterateLookup never completes. The scan log shows the following repeating pattern, with OnStop firing repeatedly and OnStart never called between batches:
OnStop → Accept... → OnStop
Accept...
OnStop → Accept... → OnStop
OnStop → Accept... → OnStop
(repeats indefinitely)② Other devices (e.g. ManagedLocalStorageDevice): missing records
The loop terminates, but keys 0–66 (67 records) are never returned. Only keys 67–252 (186 records) are retrieved. Assert.Equal(253, TotalCount) fails.
Comparison with v1.1
Root Cause Hypothesis
The bug appears to be in how v2.0beta3's IterateLookup handles cursor resumption across batch boundaries (EndBatch) when deleted (tombstoned) records are physically present in the log. Specifically, the resume address calculation may not correctly account for skipped delete records, causing the scan to either loop back to an already-visited region (LocalMemoryDevice) or skip the initial segment of live records entirely (other devices). The absence of OnStart between batches in the LocalMemoryDevice log strongly suggests the cursor state is not being preserved correctly when re-entering the scan after EndBatch.
A minimal reproduction is provided in the attached test code.