summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-08-25 13:22:46 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-08-25 13:22:46 +0000
commite3080643537e778060f7456bc5777d369d6ffd20 (patch)
tree7890dda53faa147b41a7bf83a28a4c7b58d44269 /apps
parenta3ba6725cb445f81e25a009aab51317e7d4a7dc9 (diff)
downloadrockbox-e3080643537e778060f7456bc5777d369d6ffd20.zip
rockbox-e3080643537e778060f7456bc5777d369d6ffd20.tar.gz
rockbox-e3080643537e778060f7456bc5777d369d6ffd20.tar.bz2
rockbox-e3080643537e778060f7456bc5777d369d6ffd20.tar.xz
Tagcache: Don't show duplicate entries and automatically inherit
clauses for correct search results. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10746 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/tagcache.c89
-rw-r--r--apps/tagcache.h11
-rw-r--r--apps/tagtree.c23
3 files changed, 84 insertions, 39 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 191c245..195de2f 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -631,6 +631,30 @@ static bool check_against_clause(long numeric, const char *str,
return false;
}
+static bool add_uniqbuf(struct tagcache_search *tcs, long id)
+{
+ int i;
+
+ /* If uniq buffer is not defined we must return true for search to work. */
+ if (tcs->unique_list == NULL)
+ return true;
+
+ for (i = 0; i < tcs->unique_list_count; i++)
+ {
+ /* Return false if entry is found. */
+ if (tcs->unique_list[i] == id)
+ return false;
+ }
+
+ if (tcs->unique_list_count < tcs->unique_list_capacity)
+ {
+ tcs->unique_list[i] = id;
+ tcs->unique_list_count++;
+ }
+
+ return true;
+}
+
static bool build_lookup_list(struct tagcache_search *tcs)
{
struct index_entry entry;
@@ -699,22 +723,16 @@ static bool build_lookup_list(struct tagcache_search *tcs)
if (j < tcs->clause_count)
continue ;
- /* Add to the seek list if not already there. */
- for (j = 0; j < tcs->seek_list_count; j++)
- {
- if (tcs->seek_list[j] == hdr->indices[i].tag_seek[tcs->type])
- break ;
- }
-
+ /* Add to the seek list if not already in uniq buffer. */
+ if (!add_uniqbuf(tcs, hdr->indices[i].tag_seek[tcs->type]))
+ continue;
+
/* Lets add it. */
- if (j == tcs->seek_list_count)
- {
- tcs->seek_list[tcs->seek_list_count] =
- hdr->indices[i].tag_seek[tcs->type];
- tcs->seek_flags[tcs->seek_list_count] =
- hdr->indices[i].flag;
- tcs->seek_list_count++;
- }
+ tcs->seek_list[tcs->seek_list_count] =
+ hdr->indices[i].tag_seek[tcs->type];
+ tcs->seek_flags[tcs->seek_list_count] =
+ hdr->indices[i].flag;
+ tcs->seek_list_count++;
}
tcs->seek_pos = i;
@@ -783,22 +801,14 @@ static bool build_lookup_list(struct tagcache_search *tcs)
if (i < tcs->clause_count)
continue ;
- /* Add to the seek list if not already there. */
- for (i = 0; i < tcs->seek_list_count; i++)
- {
- if (tcs->seek_list[i] == entry.tag_seek[tcs->type])
- break ;
- }
-
+ /* Add to the seek list if not already in uniq buffer. */
+ if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type]))
+ continue;
+
/* Lets add it. */
- if (i == tcs->seek_list_count)
- {
- tcs->seek_list[tcs->seek_list_count] =
- entry.tag_seek[tcs->type];
- tcs->seek_flags[tcs->seek_list_count] = entry.flag;
- tcs->seek_list_count++;
- }
-
+ tcs->seek_list[tcs->seek_list_count] = entry.tag_seek[tcs->type];
+ tcs->seek_flags[tcs->seek_list_count] = entry.flag;
+ tcs->seek_list_count++;
}
return tcs->seek_list_count > 0;
@@ -913,6 +923,14 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
return true;
}
+void tagcache_search_set_uniqbuf(struct tagcache_search *tcs,
+ void *buffer, long length)
+{
+ tcs->unique_list = (unsigned long *)buffer;
+ tcs->unique_list_capacity = length / sizeof(*tcs->unique_list);
+ tcs->unique_list_count = 0;
+}
+
bool tagcache_search_add_filter(struct tagcache_search *tcs,
int tag, int seek)
{
@@ -932,12 +950,23 @@ bool tagcache_search_add_filter(struct tagcache_search *tcs,
bool tagcache_search_add_clause(struct tagcache_search *tcs,
struct tagcache_search_clause *clause)
{
+ int i;
+
if (tcs->clause_count >= TAGCACHE_MAX_CLAUSES)
{
logf("Too many clauses");
return false;
}
+ /* Check if there is already a similar filter in present (filters are
+ * much faster than clauses).
+ */
+ for (i = 0; i < tcs->filter_count; i++)
+ {
+ if (tcs->filter_tag[i] == clause->tag)
+ return true;
+ }
+
if (!tagcache_is_numeric_tag(clause->tag) && tcs->idxfd[clause->tag] < 0)
{
char buf[MAX_PATH];
diff --git a/apps/tagcache.h b/apps/tagcache.h
index e43414c..d9e1c93 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -51,13 +51,13 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
#define TAGFILE_ENTRY_AVG_LENGTH 16
/* How many entries to fetch to the seek table at once while searching. */
-#define SEEK_LIST_SIZE 50
+#define SEEK_LIST_SIZE 32
/* Always strict align entries for best performance and binary compatability. */
#define TAGCACHE_STRICT_ALIGN 1
-#define TAGCACHE_MAX_FILTERS 3
-#define TAGCACHE_MAX_CLAUSES 10
+#define TAGCACHE_MAX_FILTERS 4
+#define TAGCACHE_MAX_CLAUSES 16
/* Tag database files. */
#define TAGCACHE_FILE_TEMP ROCKBOX_DIR "/tagcache_tmp.tcd"
@@ -116,6 +116,9 @@ struct tagcache_search {
int entry_count;
bool valid;
bool initialized;
+ long *unique_list;
+ int unique_list_capacity;
+ int unique_list_count;
/* Exported variables. */
bool ramsearch;
@@ -133,6 +136,8 @@ bool tagcache_is_unique_tag(int type);
bool tagcache_is_sorted_tag(int type);
bool tagcache_find_index(struct tagcache_search *tcs, const char *filename);
bool tagcache_search(struct tagcache_search *tcs, int tag);
+void tagcache_search_set_uniqbuf(struct tagcache_search *tcs,
+ void *buffer, long length);
bool tagcache_search_add_filter(struct tagcache_search *tcs,
int tag, int seek);
bool tagcache_search_add_clause(struct tagcache_search *tcs,
diff --git a/apps/tagtree.c b/apps/tagtree.c
index eaee9b9..70c8a3e 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -48,6 +48,11 @@
static int tagtree_play_folder(struct tree_context* c);
static char searchstring[32];
+
+/* Capacity 10 000 entries (for example 10k different artists) */
+#define UNIQBUF_SIZE (64*1024)
+static long *uniqbuf;
+
#define MAX_TAGS 5
/*
@@ -500,6 +505,7 @@ void tagtree_init(void)
}
close(fd);
+ uniqbuf = buffer_alloc(UNIQBUF_SIZE);
audio_set_track_buffer_event(tagtree_buffer_event);
audio_set_track_unbuffer_event(tagtree_unbuffer_event);
}
@@ -566,16 +572,21 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
if (!tagcache_search(tcs, tag))
return -1;
+ /* Prevent duplicate entries in the search list. */
+ tagcache_search_set_uniqbuf(tcs, uniqbuf, UNIQBUF_SIZE);
+
+ if (extra || csi->clause_count[0])
+ sort = true;
+
for (i = 0; i < extra; i++)
- {
tagcache_search_add_filter(tcs, csi->tagorder[i], csi->result_seek[i]);
- sort = true;
- }
- for (i = 0; i < csi->clause_count[extra]; i++)
+ for (i = 0; i <= extra; i++)
{
- tagcache_search_add_clause(tcs, &csi->clause[extra][i]);
- sort = true;
+ int j;
+
+ for (j = 0; j < csi->clause_count[i]; j++)
+ tagcache_search_add_clause(tcs, &csi->clause[i][j]);
}
current_offset = offset;