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:
Jonathan Gordon 2010-11-23 00:15:13 +00:00
parent 3dc5f59625
commit 893d2f37ba

View file

@ -764,31 +764,75 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
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;
switch (tag)
{
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;
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;
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;
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;
case tag_virt_autoscore:
if (idx->tag_seek[tag_length] == 0
|| idx->tag_seek[tag_playcount] == 0)
if (read_numeric_tag(tag_length, idx_id, idx) == 0
|| read_numeric_tag(tag_playcount, idx_id, idx) == 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)
Both terms should be small enough to avoid any overflow
*/
data = 100 * (idx->tag_seek[tag_playtime] / idx->tag_seek[tag_length])
+ (100 * (idx->tag_seek[tag_playtime] % idx->tag_seek[tag_length])) / idx->tag_seek[tag_length];
data /= idx->tag_seek[tag_playcount];
data = 100 * (read_numeric_tag(tag_playtime, idx_id, idx)
/ read_numeric_tag(tag_length, idx_id, idx))
+ (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;
/* How many commits before the file has been added to the DB. */
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;
default:
data = idx->tag_seek[tag];
data = read_numeric_tag(tag, idx_id, idx);
}
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))
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)
@ -945,7 +993,7 @@ static bool check_clauses(struct tagcache_search *tcs,
char buf[256];
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))
{
@ -975,7 +1023,7 @@ static bool check_clauses(struct tagcache_search *tcs,
int seek;
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);
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]];
}
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)
@ -1640,16 +1688,16 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
id3->albumartist = get_tag_string(entry, tag_albumartist);
id3->grouping = get_tag_string(entry, tag_grouping);
id3->length = get_tag_numeric(entry, tag_length);
id3->playcount = get_tag_numeric(entry, tag_playcount);
id3->rating = get_tag_numeric(entry, tag_rating);
id3->lastplayed = get_tag_numeric(entry, tag_lastplayed);
id3->score = get_tag_numeric(entry, tag_virt_autoscore) / 10;
id3->year = get_tag_numeric(entry, tag_year);
id3->length = get_tag_numeric(entry, tag_length, idx_id);
id3->playcount = get_tag_numeric(entry, tag_playcount, idx_id);
id3->rating = get_tag_numeric(entry, tag_rating, idx_id);
id3->lastplayed = get_tag_numeric(entry, tag_lastplayed, idx_id);
id3->score = get_tag_numeric(entry, tag_virt_autoscore, idx_id) / 10;
id3->year = get_tag_numeric(entry, tag_year, idx_id);
id3->discnum = get_tag_numeric(entry, tag_discnumber);
id3->tracknum = get_tag_numeric(entry, tag_tracknumber);
id3->bitrate = get_tag_numeric(entry, tag_bitrate);
id3->discnum = get_tag_numeric(entry, tag_discnumber, idx_id);
id3->tracknum = get_tag_numeric(entry, tag_tracknumber, idx_id);
id3->bitrate = get_tag_numeric(entry, tag_bitrate, idx_id);
if (id3->bitrate == 0)
id3->bitrate = 1;
@ -3103,8 +3151,6 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
}
#endif
#define COMMAND_QUEUE_IS_EMPTY (command_queue_ridx == command_queue_widx)
static bool command_queue_is_full(void)
{
int next;