Commit 85db2d67 authored by Max Kellermann's avatar Max Kellermann

db/proxy: split search into chunks to avoid exceeding the output buffer

parent 22ebb2bd
...@@ -5,6 +5,7 @@ ver 0.23 (not yet released) ...@@ -5,6 +5,7 @@ ver 0.23 (not yet released)
* database * database
- proxy: require MPD 0.20 or later - proxy: require MPD 0.20 or later
- proxy: require libmpdclient 2.11 or later - proxy: require libmpdclient 2.11 or later
- proxy: split search into chunks to avoid exceeding the output buffer
* output * output
- pipewire: new plugin - pipewire: new plugin
- snapcast: new plugin - snapcast: new plugin
......
...@@ -825,26 +825,48 @@ try { ...@@ -825,26 +825,48 @@ try {
const bool exact = selection.filter == nullptr || const bool exact = selection.filter == nullptr ||
!selection.filter->HasFoldCase(); !selection.filter->HasFoldCase();
if (!mpd_search_db_songs(connection, exact) || /* request only this number of songs at a time to avoid
!SendConstraints(connection, selection, selection.window) || blowing the server's max_output_buffer_size limit */
!mpd_search_commit(connection)) constexpr unsigned LIMIT = 4096;
ThrowError(connection);
while (auto *song = mpd_recv_song(connection)) { auto remaining_window = selection.window;
AllocatedProxySong song2(song);
if (Match(selection.filter, song2)) { while (remaining_window.start < remaining_window.end) {
try { auto window = remaining_window;
visit_song(song2); if (window.end - window.start > LIMIT)
} catch (...) { window.end = window.start + LIMIT;
mpd_response_finish(connection);
throw; if (!mpd_search_db_songs(connection, exact) ||
!SendConstraints(connection, selection, window) ||
!mpd_search_commit(connection))
ThrowError(connection);
while (auto *song = mpd_recv_song(connection)) {
++window.start;
AllocatedProxySong song2(song);
if (Match(selection.filter, song2)) {
try {
visit_song(song2);
} catch (...) {
mpd_response_finish(connection);
throw;
}
} }
} }
}
if (!mpd_response_finish(connection)) if (!mpd_response_finish(connection))
ThrowError(connection); ThrowError(connection);
if (window.start != window.end)
/* the other MPD has given us less than we
requested - this means there's no more
data */
break;
remaining_window.start = window.end;
}
} catch (...) { } catch (...) {
if (connection != nullptr) if (connection != nullptr)
mpd_search_cancel(connection); mpd_search_cancel(connection);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment