fix(flatfile): page-up cursor must not stick on entries[0]
All checks were successful
CI Code / Check spelling (pull_request) Successful in 23s
CI Code / Check coding style (pull_request) Successful in 37s
CI Code / Code Coverage (pull_request) Successful in 2m39s
CI Code / Linux (debian) (pull_request) Successful in 4m51s
CI Code / Linux (ubuntu) (pull_request) Successful in 6m47s
CI Code / Linux (arch) (pull_request) Successful in 9m59s

When the cursor lands on entries[0].byte_offset, the !from_start
backup logic produces an empty [X, X) range, get_previous_chat
returns DB_RESPONSE_EMPTY, the UI sets WIN_SCROLL_REACHED_TOP and
never tries again — page-up is permanently stuck.

Guard the cursor optimisation with two conditions: index must be
non-empty AND cursor must not equal entries[0].byte_offset. When
either fails, fall through to the end_time bisect path which
correctly locates the byte range with older messages.

F16 regression test in bench_failure_modes:
  without guard: received=200 in 3 iters (premature EMPTY)
  with guard:    received=600 in 7 iters (truly reaches top)
This commit is contained in:
2026-05-04 12:14:54 +03:00
parent 1fe3808b23
commit a7da9e2add
2 changed files with 123 additions and 3 deletions

View File

@@ -728,8 +728,13 @@ _flatfile_get_previous_chat(const gchar* const contact_barejid, const gchar* sta
off_t read_from = state->bom_len;
off_t read_to = state->stamp.size;
// Use stored cursor for sequential Page Up (skip bisect)
if (!start_time && end_time && state->cursor_offset >= 0) {
// Use stored cursor for sequential Page Up (skip bisect).
// Guard: when cursor lands on entries[0].byte_offset, the !from_start
// backup below produces an empty [X, X) range; falling back to the
// end_time bisect avoids permanently sticking page-up at the top.
if (!start_time && end_time && state->cursor_offset >= 0
&& state->n_entries > 0
&& state->cursor_offset != state->entries[0].byte_offset) {
read_to = state->cursor_offset;
} else if (end_time) {
// Upper-bound: find first index entry AFTER end_time