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
This commit is contained in:
parent
a3ba6725cb
commit
e308064353
3 changed files with 86 additions and 41 deletions
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
for (i = 0; i < extra; i++)
|
||||
{
|
||||
tagcache_search_add_filter(tcs, csi->tagorder[i], csi->result_seek[i]);
|
||||
sort = true;
|
||||
}
|
||||
/* Prevent duplicate entries in the search list. */
|
||||
tagcache_search_set_uniqbuf(tcs, uniqbuf, UNIQBUF_SIZE);
|
||||
|
||||
for (i = 0; i < csi->clause_count[extra]; i++)
|
||||
{
|
||||
tagcache_search_add_clause(tcs, &csi->clause[extra][i]);
|
||||
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]);
|
||||
|
||||
for (i = 0; i <= extra; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < csi->clause_count[i]; j++)
|
||||
tagcache_search_add_clause(tcs, &csi->clause[i][j]);
|
||||
}
|
||||
|
||||
current_offset = offset;
|
||||
|
|
Loading…
Reference in a new issue