input/cache: first draft of the file cache

This commit is contained in:
Max Kellermann
2019-05-08 18:39:00 +02:00
parent e8a0ce643a
commit 5d74b5cee1
27 changed files with 880 additions and 6 deletions

View File

@@ -20,10 +20,15 @@
#include "config.h"
#include "Partition.hxx"
#include "Instance.hxx"
#include "Log.hxx"
#include "song/DetachedSong.hxx"
#include "mixer/Volume.hxx"
#include "IdleFlags.hxx"
#include "client/Listener.hxx"
#include "input/cache/Manager.hxx"
#include "util/Domain.hxx"
static constexpr Domain cache_domain("cache");
Partition::Partition(Instance &_instance,
const char *_name,
@@ -37,7 +42,9 @@ Partition::Partition(Instance &_instance,
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
playlist(max_length, *this),
outputs(*this),
pc(*this, outputs, buffer_chunks,
pc(*this, outputs,
instance.input_cache.get(),
buffer_chunks,
configured_audio_format, replay_gain_config)
{
UpdateEffectiveReplayGainMode();
@@ -51,6 +58,43 @@ Partition::EmitIdle(unsigned mask) noexcept
instance.EmitIdle(mask);
}
static void
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
{
if (cache.Contains(uri))
return;
FormatDebug(cache_domain, "Prefetch '%s'", uri);
try {
cache.Prefetch(uri);
} catch (...) {
FormatError(std::current_exception(),
"Prefetch '%s' failed", uri);
}
}
static void
PrefetchSong(InputCacheManager &cache, const DetachedSong &song) noexcept
{
PrefetchSong(cache, song.GetURI());
}
inline void
Partition::PrefetchQueue() noexcept
{
if (!instance.input_cache)
return;
auto &cache = *instance.input_cache;
int next = playlist.GetNextPosition();
if (next >= 0)
PrefetchSong(cache, playlist.queue.Get(next));
// TODO: prefetch more songs
}
void
Partition::UpdateEffectiveReplayGainMode() noexcept
{
@@ -106,6 +150,10 @@ void
Partition::SyncWithPlayer() noexcept
{
playlist.SyncWithPlayer(pc);
/* TODO: invoke this function in batches, to let the hard disk
spin down in between */
PrefetchQueue();
}
void