Commit Diff


commit - 5b31cfc4bd8e518922ddf6fdd4480c69fd8ec7fa
commit + 777c402909372bd380b73ddc0019630a789db099
blob - d2a3c776841c370e0c92e468ffc380f7565ace62
blob + 9b4b51299dbdf1b1309cf4c534c3de42f082f2af
--- src/db.rs
+++ src/db.rs
@@ -40,6 +40,7 @@ pub struct LibraryDb {
 }
 
 const SEP: u8 = 0x00;
+const BPM_KEY_LEN: usize = 8;
 
 fn prefix_index_key(value: &[u8], primary_key: &[u8]) -> Vec<u8> {
     let mut buf = Vec::with_capacity(value.len() + 1 + primary_key.len());
@@ -50,7 +51,7 @@ fn prefix_index_key(value: &[u8], primary_key: &[u8]) 
 }
 
 fn bpm_index_key(bpm: f64, primary_key: &[u8]) -> Vec<u8> {
-    let mut buf = Vec::with_capacity(8 + 1 + primary_key.len());
+    let mut buf = Vec::with_capacity(BPM_KEY_LEN + 1 + primary_key.len());
     buf.extend_from_slice(&bpm.to_be_bytes());
     buf.push(SEP);
     buf.extend_from_slice(primary_key);
@@ -276,9 +277,16 @@ impl LibraryDb {
     pub fn find_by_bpm_range(&self, min: f64, max: f64) -> Result<Vec<(String, TrackReport)>> {
         let mut results = Vec::new();
 
-        for item in self.bpm_tree.range(min.to_be_bytes()..=max.to_be_bytes()) {
+        // Sled sorts longer keys after their prefix, so a bare 8-byte bound would
+        // exclude keys like [max_be, 0x00, primary_key].
+        let mut upper = Vec::with_capacity(BPM_KEY_LEN + 1);
+        upper.extend_from_slice(&max.to_be_bytes());
+        upper.push(0xFF);
+
+        for item in self.bpm_tree.range(min.to_be_bytes().as_slice()..upper.as_slice()) {
             let (idx_key, _) = item.context("Failed to read bpm index")?;
-            let primary_key_bytes = extract_primary_key(&idx_key)?;
+            // Primary key starts after 8-byte BPM + 1-byte separator.
+            let primary_key_bytes = &idx_key[BPM_KEY_LEN + 1..];
             let primary_key = String::from_utf8(primary_key_bytes.to_vec())
                 .context("Invalid UTF-8 in primary key")?;