diff options
author | Max Kellermann <max@duempel.org> | 2009-01-18 15:40:50 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-01-18 15:40:50 +0100 |
commit | 14ca99b22469808642034813156281a203cfee5e (patch) | |
tree | e6a38e78d4fe52eb915198c04a8d1fd75ea8577c /src/stats.c | |
parent | 91fb2a29deaafcc0ae9c710aec3c5cf54ce60d91 (diff) | |
download | mpd-14ca99b22469808642034813156281a203cfee5e.tar.gz mpd-14ca99b22469808642034813156281a203cfee5e.tar.xz mpd-14ca99b22469808642034813156281a203cfee5e.zip |
stats: use one db_walk() to obtain stats
Don't use dbUtils.h functions. This reduces 4 full database walks to
just one.
Diffstat (limited to 'src/stats.c')
-rw-r--r-- | src/stats.c | 74 |
1 files changed, 44 insertions, 30 deletions
diff --git a/src/stats.c b/src/stats.c index 119b12456..c85c705d7 100644 --- a/src/stats.c +++ b/src/stats.c @@ -24,7 +24,6 @@ #include "client.h" #include "player_control.h" #include "strset.h" -#include "dbUtils.h" struct stats stats; @@ -34,50 +33,65 @@ void stats_global_init(void) } struct visit_data { - enum tag_type type; - struct strset *set; + struct strset *artists; + struct strset *albums; }; -static int -visit_tag_items(struct song *song, void *_data) +static void +visit_tag(struct visit_data *data, const struct tag *tag) { - const struct visit_data *data = _data; - unsigned i; + if (tag->time > 0) + stats.song_duration += tag->time; - if (song->tag == NULL) - return 0; + for (unsigned i = 0; i < tag->numOfItems; ++i) { + const struct tag_item *item = tag->items[i]; - for (i = 0; i < (unsigned)song->tag->numOfItems; ++i) { - const struct tag_item *item = song->tag->items[i]; - if (item->type == data->type) - strset_add(data->set, item->value); - } + switch (item->type) { + case TAG_ITEM_ARTIST: + strset_add(data->artists, item->value); + break; - return 0; + case TAG_ITEM_ALBUM: + strset_add(data->albums, item->value); + break; + + default: + break; + } + } } -static unsigned int -getNumberOfTagItems(enum tag_type type) +static int +stats_collect_song(struct song *song, void *_data) { - struct visit_data data = { - .type = type, - .set = strset_new(), - }; - unsigned int ret; + struct visit_data *data = _data; + + ++stats.song_count; - db_walk(NULL, visit_tag_items, NULL, &data); + if (song->tag != NULL) + visit_tag(data, song->tag); - ret = strset_size(data.set); - strset_free(data.set); - return ret; + return 0; } void stats_update(void) { - stats.song_count = countSongsIn(NULL); - stats.song_duration = sumSongTimesIn(NULL); - stats.artist_count = getNumberOfTagItems(TAG_ITEM_ARTIST); - stats.album_count = getNumberOfTagItems(TAG_ITEM_ALBUM); + struct visit_data data; + + stats.song_count = 0; + stats.song_duration = 0; + stats.artist_count = 0; + + data.artists = strset_new(); + data.albums = strset_new(); + + db_walk(NULL, stats_collect_song, NULL, &data); + + stats.artist_count = strset_size(data.artists); + stats.album_count = strset_size(data.albums); + + strset_free(data.artists); + strset_free(data.albums); } int stats_print(struct client *client) |