diff options
| author | blasty <blasty@local> | 2026-08-10 01:18:27 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-08-10 01:18:27 +0200 |
| commit | 70a1fc453f64aad246e1074df3303b275a9e3032 (patch) | |
| tree | f05bfca9c1050376d3bb06a71b37dc2b08576d54 /idatui/codemode_client.py | |
| parent | domain: build Head positionally, and drop a dead test from _as_int (diff) | |
| download | ida-tui-70a1fc453f64aad246e1074df3303b275a9e3032.tar.gz ida-tui-70a1fc453f64aad246e1074df3303b275a9e3032.tar.xz ida-tui-70a1fc453f64aad246e1074df3303b275a9e3032.zip | |
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.
Diffstat (limited to 'idatui/codemode_client.py')
| -rw-r--r-- | idatui/codemode_client.py | 6 |
1 files changed, 6 insertions, 0 deletions
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", ""),' |
