perf: round 5 — CalDAV cursor streaming, SPA interning gaps, NC href prefix, per-request micro-allocs
Seven benchmark-gated changes (benches/ROUND5.md; BEFORE/AFTER bench + equivalence gate each, rollback rule as ROUND2-4 — two intermediate CalDAV shapes measured worse and were themselves rolled back before shipping): - CalDAV whole-calendar responses (REPORT no-range/sync-collection, depth-1 collection PROPFIND, .ics GET): buffered double-residency → ONE window-ordered scan (MIN(start_time) OVER (PARTITION BY ical_uid)) streamed through a PG cursor, pages cut at UID boundaries. TTFB 23.3→11.0 ms (2.1x), peak heap 14.2→8.0 MiB at 4k events / 45→24 MiB at 12k, wall +9-15% (documented trade, ZIP-streaming class); both multistatus and ICS byte-identical to the buffered output. Rejected shapes kept in the doc: per-page GROUP-BY keyset (3-4x wall) and per-uid ANY hydration (~20 µs/index descent). - SPA listing interning gaps: folder/recent/favorites resources handlers (and the WebDAV pseudo-root) called raw Arc::from per row for the closed display set ROUND3 interned — now intern_display/intern_mime, 4→0 allocs/row, byte-identical Arc contents. - NC PROPFIND child hrefs: username + parent path encoded once per request instead of per child (543→165 ns/row, 13→4 allocs); native WebDAV href drops its intermediate encode String. - suggest enrichment: entity clone + field re-clones per keystroke row → consume + move (166.5→126.8 µs/200 rows, 20→7 allocs/row). - list_readable_by returns the cache's Arc (246→128 ns warm hit, 4→0 allocs) — deep Vec clone per DAV-selector request removed. - CardDAV REPORT: borrowed props, reused href buffer, exact-size etag quoting (3.04→2.34 ms per 5k-contact getetag poll). - Auth span records: user_id.to_string() per request ×3 → tracing::field::display. Checks: cargo fmt, clippy --all-features --all-targets -D warnings, cargo test --workspace (523 passed). Follow-ups (CardDAV streaming, &[&str] id batches, ::text UUID casts A/B, share-landing join) recorded in benches/ROUND5.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017aJu9ghvuT8WqC31ZEGTBA
This commit is contained in:
@@ -25,6 +25,18 @@ pub trait CalendarEventRepository: Send + Sync + 'static {
|
||||
/// Finds a calendar event by its ID
|
||||
async fn find_event_by_id(&self, id: &Uuid) -> CalendarEventRepositoryResult<CalendarEvent>;
|
||||
|
||||
/// Cursor stream over every event of `calendar_id` in bundle order:
|
||||
/// rows sorted by `(first occurrence per UID, uid, master-first,
|
||||
/// start_time)` so a recurring master + its exception overrides
|
||||
/// arrive adjacent and bundles appear in the first-appearance order
|
||||
/// the buffered `start_time` listing produced. ONE scan+sort on the
|
||||
/// server; the streaming CalDAV emitters cut pages at UID
|
||||
/// boundaries so only a page of rows is ever resident.
|
||||
fn stream_events_uid_order(
|
||||
&self,
|
||||
calendar_id: Uuid,
|
||||
) -> futures::stream::BoxStream<'static, CalendarEventRepositoryResult<CalendarEvent>>;
|
||||
|
||||
/// Lists all events in a specific calendar
|
||||
async fn list_events_by_calendar(
|
||||
&self,
|
||||
|
||||
@@ -172,10 +172,14 @@ pub trait DriveRepository: Send + Sync + 'static {
|
||||
/// Returns rows in a stable order: default drive first (if any),
|
||||
/// then by display name. The `/api/drives` handler relies on that
|
||||
/// order for the picker UI without a follow-up sort.
|
||||
/// Returned as `Arc<Vec<…>>`: warm hits are a refcount bump straight
|
||||
/// off the per-user cache instead of a deep clone of every row's
|
||||
/// Strings — this runs per DAV request with an explicit drive
|
||||
/// selector.
|
||||
async fn list_readable_by(
|
||||
&self,
|
||||
caller_id: Uuid,
|
||||
) -> Result<Vec<DriveWithRootName>, DriveRepositoryError>;
|
||||
) -> Result<std::sync::Arc<Vec<DriveWithRootName>>, DriveRepositoryError>;
|
||||
|
||||
/// `true` when the drive holds no live (non-trashed) folders other
|
||||
/// than its own root and no live files at all. Used by
|
||||
|
||||
Reference in New Issue
Block a user