perf: round 16 — shares-lane & contextMap incremental builders, folder/href/disposition/preview alloc cuts
Finishes the route-level half of the O(N²/page) grouped-listing class ROUND15 fixed inside ResourceList, plus a backend CPU/alloc micro-pack. Every change is benchmark-gated with a hard rollback rule; no PostgreSQL needed for any arm (benches/ROUND16.md). Frontend (vitest): - F1 "My shares" lanes: the `lanes` $derived.by re-bucketed the whole accumulated grant list on every page and every grant edit. SharedLanesBuilder re-emits only the fresh page (fan-out + first-appearance header), reusing untouched lanes' array refs. 25.5x fewer emit calls, 8.8x wall, O(N²/page)→O(N). - F2 contextMap (trash/recent/favorites/shared-with-me): each rebuilt a fresh N-key Map, re-hashing every accumulated id, per page. primeContextPage holds a persistent SvelteMap primed per page (the shipped favoriteIds shape). 25.5x fewer entry calls, 7.2x wall. - Extracted the shared O(1) append test (isAppendExtension); F1's gate re-covers it. Backend (counting-allocator): - M1 folder display constants Arc::from -> intern_display (3 sites): 3 -> 0 allocs/row. - M2 build_content_disposition (every download + Range seek): 3 -> 1 alloc, 6x, 2.67x wall. - M3 nc_href (every NC PROPFIND/REPORT href): Vec+join+format -> one pre-sized buffer, keeping urlencoding::encode (byte-identical). 38 -> 27 allocs/op. - M4 NC preview fileId: collect-then-parse -> borrow-slice parse. 4 -> 0 allocs. Gates: sharedLanes/listContext.bench.test.ts, examples/bench_round16_micro.rs (GATE PASS all sections). Frontend: vitest 331 pass, svelte-check clean. Backend: clippy -D warnings clean, 524 lib tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193NjactJVqfU32gxeJDj8m
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
||||
import { primeContextPage } from '$lib/utils/listContext';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import { useOwnerCache } from '$lib/composables/useOwnerCache.svelte';
|
||||
import { errorToast } from '$lib/utils/errors';
|
||||
@@ -52,11 +53,10 @@
|
||||
// items on this page are favorites — pass every id in `favoriteIds`
|
||||
// so the star widget lights up universally.
|
||||
const items = $derived(raw.map((it) => it.resource as FileItem | FolderItem));
|
||||
const contextMap = $derived(
|
||||
new Map<string, ItemContext>(
|
||||
raw.map((it) => [it.resource.id, { date: it.favorited_at } satisfies ItemContext])
|
||||
)
|
||||
);
|
||||
// Persistent reactive map, primed per page in `load()` (benches/ROUND16.md §F2)
|
||||
// instead of rebuilding a fresh Map that re-hashes the whole accumulated list
|
||||
// on every infinite-scroll page. Mirrors the sibling `favoriteIds` SvelteSet.
|
||||
const contextMap = new SvelteMap<string, ItemContext>();
|
||||
// Persistent reactive set, updated in place per page (add the fresh page's
|
||||
// ids; clear on reset) instead of rebuilding a brand-new SvelteSet over the
|
||||
// whole accumulated list on every infinite-scroll page — that was O(N²)
|
||||
@@ -117,6 +117,10 @@
|
||||
// reset, then add only this page's ids (benches/ROUND14.md §F2).
|
||||
if (reset) favoriteIds.clear();
|
||||
for (const it of page.items) favoriteIds.add(it.resource.id);
|
||||
primeContextPage(contextMap, reset, page.items, (it) => [
|
||||
it.resource.id,
|
||||
{ date: it.favorited_at }
|
||||
]);
|
||||
cursor = page.next_cursor;
|
||||
void owners.resolve(page.items.map((i) => i.resource.created_by));
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user