Add two-level audio cache system (L1: memory, L2: disk)
L1 (Memory): 300MB for ~3-4 Hi-Res tracks, instant access L2 (Disk): 500MB playback cache at ~/.cache/qbz/playback/ Flow: - When track evicted from memory, saved to disk cache - When loading: check memory → disk → download cache → network - Tracks promoted back to memory when accessed from disk This reduces re-downloads when navigating back to recently played tracks in mixed playlists.
This commit is contained in:
1 parent
2bdde3d592
commit
73d022ae20
5 files changed
+406
-24
No files matched your search
@@ -53,7 +53,7 @@ pub async fn play_track(
|
||||
|
||||
let cache = state.audio_cache.clone();
|
||||
|
||||
// Check if track is in memory cache
|
||||
// Check if track is in memory cache (L1)
|
||||
if let Some(cached) = cache.get(track_id) {
|
||||
log::info!("Playing track {} from memory cache ({} bytes)", track_id, cached.size_bytes);
|
||||
state.player.play_data(cached.data, track_id)?;
|
||||
@@ -68,8 +68,29 @@ pub async fn play_track(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Check if track is in playback cache (L2 - disk)
|
||||
if let Some(playback_cache) = cache.get_playback_cache() {
|
||||
if let Some(audio_data) = playback_cache.get(track_id) {
|
||||
log::info!("Playing track {} from playback cache ({} bytes)", track_id, audio_data.len());
|
||||
|
||||
// Promote back to memory cache
|
||||
cache.insert(track_id, audio_data.clone());
|
||||
|
||||
state.player.play_data(audio_data, track_id)?;
|
||||
|
||||
// Prefetch next track in background
|
||||
spawn_prefetch(
|
||||
state.client.clone(),
|
||||
state.audio_cache.clone(),
|
||||
&state.queue,
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// Not in any cache - download and cache in memory
|
||||
log::info!("Track {} not in cache, streaming...", track_id);
|
||||
log::info!("Track {} not in any cache, streaming...", track_id);
|
||||
|
||||
let client = state.client.lock().await;
|
||||
|
||||
|
||||
Reference in new issue
Block a user