Rebuild index on startup

This commit is contained in:
Antoine Gersant 2024-07-29 21:54:07 -07:00
parent 8db6a2352b
commit 1f3cc1ea26
4 changed files with 55 additions and 21 deletions

View file

@ -20,6 +20,8 @@ pub mod test;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error { pub enum Error {
#[error(transparent)]
Collection(#[from] collection::Error),
#[error(transparent)] #[error(transparent)]
Config(#[from] config::Error), Config(#[from] config::Error),
#[error(transparent)] #[error(transparent)]
@ -72,7 +74,8 @@ impl App {
index_manager.clone(), index_manager.clone(),
settings_manager.clone(), settings_manager.clone(),
vfs_manager.clone(), vfs_manager.clone(),
); )
.await?;
let config_manager = config::Manager::new( let config_manager = config::Manager::new(
settings_manager.clone(), settings_manager.clone(),
user_manager.clone(), user_manager.clone(),

View file

@ -61,13 +61,15 @@ pub(super) struct IndexBuilder {
} }
impl IndexBuilder { impl IndexBuilder {
pub fn add_song(&mut self, song: &collection::Song) { pub fn add_song(&mut self, song: collection::Song) {
self.songs.insert(song.into(), song.clone()); let song_id: SongID = song.song_id();
self.add_song_to_album(song); self.add_song_to_album(&song);
self.songs.insert(song_id, song);
} }
fn add_song_to_album(&mut self, song: &collection::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) { let album = match self.albums.get_mut(&album_id) {
Some(l) => l, Some(l) => l,
@ -97,7 +99,7 @@ impl IndexBuilder {
album.artists = song.artists.0.clone(); album.artists = song.artists.0.clone();
} }
album.songs.insert(song.into()); album.songs.insert(song_id);
} }
pub fn build(self) -> Index { pub fn build(self) -> Index {
@ -168,9 +170,9 @@ impl From<&SongKey> for SongID {
} }
} }
impl From<&collection::Song> for SongID { impl collection::Song {
fn from(song: &collection::Song) -> Self { pub(self) fn song_id(&self) -> SongID {
let key: SongKey = song.into(); let key: SongKey = self.into();
(&key).into() (&key).into()
} }
} }
@ -214,9 +216,9 @@ impl From<&AlbumKey> for AlbumID {
} }
} }
impl From<&collection::Song> for AlbumID { impl collection::Song {
fn from(song: &collection::Song) -> Self { pub(self) fn album_id(&self) -> AlbumID {
let key: AlbumKey = song.into(); let key: AlbumKey = self.into();
(&key).into() (&key).into()
} }
} }

View file

@ -21,13 +21,13 @@ pub struct Updater {
} }
impl Updater { impl Updater {
pub fn new( pub async fn new(
db: DB, db: DB,
index_manager: IndexManager, index_manager: IndexManager,
settings_manager: settings::Manager, settings_manager: settings::Manager,
vfs_manager: vfs::Manager, vfs_manager: vfs::Manager,
) -> Self { ) -> Result<Self, Error> {
let updater = Self { let mut updater = Self {
db, db,
index_manager, index_manager,
vfs_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) { 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> { pub async fn update(&mut self) -> Result<(), Error> {
let start = Instant::now(); let start = Instant::now();
info!("Beginning library index update"); info!("Beginning collection scan");
let cleaner = Cleaner::new(self.db.clone(), self.vfs_manager.clone()); let cleaner = Cleaner::new(self.db.clone(), self.vfs_manager.clone());
cleaner.clean().await?; cleaner.clean().await?;
@ -134,7 +161,7 @@ impl Updater {
0 => break, 0 => break,
_ => { _ => {
for song in buffer.drain(0..) { for song in buffer.drain(0..) {
index_builder.add_song(&song); index_builder.add_song(song.clone());
song_inserter.insert(song).await; song_inserter.insert(song).await;
} }
} }
@ -148,7 +175,7 @@ impl Updater {
self.index_manager.replace_index(index).await; self.index_manager.replace_index(index).await;
info!( info!(
"Library index update took {} seconds", "Collection scan took {} seconds",
start.elapsed().as_millis() as f32 / 1000.0 start.elapsed().as_millis() as f32 / 1000.0
); );

View file

@ -74,7 +74,9 @@ impl ContextBuilder {
index_manager.clone(), index_manager.clone(),
settings_manager.clone(), settings_manager.clone(),
vfs_manager.clone(), vfs_manager.clone(),
); )
.await
.unwrap();
let playlist_manager = playlist::Manager::new(db.clone(), vfs_manager.clone()); let playlist_manager = playlist::Manager::new(db.clone(), vfs_manager.clone());
config_manager.apply(&self.config).await.unwrap(); config_manager.apply(&self.config).await.unwrap();