-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Storage Engines - Foundations
-
3,799.141
-
None
-
None
Problem
- Every truncate-list operation takes truncate_list.lock: __wt_truncate_delete_visible_check on each stable-side search, search_near, next/prev reposition and next_random; __wt_layered_table_truncate_detect_write_conflict on each ingest-routed insert/update/modify/reserve/remove; __wt_layered_table_truncate_detect_non_ingest_write_conflict on each truncate.
- The list is empty most of the time on tables that are not being truncated; the lock and the TAILQ_FOREACH are pure overhead there.
- Statistics layered_truncate_list_search_calls and layered_truncate_list_search_entries_walked show the cost but no "empty" fast path exists.
Scope
- Add an atomic entry count (or empty flag) to WT_TRUNCATE_LIST, maintained under the write lock in __txn_insert_truncate_entry_helper, __truncate_entry_remove and __wt_layered_table_truncate_clear.
- Return early from the three read-side functions when the count is zero, without taking the read lock.
- Ordering: a writer's early return on "empty" must not be weaker than today's lock-based check. A truncate appends its entry after its ingest scan (the check-then-insert window already exists), so a relaxed load does not introduce a new race; document this in the code.
- Out of scope: sorting or replacing the data structure (WT-17330); GC timing.
Definition of Done
- Atomic empty check in place; no read lock taken when the list is empty.
- Catch2 test: count tracks insert, rollback, GC and clear.
- Python test or statistic assertion: no layered_truncate_list_search_calls growth on a follower table with an empty list.