return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd);
}
-static long compute_score(struct afs_info *afsi)
+static long compute_score(struct afs_info *afsi,
+ const struct afs_statistics *stats)
{
- const struct afs_statistics *stats = ¤t_mood->stats;
long score = -normalized_value(afsi->num_played, stats->num,
stats->num_played_sum, stats->num_played_qd);
score -= normalized_value(afsi->last_played, stats->num,
return score / 2;
}
-static int add_afs_statistics(const struct osl_row *row)
+static int add_afs_statistics(const struct osl_row *row,
+ struct afs_statistics *stats)
{
uint64_t n, x, s, q;
struct afs_info afsi;
int ret;
- struct afs_statistics *stats = ¤t_mood->stats;
ret = get_afsi_of_row(row, &afsi);
if (ret < 0)
*/
static int add_if_admissible(struct osl_row *aft_row, void *data)
{
- const struct afs_statistics *stats = ¤t_mood->stats;
struct admissible_array *aa = data;
+ struct afs_statistics *stats = &aa->m->stats;
if (!mp_eval_row(aft_row, aa->m->parser_context))
return 0;
sizeof(struct osl_row *));
}
aa->array[stats->num] = aft_row;
- return add_afs_statistics(aft_row);
+ return add_afs_statistics(aft_row, stats);
}
/**
stats->num_played_sum += new_afsi->num_played - old_afsi->num_played;
}
-static int add_to_score_table(const struct osl_row *aft_row)
+static int add_to_score_table(const struct osl_row *aft_row,
+ const struct afs_statistics *stats)
{
long score;
struct afs_info afsi;
if (ret < 0)
return ret;
- score = compute_score(&afsi);
+ score = compute_score(&afsi, stats);
return score_add(aft_row, score);
}
if (was_admissible && !is_admissible)
return delete_from_statistics_and_score_table(aft_row);
if (!was_admissible && is_admissible) {
- ret = add_afs_statistics(aft_row);
+ ret = add_afs_statistics(aft_row, ¤t_mood->stats);
if (ret < 0)
return ret;
- return add_to_score_table(aft_row);
+ return add_to_score_table(aft_row, ¤t_mood->stats);
}
/* update score */
ret = get_afsi_of_row(aft_row, &afsi);
return ret;
if (old_afsi)
update_afs_statistics(old_afsi, &afsi);
- score = compute_score(&afsi);
+ score = compute_score(&afsi, ¤t_mood->stats);
PARA_DEBUG_LOG("score: %li\n", score);
percent = (score + 100) / 3;
if (percent > 100)
}
/* sse: seconds since epoch. */
-static void log_statistics(int64_t sse)
+static void log_statistics(struct afs_statistics *stats, int64_t sse)
{
- const struct afs_statistics *stats = ¤t_mood->stats;
unsigned n = stats->num;
int mean_days, sigma_days;
- assert(current_mood);
- PARA_NOTICE_LOG("loaded mood %s\n", current_mood->name?
- current_mood->name : "(dummy)");
if (!n) {
PARA_WARNING_LOG("no admissible files\n");
return;
current_mood = NULL;
}
-static void compute_correction_factors(int64_t sse)
+static void compute_correction_factors(int64_t sse, struct afs_statistics *s)
{
- struct afs_statistics *s = ¤t_mood->stats;
-
if (s->num > 0) {
s->normalization_divisor = int_sqrt(s->last_played_qd)
* int_sqrt(s->num_played_qd) / s->num / 100;
*
* \sa struct \ref afs_info::last_played, \ref mp_eval_row().
*/
-int change_current_mood(const char *mood_name, char **errmsg)
+int mood_switch(const char *mood_name, char **errmsg)
{
int i, ret;
- struct admissible_array aa = {
- .size = 0,
- .array = NULL
- };
+ struct admissible_array aa = {.size = 0};
/*
* We can not use the "now" pointer from sched.c here because we are
* called before schedule(), which initializes "now".
struct timeval rnow;
if (mood_name) {
- struct mood *m;
- ret = init_mood_parser(mood_name, &m, errmsg);
+ ret = init_mood_parser(mood_name, &aa.m, errmsg);
if (ret < 0)
return ret;
- close_current_mood();
- current_mood = m;
- } else { /* load dummy mood */
- close_current_mood();
- current_mood = alloc_new_mood(NULL);
- }
- aa.m = current_mood;
+ } else /* load dummy mood */
+ aa.m = alloc_new_mood(NULL);
PARA_NOTICE_LOG("computing statistics of admissible files\n");
ret = audio_file_loop(&aa, add_if_admissible);
if (ret < 0) {
goto out;
}
clock_get_realtime(&rnow);
- compute_correction_factors(rnow.tv_sec);
- log_statistics(rnow.tv_sec);
- for (i = 0; i < current_mood->stats.num; i++) {
- ret = add_to_score_table(aa.array[i]);
+ compute_correction_factors(rnow.tv_sec, &aa.m->stats);
+ log_statistics(&aa.m->stats, rnow.tv_sec);
+ for (i = 0; i < aa.m->stats.num; i++) {
+ ret = add_to_score_table(aa.array[i], &aa.m->stats);
if (ret < 0) {
if (errmsg)
*errmsg = make_message(
goto out;
}
}
- ret = current_mood->stats.num;
+ /* success */
+ close_current_mood();
+ current_mood = aa.m;
+ PARA_NOTICE_LOG("loaded mood %s\n", mood_name? mood_name : "(dummy)");
+ ret = aa.m->stats.num;
out:
free(aa.array);
if (ret < 0)
- close_current_mood();
+ destroy_mood(aa.m);
return ret;
}
if (current_mood->name)
mood_name = para_strdup(current_mood->name);
close_current_mood();
- ret = change_current_mood(mood_name, NULL);
+ ret = mood_switch(mood_name, NULL);
free(mood_name);
return ret;
}