aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-01-18 15:40:50 +0100
committerMax Kellermann <max@duempel.org>2009-01-18 15:40:50 +0100
commit14ca99b22469808642034813156281a203cfee5e (patch)
treee6a38e78d4fe52eb915198c04a8d1fd75ea8577c
parent91fb2a29deaafcc0ae9c710aec3c5cf54ce60d91 (diff)
downloadmpd-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.
-rw-r--r--src/dbUtils.c41
-rw-r--r--src/dbUtils.h2
-rw-r--r--src/stats.c74
3 files changed, 44 insertions, 73 deletions
diff --git a/src/dbUtils.c b/src/dbUtils.c
index 3677b2ae6..cd1476d9d 100644
--- a/src/dbUtils.c
+++ b/src/dbUtils.c
@@ -51,16 +51,6 @@ typedef struct _SearchStats {
} SearchStats;
static int
-countSongsInDirectory(struct directory *directory, void *data)
-{
- int *count = (int *)data;
-
- *count += directory->songs.nr;
-
- return 0;
-}
-
-static int
printDirectoryInDirectory(struct directory *directory, void *data)
{
struct client *client = data;
@@ -237,43 +227,12 @@ directoryPrintSongInfo(struct song *song, void *data)
return 0;
}
-static int
-sumSongTime(struct song *song, void *data)
-{
- unsigned long *sum_time = (unsigned long *)data;
-
- if (song->tag && song->tag->time >= 0)
- *sum_time += song->tag->time;
-
- return 0;
-}
-
int printInfoForAllIn(struct client *client, const char *name)
{
return db_walk(name, directoryPrintSongInfo,
printDirectoryInDirectory, client);
}
-int countSongsIn(const char *name)
-{
- int count = 0;
- void *ptr = (void *)&count;
-
- db_walk(name, NULL, countSongsInDirectory, ptr);
-
- return count;
-}
-
-unsigned long sumSongTimesIn(const char *name)
-{
- unsigned long dbPlayTime = 0;
- void *ptr = (void *)&dbPlayTime;
-
- db_walk(name, sumSongTime, NULL, ptr);
-
- return dbPlayTime;
-}
-
static ListCommandItem *newListCommandItem(int tagType, int numConditionals,
LocateTagItem * conditionals)
{
diff --git a/src/dbUtils.h b/src/dbUtils.h
index 1ccd75793..5c8e71604 100644
--- a/src/dbUtils.h
+++ b/src/dbUtils.h
@@ -40,8 +40,6 @@ int findSongsIn(struct client *client, const char *name,
int searchStatsForSongsIn(struct client *client, const char *name,
int numItems, LocateTagItem * items);
-int countSongsIn(const char *name);
-
unsigned long sumSongTimesIn(const char *name);
int listAllUniqueTags(struct client *client, int type, int numConditiionals,
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)