command/file: cache the last "albumart" file
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1156
This commit is contained in:
parent
e1e41708af
commit
dbb18a401b
1
NEWS
1
NEWS
@ -1,6 +1,7 @@
|
|||||||
ver 0.22.7 (not yet released)
|
ver 0.22.7 (not yet released)
|
||||||
* protocol
|
* protocol
|
||||||
- don't use glibc extension to parse time stamps
|
- don't use glibc extension to parse time stamps
|
||||||
|
- optimize the "albumart" command
|
||||||
* input
|
* input
|
||||||
- curl: send user/password in the first request, save one roundtrip
|
- curl: send user/password in the first request, save one roundtrip
|
||||||
* decoder
|
* decoder
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "Message.hxx"
|
#include "Message.hxx"
|
||||||
#include "command/CommandResult.hxx"
|
#include "command/CommandResult.hxx"
|
||||||
#include "command/CommandListBuilder.hxx"
|
#include "command/CommandListBuilder.hxx"
|
||||||
|
#include "input/LastInputStream.hxx"
|
||||||
#include "tag/Mask.hxx"
|
#include "tag/Mask.hxx"
|
||||||
#include "event/FullyBufferedSocket.hxx"
|
#include "event/FullyBufferedSocket.hxx"
|
||||||
#include "event/TimerEvent.hxx"
|
#include "event/TimerEvent.hxx"
|
||||||
@ -90,6 +91,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
size_t binary_limit = 8192;
|
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:
|
private:
|
||||||
static constexpr size_t MAX_SUBSCRIPTIONS = 16;
|
static constexpr size_t MAX_SUBSCRIPTIONS = 16;
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ Client::Client(EventLoop &_loop, Partition &_partition,
|
|||||||
partition(&_partition),
|
partition(&_partition),
|
||||||
permission(_permission),
|
permission(_permission),
|
||||||
uid(_uid),
|
uid(_uid),
|
||||||
num(_num)
|
num(_num),
|
||||||
|
last_album_art(_loop)
|
||||||
{
|
{
|
||||||
timeout_event.Schedule(client_timeout);
|
timeout_event.Schedule(client_timeout);
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,16 @@ read_stream_art(Response &r, const char *uri, size_t offset)
|
|||||||
{
|
{
|
||||||
const auto art_directory = PathTraitsUTF8::GetParent(uri);
|
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) {
|
if (is == nullptr) {
|
||||||
r.Error(ACK_ERROR_NO_EXIST, "No file exists");
|
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;
|
std::size_t read_size = 0;
|
||||||
if (buffer_size > 0) {
|
if (buffer_size > 0) {
|
||||||
std::unique_lock<Mutex> lock(mutex);
|
std::unique_lock<Mutex> lock(is->mutex);
|
||||||
is->Seek(lock, offset);
|
is->Seek(lock, offset);
|
||||||
read_size = is->Read(lock, buffer.get(), buffer_size);
|
read_size = is->Read(lock, buffer.get(), buffer_size);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user