Skip to content

Commit 05fb28d

Browse files
committed
improve: Message LRU decrypt-on-demand
A powerful LRU cache that only preloads the bare minimum messages required, meshes Procedural Loading with a powerful self-evicting cache, and a hot NIP-59 decryptor cache to swiftly skip repeat events without needing to decrypt them, and without hitting the DB at each event. This commit drops RAM use by 33.4% on an account with 74k messages, vastly decreases startup time, and vastly decreases CPU usage across the board.
1 parent 770b336 commit 05fb28d

File tree

11 files changed

+1361
-215
lines changed

11 files changed

+1361
-215
lines changed

src-tauri/src/account_manager.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ CREATE TABLE IF NOT EXISTS messages (
7070
at INTEGER NOT NULL,
7171
mine INTEGER NOT NULL,
7272
user_id INTEGER,
73+
wrapper_event_id TEXT,
7374
FOREIGN KEY (chat_id) REFERENCES chats(id) ON DELETE CASCADE,
7475
FOREIGN KEY (user_id) REFERENCES profiles(id) ON DELETE SET NULL
7576
);
7677
CREATE INDEX IF NOT EXISTS idx_messages_chat ON messages(chat_id, at);
7778
CREATE INDEX IF NOT EXISTS idx_messages_time ON messages(at DESC);
7879
CREATE INDEX IF NOT EXISTS idx_messages_user ON messages(user_id);
80+
CREATE INDEX IF NOT EXISTS idx_messages_wrapper ON messages(wrapper_event_id);
7981
8082
-- Settings table (key-value pairs)
8183
CREATE TABLE IF NOT EXISTS settings (
@@ -354,6 +356,10 @@ pub fn get_db_connection<R: Runtime>(handle: &AppHandle<R>) -> Result<rusqlite::
354356
conn.execute_batch("PRAGMA journal_mode=WAL;")
355357
.map_err(|e| format!("Failed to set WAL mode: {}", e))?;
356358

359+
// Run migrations to ensure schema is up to date
360+
// This is important for existing databases that may not have new columns
361+
run_migrations(&conn)?;
362+
357363
Ok(conn)
358364
}
359365

@@ -406,11 +412,45 @@ pub async fn init_profile_database<R: Runtime>(
406412
conn.execute_batch(SQL_SCHEMA)
407413
.map_err(|e| format!("Failed to create database schema: {}", e))?;
408414

415+
// Run migrations for existing databases
416+
run_migrations(&conn)?;
417+
409418
println!("[Account Manager] Database schema created successfully");
410419

411420
Ok(())
412421
}
413422

423+
/// Run database migrations for schema updates
424+
/// This handles adding new columns to existing tables
425+
fn run_migrations(conn: &rusqlite::Connection) -> Result<(), String> {
426+
// Migration 1: Add wrapper_event_id column to messages table
427+
// This column stores the public giftwrap event ID for fast duplicate detection
428+
let has_wrapper_column: bool = conn.query_row(
429+
"SELECT COUNT(*) FROM pragma_table_info('messages') WHERE name = 'wrapper_event_id'",
430+
[],
431+
|row| row.get::<_, i32>(0)
432+
).map(|count| count > 0)
433+
.unwrap_or(false);
434+
435+
if !has_wrapper_column {
436+
println!("[Migration] Adding wrapper_event_id column to messages table...");
437+
conn.execute(
438+
"ALTER TABLE messages ADD COLUMN wrapper_event_id TEXT",
439+
[]
440+
).map_err(|e| format!("Failed to add wrapper_event_id column: {}", e))?;
441+
442+
// Create index for fast lookups
443+
conn.execute(
444+
"CREATE INDEX IF NOT EXISTS idx_messages_wrapper ON messages(wrapper_event_id)",
445+
[]
446+
).map_err(|e| format!("Failed to create wrapper_event_id index: {}", e))?;
447+
448+
println!("[Migration] wrapper_event_id column added successfully");
449+
}
450+
451+
Ok(())
452+
}
453+
414454
/// Switch to a different account
415455
#[tauri::command]
416456
pub async fn switch_account<R: Runtime>(

src-tauri/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ impl SlimMessage {
259259
failed: false, // Default values
260260
mine: self.mine,
261261
npub: self.npub.clone(),
262+
wrapper_event_id: None, // Not stored in slim format
262263
}
263264
}
264265
}

0 commit comments

Comments
 (0)