From 1c958e85251c83e4ca24c2a7490a4b9e8458f07b Mon Sep 17 00:00:00 2001 From: Ilja Heitlager Date: Mon, 31 Aug 2026 11:39:45 +0200 Subject: [PATCH] perf: leak names in BtreeError::InvalidRootPage/MasterEntryNotFound Replaces the owned `String` in these two cold sqlite_master corruption/lookup variants with a leaked `&'static str`, removing their drop glue. This is intentional: both variants are only constructed on rare error paths (corrupt rootpage, missing schema entry during delete), so leaking the handful of bytes is a deliberate trade against the drop cost these variants otherwise impose on every Result<_, BtreeError> in TableCursor::seek's hot per-page binary search. std::mem::needs_drop::() still returns true overall because BtreeError::Pager(PagerError) transitively owns a `path: String` (PagerError::HotJournal/Wal) -- fixing that is a separate, out-of-scope change (see PR description). Refs: follow-up to #677, closes #679 --- src/btree/error.rs | 19 ++++++++++++------- src/btree/master.rs | 6 +++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/btree/error.rs b/src/btree/error.rs index d2660ec3..28100efb 100644 --- a/src/btree/error.rs +++ b/src/btree/error.rs @@ -131,17 +131,25 @@ pub enum BtreeError { KeyNotFound, /// A `sqlite_master` entry names a rootpage number outside the valid page range. + /// + /// `name` is leaked (via [`Box::leak`]) rather than owned as a `String`: + /// this is a cold, rare corruption-detection path, and leaking here keeps + /// `BtreeError` itself free of drop glue (`needs_drop::() == + /// false`), which matters because it is constructed on the hot + /// `TableCursor::seek` path (see #679). InvalidRootPage { /// Name of the offending `sqlite_master` entry. - name: String, + name: &'static str, /// Out-of-range rootpage value. rootpage: i64, }, /// A delete targeted a `sqlite_master` entry that does not exist. + /// + /// `name` is leaked for the same reason as [`BtreeError::InvalidRootPage`]. MasterEntryNotFound { /// Name of the entry that could not be found. - name: String, + name: &'static str, }, /// An internal invariant was violated; the message describes what was expected. @@ -369,17 +377,14 @@ mod tests { ); assert_eq!( BtreeError::InvalidRootPage { - name: "t".to_string(), + name: "t", rootpage: -1 } .to_string(), "sqlite_master entry \"t\" has out-of-range rootpage -1" ); assert_eq!( - BtreeError::MasterEntryNotFound { - name: "t".to_string() - } - .to_string(), + BtreeError::MasterEntryNotFound { name: "t" }.to_string(), "cannot delete sqlite_master entry \"t\": no such entry" ); assert_eq!( diff --git a/src/btree/master.rs b/src/btree/master.rs index 5e9cf618..6ff8fdb3 100644 --- a/src/btree/master.rs +++ b/src/btree/master.rs @@ -168,7 +168,7 @@ pub fn delete_master_row( header.text_encoding, )? .ok_or_else(|| BtreeError::MasterEntryNotFound { - name: name.to_string(), + name: Box::leak(name.to_string().into_boxed_str()), })?; super::delete_row(pager, header, SQLITE_MASTER_ROOT_PAGE, rowid) } @@ -225,12 +225,12 @@ fn find_master_rootpage( if let (Some(Value::Text(n)), Some(Value::Integer(rp))) = (values.get(1), values.get(3)) { if n.as_ref() == name { let rootpage = u32::try_from(*rp).map_err(|_| BtreeError::InvalidRootPage { - name: name.to_string(), + name: Box::leak(name.to_string().into_boxed_str()), rootpage: *rp, })?; if rootpage == 0 { return Err(BtreeError::InvalidRootPage { - name: name.to_string(), + name: Box::leak(name.to_string().into_boxed_str()), rootpage: *rp, }); }