*/
static struct mood *current_mood;
-/**
- * Rough approximation to sqrt.
+/*
+ * Find the position of the most-significant set bit.
*
- * \param x Integer of which to calculate the sqrt.
+ * Copied and slightly adapted from the linux source tree, version 4.9.39
+ * (2017-07).
+ */
+__a_const static uint32_t fls64(uint64_t v)
+{
+ int n = 63;
+ const uint64_t ones = ~(uint64_t)0U;
+
+ if ((v & (ones << 32)) == 0) {
+ n -= 32;
+ v <<= 32;
+ }
+ if ((v & (ones << (64 - 16))) == 0) {
+ n -= 16;
+ v <<= 16;
+ }
+ if ((v & (ones << (64 - 8))) == 0) {
+ n -= 8;
+ v <<= 8;
+ }
+ if ((v & (ones << (64 - 4))) == 0) {
+ n -= 4;
+ v <<= 4;
+ }
+ if ((v & (ones << (64 - 2))) == 0) {
+ n -= 2;
+ v <<= 2;
+ }
+ if ((v & (ones << (64 - 1))) == 0)
+ n -= 1;
+ return n;
+}
+
+/*
+ * Compute the integer square root floor(sqrt(x)).
*
- * \return An integer res with res * res <= x.
+ * Taken 2007 from the linux source tree.
*/
__a_const static uint64_t int_sqrt(uint64_t x)
{
- uint64_t op, res, one = 1;
- op = x;
- res = 0;
-
- one = one << 62;
- while (one > op)
- one >>= 2;
+ uint64_t op = x, res = 0, one = 1;
+ one = one << (fls64(x) & ~one);
while (one != 0) {
if (op >= res + one) {
op = op - (res + one);
- res = res + 2 * one;
+ res = res + 2 * one;
}
res /= 2;
one /= 4;
}
-// PARA_NOTICE_LOG("sqrt(%llu) = %llu\n", x, res);
return res;
}
}
/* returns 1 if row admissible, 0 if not, negative on errors */
-static int compute_mood_score(const struct osl_row *aft_row, struct mood *m,
- long *result)
+static int row_is_admissible(const struct osl_row *aft_row, struct mood *m,
+ long *scorep)
{
struct mood_item *item;
int ret;
if (!m)
return -E_NO_MOOD;
ret = get_afsi_of_row(aft_row, &afsi);
- if (ret< 0)
+ if (ret < 0)
return ret;
ret = get_afhi_of_row(aft_row, &afhi);
- if (ret< 0)
+ if (ret < 0)
return ret;
ret = get_audio_file_path_of_row(aft_row, &path);
- if (ret< 0)
+ if (ret < 0)
return ret;
/* reject audio file if it matches any entry in the deny list */
list_for_each_entry(item, &m->deny_list, mood_item_node) {
}
if (score_arg_sum)
score /= score_arg_sum;
- *result = score;
+ *scorep = score;
return 1;
}
* <score> is either an integer or "random" which assigns a random score to
* all matching files
*/
-
static int parse_mood_line(char *mood_line, void *data)
{
struct mood_line_parser_data *mlpd = data;
int ret;
long score = 0;
- ret = compute_mood_score(aft_row, aa->m, &score);
+ ret = row_is_admissible(aft_row, aa->m, &score);
if (ret <= 0)
return ret;
if (statistics.num >= aa->size) {
return old_qd + delta * (sigma - 2 * old_sum / n - delta / n);
}
-static int update_afs_statistics(struct afs_info *old_afsi, struct afs_info *new_afsi)
+static int update_afs_statistics(struct afs_info *old_afsi,
+ struct afs_info *new_afsi)
{
unsigned n;
int ret = get_num_admissible_files(&n);
if (ret < 0)
return ret;
was_admissible = ret;
- ret = compute_mood_score(aft_row, current_mood, &score);
+ ret = row_is_admissible(aft_row, current_mood, &score);
if (ret < 0)
return ret;
is_admissible = (ret > 0);
free(aa.array);
return ret;
}
+
/*
* Close and re-open the current mood.
*