aboutsummaryrefslogtreecommitdiffstats
path: root/src/DatabaseHelpers.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-08-15 22:20:28 +0200
committerMax Kellermann <max@duempel.org>2012-08-15 23:05:08 +0200
commit3c0dea811d498db3091dad868740c4653c22717e (patch)
tree698de51e854a052d43cb3f872a5aee5b608fb71f /src/DatabaseHelpers.cxx
parenta6ac0f89656b9ef374703d24bbb27316a705eadc (diff)
downloadmpd-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.cxx56
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;
+}