diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 13:54:10 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 13:54:10 +0300 |
| commit | 274abc013e4b914b005191a7f74eaf2961a1e59e (patch) | |
| tree | 1b515d6869cf8f63c5373b471c0c1b83a2da4e53 /src/hist_view.c | |
| parent | 4741f7a6dfa144ce65cf3bbdd4a1bc6bee6df2e5 (diff) | |
Optimize loops and data structures in hist.c and hist_view.c
- Unroll fast paths in put_varint and get_varint
- Replace while capacity loop with branchless term_grow_cap in runs_reserve
- Vectorize continuation ring rehash with slice memcpy in cont_push
- Fast-check simple line runs using combined bitwise XOR-OR mask in evict_simple_run
- Resume batch simple-run eviction on interrupted sweeps in evict_for
- Eliminate unused page_rows and page_simple allocations (>320 KB heap saved)
- Add zero-delta bypass in Fenwick tree set_count
- Replace iterative capacity loop with branchless term_next_pow2_32 in hist_view_sync
- Eliminate prefix-walk in term_hist_view_find_row by reusing Fenwick remainder
- Simplify upward and downward viewport movement in term_hist_view_scroll
Diffstat (limited to 'src/hist_view.c')
| -rw-r--r-- | src/hist_view.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/src/hist_view.c b/src/hist_view.c index d413c43..29eac35 100644 --- a/src/hist_view.c +++ b/src/hist_view.c @@ -40,6 +40,8 @@ static void set_count(struct hist_view *v, uint64_t id, uint32_t count) { uint32_t slot = (uint32_t)id & (v->cap - 1); int64_t delta = (int64_t)count - v->counts[slot]; + if (!delta) + return; v->counts[slot] = count; v->total_rows = (uint64_t)((int64_t)v->total_rows + delta); for (uint32_t i = slot + 1; i <= v->cap; i += i & -i) @@ -66,12 +68,11 @@ bool term_hist_view_sync(struct hist_view *v, const struct hist *h, int cols) rebuild = changed > v->cap / 4; } if (h->lines > v->cap || !v->cap) { - uint32_t cap = 16; - while (cap < h->lines) { - if (cap >= UINT32_MAX / 2) - return false; - cap *= 2; - } + if (h->lines > (UINT32_C(1) << 31)) + return false; + uint32_t cap = term_next_pow2_32(h->lines < 16 ? 16 : h->lines); + if (cap == UINT32_MAX) + return false; uint64_t *tree = calloc((size_t)cap + 1, sizeof(*tree)); uint32_t *counts = calloc(cap, sizeof(*counts)); if (!tree || !counts) { @@ -91,15 +92,14 @@ bool term_hist_view_sync(struct hist_view *v, const struct hist *h, int cols) memset(v->fenwick, 0, ((size_t)v->cap + 1) * sizeof(*v->fenwick)); for (uint64_t id = first; id < end; id++) v->counts[(uint32_t)id & (v->cap - 1)] = (uint32_t)term_hist_line_estimate(h, id, cols); - v->total_rows = 0; /* Build all tree nodes in one pass. */ for (uint32_t i = 1; i <= v->cap; i++) { v->fenwick[i] += v->counts[i - 1]; - v->total_rows += v->counts[i - 1]; uint32_t parent = i + (i & -i); if (parent <= v->cap) v->fenwick[parent] += v->fenwick[i]; } + v->total_rows = v->fenwick[v->cap]; } else { for (uint64_t id = v->first_id; id < first; id++) set_count(v, id, 0); @@ -140,25 +140,28 @@ uint64_t term_hist_view_rows(const struct hist_view *v, const struct hist *h, in /* Rows of the retained lines before id, in logical order. */ static uint64_t before(const struct hist_view *v, uint64_t id) { + if (id <= v->first_id) + return 0; uint32_t start = (uint32_t)v->first_id & (v->cap - 1); - uint64_t n = id - v->first_id; - uint32_t stop = start + (uint32_t)n; + uint32_t stop = start + (uint32_t)(id - v->first_id); + uint64_t p_start = prefix(v, start); if (stop <= v->cap) - return prefix(v, stop) - prefix(v, start); - return prefix(v, v->cap) - prefix(v, start) + prefix(v, stop - v->cap); + return prefix(v, stop) - p_start; + return v->total_rows - p_start + prefix(v, stop - v->cap); } /* Physical slot of a row in tree order. */ -static uint32_t select_slot(const struct hist_view *v, uint64_t row) +static uint32_t select_slot(const struct hist_view *v, uint64_t row, int *seg) { uint32_t slot = 0; - for (uint32_t bit = v->cap; bit; bit >>= 1) { + for (uint32_t bit = v->cap >> 1; bit; bit >>= 1) { uint32_t next = slot + bit; - if (next <= v->cap && v->fenwick[next] <= row) { + if (v->fenwick[next] <= row) { row -= v->fenwick[next]; slot = next; } } + *seg = (int)row; return slot; } @@ -186,9 +189,8 @@ bool term_hist_view_find_row(const struct hist_view *v, const struct hist *h, in uint32_t start = (uint32_t)v->first_id & (v->cap - 1); uint64_t low = prefix(v, start), high = total - low; uint64_t physical = (uint64_t)row < high ? low + row : (uint64_t)row - high; - uint32_t slot = select_slot(v, physical); + uint32_t slot = select_slot(v, physical, seg); *id = v->first_id + ((slot - start) & (v->cap - 1)); - *seg = (int)(physical - prefix(v, slot)); return true; } @@ -292,18 +294,21 @@ void term_hist_view_scroll(struct hist_view *v, const struct hist *h, int cols, seg = term_hist_line_rows(h, id, cols); } seg -= (int64_t)lines; - while (seg < 0 && id > hist_first_id(h)) - seg += term_hist_line_rows(h, --id, cols); - if (seg < 0) - seg = 0; - for (;;) { - int count = term_hist_line_rows(h, id, cols); - if (seg < count) - break; - seg -= count; - if (++id == hist_end_id(h)) { - term_hist_view_reset_bottom(v); - return; + if (lines > 0) { + while (seg < 0 && id > hist_first_id(h)) + seg += term_hist_line_rows(h, --id, cols); + if (seg < 0) + seg = 0; + } else { + for (;;) { + int count = term_hist_line_rows(h, id, cols); + if (seg < count) + break; + seg -= count; + if (++id == hist_end_id(h)) { + term_hist_view_reset_bottom(v); + return; + } } } v->anchor = (struct view_anchor){ .line_id = id, .seg = (uint32_t)seg, |
