diff options
author | Max Kellermann <max@duempel.org> | 2012-08-15 22:20:28 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2012-08-15 23:05:08 +0200 |
commit | 3c0dea811d498db3091dad868740c4653c22717e (patch) | |
tree | 698de51e854a052d43cb3f872a5aee5b608fb71f /src/DatabaseHelpers.cxx | |
parent | a6ac0f89656b9ef374703d24bbb27316a705eadc (diff) | |
download | mpd-3c0dea811d498db3091dad868740c4653c22717e.tar.gz mpd-3c0dea811d498db3091dad868740c4653c22717e.tar.xz mpd-3c0dea811d498db3091dad868740c4653c22717e.zip |
DatabasePlugin: add method GetStats()
Optimize the ProxyDatabase by invoking "stats" on the peer, instead of
visiting all songs.
Diffstat (limited to '')
-rw-r--r-- | src/DatabaseHelpers.cxx | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/DatabaseHelpers.cxx b/src/DatabaseHelpers.cxx index 9a0931137..dc31a4bc2 100644 --- a/src/DatabaseHelpers.cxx +++ b/src/DatabaseHelpers.cxx @@ -76,3 +76,59 @@ VisitUniqueTags(const Database &db, const DatabaseSelection &selection, return true; } + +static void +StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums, + const struct tag &tag) +{ + if (tag.time > 0) + stats.total_duration += tag.time; + + for (unsigned i = 0; i < tag.num_items; ++i) { + const struct tag_item &item = *tag.items[i]; + + switch (item.type) { + case TAG_ARTIST: + artists.insert(item.value); + break; + + case TAG_ALBUM: + albums.insert(item.value); + break; + + default: + break; + } + } +} + +static bool +StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums, + song &song) +{ + ++stats.song_count; + + if (song.tag != nullptr) + StatsVisitTag(stats, artists, albums, *song.tag); + + return true; +} + +bool +GetStats(const Database &db, const DatabaseSelection &selection, + DatabaseStats &stats, GError **error_r) +{ + stats.Clear(); + + StringSet artists, albums; + using namespace std::placeholders; + const auto f = std::bind(StatsVisitSong, + std::ref(stats), std::ref(artists), + std::ref(albums), _1); + if (!db.Visit(selection, f, error_r)) + return false; + + stats.artist_count = artists.size(); + stats.album_count = albums.size(); + return true; +} |