aboutsummaryrefslogtreecommitdiffstats
path: root/src/tagTracker.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-08-29 09:38:31 +0200
committerMax Kellermann <max@duempel.org>2008-08-29 09:38:31 +0200
commitb731bbe93abd48e745d72958be0c253ade7a9d08 (patch)
tree2d39cd09d59abc156318f94349f8d7a2235737aa /src/tagTracker.c
parentad0e09b2db5ebf428acc98f90c3ef0dd171bebbb (diff)
downloadmpd-b731bbe93abd48e745d72958be0c253ade7a9d08.tar.gz
mpd-b731bbe93abd48e745d72958be0c253ade7a9d08.tar.xz
mpd-b731bbe93abd48e745d72958be0c253ade7a9d08.zip
removed tree.c
This patch makes MPD consume much more memory because string pooling is disabled, but it prepares the next bunch of patches. Replace the code in tagTracker.c with naive algorithms without the tree code. For now, this should do; later we should find better algorithms, especially for getNumberOfTagItems(), which has become wasteful with temporary memory.
Diffstat (limited to 'src/tagTracker.c')
-rw-r--r--src/tagTracker.c154
1 files changed, 69 insertions, 85 deletions
diff --git a/src/tagTracker.c b/src/tagTracker.c
index b75c42d7c..af94db1c1 100644
--- a/src/tagTracker.c
+++ b/src/tagTracker.c
@@ -19,126 +19,110 @@
#include "tagTracker.h"
#include "tag.h"
-#include "tree.h"
#include "utils.h"
#include "myfprintf.h"
+#include "directory.h"
-static Tree *tagTrees[TAG_NUM_OF_ITEM_TYPES];
+struct visited {
+ struct visited *next;
-typedef struct tagTrackerItem {
- int count;
- mpd_sint8 visited;
-} TagTrackerItem;
+ /**
+ * this is the original pointer passed to visitInTagTracker(),
+ * i.e. the caller must not invalidate it until he calls
+ * resetVisitedFlagsInTagTracker().
+ */
+ const char *value;
+} mpd_packed;
-char *getTagItemString(int type, char *string)
-{
- TreeIterator iter;
-
- if (tagTrees[type] == NULL)
- {
- tagTrees[type] = MakeTree((TreeCompareKeyFunction)strcmp,
- (TreeFreeFunction)free,
- (TreeFreeFunction)free);
- }
+static struct visited *visited_heads[TAG_NUM_OF_ITEM_TYPES];
+static unsigned num_visited[TAG_NUM_OF_ITEM_TYPES];
- if (FindInTree(tagTrees[type], string, &iter))
- {
- ((TagTrackerItem *)GetTreeKeyData(&iter)->data)->count++;
- return (char *)GetTreeKeyData(&iter)->key;
- }
- else
- {
- TagTrackerItem *item = xmalloc(sizeof(TagTrackerItem));
- char *key = xstrdup(string);
- item->count = 1;
- item->visited = 0;
- InsertInTree(tagTrees[type], key, item);
- return key;
- }
+char *getTagItemString(int type mpd_unused, char *string)
+{
+ return xstrdup(string);
}
-void removeTagItemString(int type, char *string)
+void removeTagItemString(int type mpd_unused, char *string)
{
- TreeIterator iter;
+ free(string);
+}
- assert(string);
+static int visit_tag_items(int fd mpd_unused, Song *song, void *data)
+{
+ enum tag_type type = (enum tag_type)(size_t)data;
+ unsigned i;
- assert(tagTrees[type]);
- if (tagTrees[type] == NULL)
- return;
+ if (song->tag == NULL)
+ return 0;
- if (FindInTree(tagTrees[type], string, &iter))
- {
- TagTrackerItem * item =
- (TagTrackerItem *)GetTreeKeyData(&iter)->data;
- item->count--;
- if (item->count <= 0)
- RemoveFromTreeByIterator(tagTrees[type], &iter);
+ for (i = 0; i < (unsigned)song->tag->numOfItems; ++i) {
+ const struct tag_item *item = song->tag->items[i];
+ if (item->type == type)
+ visitInTagTracker(type, item->value);
}
- if (GetTreeSize(tagTrees[type]) == 0)
- {
- FreeTree(tagTrees[type]);
- tagTrees[type] = NULL;
- }
+ return 0;
}
int getNumberOfTagItems(int type)
{
- if (tagTrees[type] == NULL)
- return 0;
+ int ret;
+
+ resetVisitedFlagsInTagTracker(type);
- return GetTreeSize(tagTrees[type]);
+ traverseAllIn(-1, NULL, visit_tag_items, NULL, (void*)(size_t)type);
+
+ ret = (int)num_visited[type];
+ resetVisitedFlagsInTagTracker(type);
+ return ret;
}
void resetVisitedFlagsInTagTracker(int type)
{
- TreeIterator iter;
+ while (visited_heads[type] != NULL) {
+ struct visited *v = visited_heads[type];
+ visited_heads[type] = v->next;
+ free(v);
+ }
- if (!tagTrees[type])
- return;
+ num_visited[type] = 0;
+}
- for (SetTreeIteratorToBegin(tagTrees[type], &iter);
- !IsTreeIteratorAtEnd(&iter);
- IncrementTreeIterator(&iter))
- {
- ((TagTrackerItem *)GetTreeKeyData(&iter)->data)->visited = 0;
- }
+static struct visited *
+find_visit(int type, const char *p)
+{
+ struct visited *v;
+
+ for (v = visited_heads[type]; v != NULL; v = v->next)
+ if (strcmp(v->value, p) == 0)
+ return v;
+
+ return NULL;
}
void visitInTagTracker(int type, const char *str)
{
- TreeIterator iter;
-
- if (!tagTrees[type])
- return;
+ struct visited *v = find_visit(type, str);
+ size_t length;
- if (!FindInTree(tagTrees[type], str, &iter))
+ if (v != NULL)
return;
- ((TagTrackerItem *)GetTreeKeyData(&iter)->data)->visited = 1;
+ length = strlen(str);
+ v = xmalloc(sizeof(*v));
+ v->value = str;
+ v->next = visited_heads[type];
+ visited_heads[type] = v;
+ ++num_visited[type];
}
void printVisitedInTagTracker(int fd, int type)
{
- TreeIterator iter;
- TagTrackerItem * item;
+ struct visited *v;
- if (!tagTrees[type])
- return;
-
- for (SetTreeIteratorToBegin(tagTrees[type], &iter);
- !IsTreeIteratorAtEnd(&iter);
- IncrementTreeIterator(&iter))
- {
- item = ((TagTrackerItem *)GetTreeKeyData(&iter)->data);
-
- if (item->visited)
- {
- fdprintf(fd,
- "%s: %s\n",
- mpdTagItemKeys[type],
- (char *)GetTreeKeyData(&iter)->key);
- }
- }
+ for (v = visited_heads[type]; v != NULL; v = v->next)
+ fdprintf(fd,
+ "%s: %s\n",
+ mpdTagItemKeys[type],
+ v->value);
}