From 1f3cc1ea261b0cc211f1f7a43000f3a7e4ead877 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Mon, 29 Jul 2024 21:54:07 -0700 Subject: [PATCH] Rebuild index on startup --- src/app.rs | 5 +++- src/app/collection/index.rs | 24 ++++++++++--------- src/app/collection/updater.rs | 43 ++++++++++++++++++++++++++++------- src/app/test.rs | 4 +++- 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/app.rs b/src/app.rs index 96ff2f1..074640c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -20,6 +20,8 @@ pub mod test; #[derive(thiserror::Error, Debug)] pub enum Error { + #[error(transparent)] + Collection(#[from] collection::Error), #[error(transparent)] Config(#[from] config::Error), #[error(transparent)] @@ -72,7 +74,8 @@ impl App { index_manager.clone(), settings_manager.clone(), vfs_manager.clone(), - ); + ) + .await?; let config_manager = config::Manager::new( settings_manager.clone(), user_manager.clone(), diff --git a/src/app/collection/index.rs b/src/app/collection/index.rs index d9f8416..4e18427 100644 --- a/src/app/collection/index.rs +++ b/src/app/collection/index.rs @@ -61,13 +61,15 @@ pub(super) struct IndexBuilder { } impl IndexBuilder { - pub fn add_song(&mut self, song: &collection::Song) { - self.songs.insert(song.into(), song.clone()); - self.add_song_to_album(song); + pub fn add_song(&mut self, song: collection::Song) { + let song_id: SongID = song.song_id(); + self.add_song_to_album(&song); + self.songs.insert(song_id, song); } fn add_song_to_album(&mut self, song: &collection::Song) { - let album_id: AlbumID = song.into(); + let song_id: SongID = song.song_id(); + let album_id: AlbumID = song.album_id(); let album = match self.albums.get_mut(&album_id) { Some(l) => l, @@ -97,7 +99,7 @@ impl IndexBuilder { album.artists = song.artists.0.clone(); } - album.songs.insert(song.into()); + album.songs.insert(song_id); } pub fn build(self) -> Index { @@ -168,9 +170,9 @@ impl From<&SongKey> for SongID { } } -impl From<&collection::Song> for SongID { - fn from(song: &collection::Song) -> Self { - let key: SongKey = song.into(); +impl collection::Song { + pub(self) fn song_id(&self) -> SongID { + let key: SongKey = self.into(); (&key).into() } } @@ -214,9 +216,9 @@ impl From<&AlbumKey> for AlbumID { } } -impl From<&collection::Song> for AlbumID { - fn from(song: &collection::Song) -> Self { - let key: AlbumKey = song.into(); +impl collection::Song { + pub(self) fn album_id(&self) -> AlbumID { + let key: AlbumKey = self.into(); (&key).into() } } diff --git a/src/app/collection/updater.rs b/src/app/collection/updater.rs index bfc06c0..08df067 100644 --- a/src/app/collection/updater.rs +++ b/src/app/collection/updater.rs @@ -21,13 +21,13 @@ pub struct Updater { } impl Updater { - pub fn new( + pub async fn new( db: DB, index_manager: IndexManager, settings_manager: settings::Manager, vfs_manager: vfs::Manager, - ) -> Self { - let updater = Self { + ) -> Result { + let mut updater = Self { db, index_manager, vfs_manager, @@ -47,9 +47,9 @@ impl Updater { } }); - // TODO populate index w/ whatever is already in DB + updater.rebuild_index().await?; - updater + Ok(updater) } pub fn trigger_scan(&self) { @@ -76,9 +76,36 @@ impl Updater { }); } + async fn rebuild_index(&mut self) -> Result<(), Error> { + let start = Instant::now(); + info!("Rebuilding index from disk database"); + + let mut index_builder = IndexBuilder::default(); + + let mut connection = self.db.connect().await?; + let songs = sqlx::query_as!(Song, "SELECT * FROM songs") + .fetch_all(connection.as_mut()) + .await?; + + for song in songs { + index_builder.add_song(song); + } + + self.index_manager + .replace_index(index_builder.build()) + .await; + + info!( + "Index rebuild took {} seconds", + start.elapsed().as_millis() as f32 / 1000.0 + ); + + Ok(()) + } + pub async fn update(&mut self) -> Result<(), Error> { let start = Instant::now(); - info!("Beginning library index update"); + info!("Beginning collection scan"); let cleaner = Cleaner::new(self.db.clone(), self.vfs_manager.clone()); cleaner.clean().await?; @@ -134,7 +161,7 @@ impl Updater { 0 => break, _ => { for song in buffer.drain(0..) { - index_builder.add_song(&song); + index_builder.add_song(song.clone()); song_inserter.insert(song).await; } } @@ -148,7 +175,7 @@ impl Updater { self.index_manager.replace_index(index).await; info!( - "Library index update took {} seconds", + "Collection scan took {} seconds", start.elapsed().as_millis() as f32 / 1000.0 ); diff --git a/src/app/test.rs b/src/app/test.rs index beba59c..bfebef3 100644 --- a/src/app/test.rs +++ b/src/app/test.rs @@ -74,7 +74,9 @@ impl ContextBuilder { index_manager.clone(), settings_manager.clone(), vfs_manager.clone(), - ); + ) + .await + .unwrap(); let playlist_manager = playlist::Manager::new(db.clone(), vfs_manager.clone()); config_manager.apply(&self.config).await.unwrap();