command/file: cache the last "albumart" file

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1156
This commit is contained in:
Max Kellermann 2021-05-18 16:41:48 +02:00
parent e1e41708af
commit dbb18a401b
4 changed files with 21 additions and 4 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
ver 0.22.7 (not yet released)
* protocol
- don't use glibc extension to parse time stamps
- optimize the "albumart" command
* input
- curl: send user/password in the first request, save one roundtrip
* decoder

View File

@ -23,6 +23,7 @@
#include "Message.hxx"
#include "command/CommandResult.hxx"
#include "command/CommandListBuilder.hxx"
#include "input/LastInputStream.hxx"
#include "tag/Mask.hxx"
#include "event/FullyBufferedSocket.hxx"
#include "event/TimerEvent.hxx"
@ -90,6 +91,13 @@ public:
*/
size_t binary_limit = 8192;
/**
* This caches the last "albumart" InputStream instance, to
* avoid repeating the search for each chunk requested by this
* client.
*/
LastInputStream last_album_art;
private:
static constexpr size_t MAX_SUBSCRIPTIONS = 16;

View File

@ -44,7 +44,8 @@ Client::Client(EventLoop &_loop, Partition &_partition,
partition(&_partition),
permission(_permission),
uid(_uid),
num(_num)
num(_num),
last_album_art(_loop)
{
timeout_event.Schedule(client_timeout);
}

View File

@ -191,9 +191,16 @@ read_stream_art(Response &r, const char *uri, size_t offset)
{
const auto art_directory = PathTraitsUTF8::GetParent(uri);
Mutex mutex;
// TODO: eliminate this const_cast
auto &client = const_cast<Client &>(r.GetClient());
InputStreamPtr is = find_stream_art(art_directory, mutex);
/* to avoid repeating the search for each chunk request by the
same client, use the #LastInputStream class to cache the
#InputStream instance */
auto *is = client.last_album_art.Open(art_directory, [](std::string_view directory,
Mutex &mutex){
return find_stream_art(directory, mutex);
});
if (is == nullptr) {
r.Error(ACK_ERROR_NO_EXIST, "No file exists");
@ -219,7 +226,7 @@ read_stream_art(Response &r, const char *uri, size_t offset)
std::size_t read_size = 0;
if (buffer_size > 0) {
std::unique_lock<Mutex> lock(mutex);
std::unique_lock<Mutex> lock(is->mutex);
is->Seek(lock, offset);
read_size = is->Read(lock, buffer.get(), buffer_size);
}