Accept FS#11723 by Michael Hohmuth
Tagcache returns stale numeric (runtime statistics) data git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28645 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3dc5f59625
commit
893d2f37ba
1 changed files with 74 additions and 28 deletions
102
apps/tagcache.c
102
apps/tagcache.c
|
@ -764,31 +764,75 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long check_virtual_tags(int tag, const struct index_entry *idx)
|
#define COMMAND_QUEUE_IS_EMPTY (command_queue_ridx == command_queue_widx)
|
||||||
|
|
||||||
|
static long read_numeric_tag(int tag, int idx_id, const struct index_entry *idx)
|
||||||
|
{
|
||||||
|
if (! COMMAND_QUEUE_IS_EMPTY)
|
||||||
|
{
|
||||||
|
/* Attempt to find tag data through store-to-load forwarding in
|
||||||
|
command queue */
|
||||||
|
long result = -1;
|
||||||
|
|
||||||
|
mutex_lock(&command_queue_mutex);
|
||||||
|
|
||||||
|
int ridx = command_queue_widx;
|
||||||
|
|
||||||
|
while (ridx != command_queue_ridx)
|
||||||
|
{
|
||||||
|
if (--ridx < 0)
|
||||||
|
ridx = TAGCACHE_COMMAND_QUEUE_LENGTH - 1;
|
||||||
|
|
||||||
|
if (command_queue[ridx].command == CMD_UPDATE_NUMERIC
|
||||||
|
&& command_queue[ridx].idx_id == idx_id
|
||||||
|
&& command_queue[ridx].tag == tag)
|
||||||
|
{
|
||||||
|
result = command_queue[ridx].data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&command_queue_mutex);
|
||||||
|
|
||||||
|
if (result >= 0)
|
||||||
|
{
|
||||||
|
logf("read_numeric_tag: "
|
||||||
|
"Recovered tag %d value %lX from write queue",
|
||||||
|
tag, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx->tag_seek[tag];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static long check_virtual_tags(int tag, int idx_id,
|
||||||
|
const struct index_entry *idx)
|
||||||
{
|
{
|
||||||
long data = 0;
|
long data = 0;
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case tag_virt_length_sec:
|
case tag_virt_length_sec:
|
||||||
data = (idx->tag_seek[tag_length]/1000) % 60;
|
data = (read_numeric_tag(tag_length, idx_id, idx)/1000) % 60;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tag_virt_length_min:
|
case tag_virt_length_min:
|
||||||
data = (idx->tag_seek[tag_length]/1000) / 60;
|
data = (read_numeric_tag(tag_length, idx_id, idx)/1000) / 60;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tag_virt_playtime_sec:
|
case tag_virt_playtime_sec:
|
||||||
data = (idx->tag_seek[tag_playtime]/1000) % 60;
|
data = (read_numeric_tag(tag_playtime, idx_id, idx)/1000) % 60;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tag_virt_playtime_min:
|
case tag_virt_playtime_min:
|
||||||
data = (idx->tag_seek[tag_playtime]/1000) / 60;
|
data = (read_numeric_tag(tag_playtime, idx_id, idx)/1000) / 60;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tag_virt_autoscore:
|
case tag_virt_autoscore:
|
||||||
if (idx->tag_seek[tag_length] == 0
|
if (read_numeric_tag(tag_length, idx_id, idx) == 0
|
||||||
|| idx->tag_seek[tag_playcount] == 0)
|
|| read_numeric_tag(tag_playcount, idx_id, idx) == 0)
|
||||||
{
|
{
|
||||||
data = 0;
|
data = 0;
|
||||||
}
|
}
|
||||||
|
@ -804,19 +848,23 @@ static long check_virtual_tags(int tag, const struct index_entry *idx)
|
||||||
autoscore = 100 * (alpha / playcout + beta / length / playcount)
|
autoscore = 100 * (alpha / playcout + beta / length / playcount)
|
||||||
Both terms should be small enough to avoid any overflow
|
Both terms should be small enough to avoid any overflow
|
||||||
*/
|
*/
|
||||||
data = 100 * (idx->tag_seek[tag_playtime] / idx->tag_seek[tag_length])
|
data = 100 * (read_numeric_tag(tag_playtime, idx_id, idx)
|
||||||
+ (100 * (idx->tag_seek[tag_playtime] % idx->tag_seek[tag_length])) / idx->tag_seek[tag_length];
|
/ read_numeric_tag(tag_length, idx_id, idx))
|
||||||
data /= idx->tag_seek[tag_playcount];
|
+ (100 * (read_numeric_tag(tag_playtime, idx_id, idx)
|
||||||
|
% read_numeric_tag(tag_length, idx_id, idx)))
|
||||||
|
/ read_numeric_tag(tag_length, idx_id, idx);
|
||||||
|
data /= read_numeric_tag(tag_playcount, idx_id, idx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* How many commits before the file has been added to the DB. */
|
/* How many commits before the file has been added to the DB. */
|
||||||
case tag_virt_entryage:
|
case tag_virt_entryage:
|
||||||
data = current_tcmh.commitid - idx->tag_seek[tag_commitid] - 1;
|
data = current_tcmh.commitid
|
||||||
|
- read_numeric_tag(tag_commitid, idx_id, idx) - 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
data = idx->tag_seek[tag];
|
data = read_numeric_tag(tag, idx_id, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -835,7 +883,7 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
|
||||||
if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true))
|
if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true))
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
return check_virtual_tags(tag, &idx);
|
return check_virtual_tags(tag, tcs->idx_id, &idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool str_ends_with(const char *str1, const char *str2)
|
inline static bool str_ends_with(const char *str1, const char *str2)
|
||||||
|
@ -945,7 +993,7 @@ static bool check_clauses(struct tagcache_search *tcs,
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
seek = check_virtual_tags(clause[i]->tag, idx);
|
seek = check_virtual_tags(clause[i]->tag, tcs->idx_id, idx);
|
||||||
|
|
||||||
if (!TAGCACHE_IS_NUMERIC(clause[i]->tag))
|
if (!TAGCACHE_IS_NUMERIC(clause[i]->tag))
|
||||||
{
|
{
|
||||||
|
@ -975,7 +1023,7 @@ static bool check_clauses(struct tagcache_search *tcs,
|
||||||
int seek;
|
int seek;
|
||||||
char str[256];
|
char str[256];
|
||||||
|
|
||||||
seek = check_virtual_tags(clause[i]->tag, idx);
|
seek = check_virtual_tags(clause[i]->tag, tcs->idx_id, idx);
|
||||||
|
|
||||||
memset(str, 0, sizeof str);
|
memset(str, 0, sizeof str);
|
||||||
if (!TAGCACHE_IS_NUMERIC(clause[i]->tag))
|
if (!TAGCACHE_IS_NUMERIC(clause[i]->tag))
|
||||||
|
@ -1603,9 +1651,9 @@ static struct tagfile_entry *get_tag(const struct index_entry *entry, int tag)
|
||||||
return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]];
|
return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static long get_tag_numeric(const struct index_entry *entry, int tag)
|
static long get_tag_numeric(const struct index_entry *entry, int tag, int idx_id)
|
||||||
{
|
{
|
||||||
return check_virtual_tags(tag, entry);
|
return check_virtual_tags(tag, idx_id, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* get_tag_string(const struct index_entry *entry, int tag)
|
static char* get_tag_string(const struct index_entry *entry, int tag)
|
||||||
|
@ -1640,16 +1688,16 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
|
||||||
id3->albumartist = get_tag_string(entry, tag_albumartist);
|
id3->albumartist = get_tag_string(entry, tag_albumartist);
|
||||||
id3->grouping = get_tag_string(entry, tag_grouping);
|
id3->grouping = get_tag_string(entry, tag_grouping);
|
||||||
|
|
||||||
id3->length = get_tag_numeric(entry, tag_length);
|
id3->length = get_tag_numeric(entry, tag_length, idx_id);
|
||||||
id3->playcount = get_tag_numeric(entry, tag_playcount);
|
id3->playcount = get_tag_numeric(entry, tag_playcount, idx_id);
|
||||||
id3->rating = get_tag_numeric(entry, tag_rating);
|
id3->rating = get_tag_numeric(entry, tag_rating, idx_id);
|
||||||
id3->lastplayed = get_tag_numeric(entry, tag_lastplayed);
|
id3->lastplayed = get_tag_numeric(entry, tag_lastplayed, idx_id);
|
||||||
id3->score = get_tag_numeric(entry, tag_virt_autoscore) / 10;
|
id3->score = get_tag_numeric(entry, tag_virt_autoscore, idx_id) / 10;
|
||||||
id3->year = get_tag_numeric(entry, tag_year);
|
id3->year = get_tag_numeric(entry, tag_year, idx_id);
|
||||||
|
|
||||||
id3->discnum = get_tag_numeric(entry, tag_discnumber);
|
id3->discnum = get_tag_numeric(entry, tag_discnumber, idx_id);
|
||||||
id3->tracknum = get_tag_numeric(entry, tag_tracknumber);
|
id3->tracknum = get_tag_numeric(entry, tag_tracknumber, idx_id);
|
||||||
id3->bitrate = get_tag_numeric(entry, tag_bitrate);
|
id3->bitrate = get_tag_numeric(entry, tag_bitrate, idx_id);
|
||||||
if (id3->bitrate == 0)
|
if (id3->bitrate == 0)
|
||||||
id3->bitrate = 1;
|
id3->bitrate = 1;
|
||||||
|
|
||||||
|
@ -3103,8 +3151,6 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COMMAND_QUEUE_IS_EMPTY (command_queue_ridx == command_queue_widx)
|
|
||||||
|
|
||||||
static bool command_queue_is_full(void)
|
static bool command_queue_is_full(void)
|
||||||
{
|
{
|
||||||
int next;
|
int next;
|
||||||
|
|
Loading…
Reference in a new issue