From 70a1fc453f64aad246e1074df3303b275a9e3032 Mon Sep 17 00:00:00 2001 From: blasty Date: Mon, 10 Aug 2026 01:18:27 +0200 Subject: segment_index: the row total in one call instead of 458 The listing streams a whole segment for one reason -- to know how many rows it has, so the scrollbar and paging are right. Even as skeletons that is 458 round trips and 227k rows for a 1.2MB bash, none of which is displayed. segment_index walks the same items and counts what heads() WOULD emit, building none of them, and returns the total plus [row, ea] anchors every 500 rows. Measured on bash, same process and database: segment_index : 228,659 rows, 1 call, 501ms streaming : 228,659 rows, 458 calls, 1836ms 3.7x Exactness is the whole point, so it mirrors _rows_for's arithmetic rather than approximating it: 3 banner rows at a function start, a label row for a named code head that is not one, the head row, struct members for data, 2 footer rows at a function end, and an undefined run counted as its byte length because the client presents one collapsed row as that many logical rows. A count that is off by a handful means the scrollbar lies and a seek lands on the wrong row, so the test compares against a fully streamed model in the same process rather than against a tolerance, and checks that every anchor names the address of the row it claims. Getting that right took a false alarm worth recording: the count first looked 35 rows short of a model built by the pilot, which turned out to be a DIFFERENT DATABASE (tests run on a pristine scratch copy). Against the same database it matches exactly, head for head, with zero differing addresses. Nothing consumes this yet. Spending it means teaching ListingModel to hold sparse pages seeked through the anchors instead of one dense array grown from the segment start, which is a real change to the core view and wants its own run at it. Full gate: 1054 passed. --- idatui/codemode_client.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'idatui/codemode_client.py') diff --git a/idatui/codemode_client.py b/idatui/codemode_client.py index d0d1937..2361e08 100644 --- a/idatui/codemode_client.py +++ b/idatui/codemode_client.py @@ -1205,6 +1205,12 @@ _OPERATIONS["pc_num_format"] = _remote_op( # would reformat) and had no digest/expect support (so every page was re-sent # after any edit), and whose span walk was the per-character loop our own # version had already been rewritten to avoid. +#: Row count + seek anchors for a whole segment, in ONE call. See +#: remote_tools.segment_index: the alternative is fetching every row. +_OPERATIONS["segment_index"] = _remote_op( + 'segment_index(addr=a["addr"], end=a.get("end", ""),' + ' page_rows=int(a.get("page_rows", 500)))') + _HEADS = _remote_op( 'heads(addr=a["addr"], count=int(a.get("count", 200)),' ' offset=int(a.get("offset", 0)), end=a.get("end", ""),' -- cgit v1.3.1-sl0p