From 971b46be453f3f9452985ed0ffb2fadd7d37df68 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Mon, 23 Sep 2024 20:35:16 -0700 Subject: [PATCH] Store search index fields in array --- Cargo.lock | 22 ++++++++++++ Cargo.toml | 1 + src/app/index/query.rs | 5 +-- src/app/index/search.rs | 79 +++++++++++------------------------------ 4 files changed, 46 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8c65294..56fe61ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -631,6 +631,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1669,6 +1690,7 @@ dependencies = [ "chumsky", "daemonize", "embed-resource", + "enum-map", "getopts", "headers", "http 1.1.0", diff --git a/Cargo.toml b/Cargo.toml index 555beb1e..852c6bde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ base64 = "0.22.1" bitcode = { version = "0.6.3", features = ["serde"] } branca = "0.10.1" chumsky = "0.9.3" +enum-map = { version = "2.7.3", features = ["serde"] } getopts = "0.2.21" headers = "0.4" http = "1.1.0" diff --git a/src/app/index/query.rs b/src/app/index/query.rs index 9085c1b1..69f585d5 100644 --- a/src/app/index/query.rs +++ b/src/app/index/query.rs @@ -6,9 +6,10 @@ use chumsky::{ text::{int, keyword, whitespace, TextParser}, Parser, }; +use enum_map::Enum; use serde::{Deserialize, Serialize}; -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Enum, Eq, Hash, PartialEq, Serialize)] pub enum TextField { Album, AlbumArtist, @@ -27,7 +28,7 @@ pub enum TextOp { Like, } -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Enum, Eq, Hash, PartialEq, Serialize)] pub enum NumberField { DiscNumber, TrackNumber, diff --git a/src/app/index/search.rs b/src/app/index/search.rs index fd35aa58..8c4f0376 100644 --- a/src/app/index/search.rs +++ b/src/app/index/search.rs @@ -1,4 +1,5 @@ use chumsky::Parser; +use enum_map::EnumMap; use lasso2::{RodeoReader, Spur}; use nohash_hasher::{IntMap, IntSet}; use serde::{Deserialize, Serialize}; @@ -24,8 +25,8 @@ use super::{ #[derive(Serialize, Deserialize)] pub struct Search { - text_fields: HashMap, - number_fields: HashMap, + text_fields: EnumMap, + number_fields: EnumMap, } impl Default for Search { @@ -149,13 +150,9 @@ impl Search { operator: TextOp, value: &str, ) -> IntSet { - let Some(field_index) = self.text_fields.get(&field) else { - return IntSet::default(); - }; - match operator { - TextOp::Eq => field_index.find_exact(canon, value), - TextOp::Like => field_index.find_like(strings, value), + TextOp::Eq => self.text_fields[field].find_exact(canon, value), + TextOp::Like => self.text_fields[field].find_like(strings, value), } } @@ -165,10 +162,7 @@ impl Search { operator: NumberOp, value: i32, ) -> IntSet { - let Some(field_index) = self.number_fields.get(&field) else { - return IntSet::default(); - }; - field_index.find(value as i64, operator) + self.number_fields[field].find(value as i64, operator) } } @@ -267,8 +261,8 @@ impl NumberFieldIndex { #[derive(Default)] pub struct Builder { - text_fields: HashMap, - number_fields: HashMap, + text_fields: EnumMap, + number_fields: EnumMap, } impl Builder { @@ -278,10 +272,7 @@ impl Builder { }; if let (Some(str), Some(spur)) = (&scanner_song.album, storage_song.album) { - self.text_fields - .entry(TextField::Album) - .or_default() - .insert(str, spur, song_key); + self.text_fields[TextField::Album].insert(str, spur, song_key); } for (str, spur) in scanner_song @@ -289,17 +280,11 @@ impl Builder { .iter() .zip(storage_song.album_artists.iter()) { - self.text_fields - .entry(TextField::AlbumArtist) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::AlbumArtist].insert(str, *spur, song_key); } for (str, spur) in scanner_song.artists.iter().zip(storage_song.artists.iter()) { - self.text_fields - .entry(TextField::Artist) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::Artist].insert(str, *spur, song_key); } for (str, spur) in scanner_song @@ -307,31 +292,19 @@ impl Builder { .iter() .zip(storage_song.composers.iter()) { - self.text_fields - .entry(TextField::Composer) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::Composer].insert(str, *spur, song_key); } if let Some(disc_number) = &scanner_song.disc_number { - self.number_fields - .entry(NumberField::DiscNumber) - .or_default() - .insert(*disc_number, song_key); + self.number_fields[NumberField::DiscNumber].insert(*disc_number, song_key); } for (str, spur) in scanner_song.genres.iter().zip(storage_song.genres.iter()) { - self.text_fields - .entry(TextField::Genre) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::Genre].insert(str, *spur, song_key); } for (str, spur) in scanner_song.labels.iter().zip(storage_song.labels.iter()) { - self.text_fields - .entry(TextField::Label) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::Label].insert(str, *spur, song_key); } for (str, spur) in scanner_song @@ -339,37 +312,25 @@ impl Builder { .iter() .zip(storage_song.lyricists.iter()) { - self.text_fields - .entry(TextField::Lyricist) - .or_default() - .insert(str, *spur, song_key); + self.text_fields[TextField::Lyricist].insert(str, *spur, song_key); } - self.text_fields.entry(TextField::Path).or_default().insert( + self.text_fields[TextField::Path].insert( scanner_song.virtual_path.to_string_lossy().as_ref(), storage_song.virtual_path.0, song_key, ); if let (Some(str), Some(spur)) = (&scanner_song.title, storage_song.title) { - self.text_fields - .entry(TextField::Title) - .or_default() - .insert(str, spur, song_key); + self.text_fields[TextField::Title].insert(str, spur, song_key); } if let Some(track_number) = &scanner_song.track_number { - self.number_fields - .entry(NumberField::TrackNumber) - .or_default() - .insert(*track_number, song_key); + self.number_fields[NumberField::TrackNumber].insert(*track_number, song_key); } if let Some(year) = &scanner_song.year { - self.number_fields - .entry(NumberField::Year) - .or_default() - .insert(*year, song_key); + self.number_fields[NumberField::Year].insert(*year, song_key); } }