]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - mood.c
mood.c: Avoid integer underflow.
[paraslash.git] / mood.c
diff --git a/mood.c b/mood.c
index e06382e85cf2831ce638b27d0e5b057f759faac2..415e1702a75f038694b53393d8674c426b1314c6 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -472,7 +472,7 @@ static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd)
 {
        if (!n || !qd)
                return 0;
-       return 100 * (n * x - sum) / (int64_t)int_sqrt(n * qd);
+       return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd);
 }
 
 static long compute_num_played_score(struct afs_info *afsi)
@@ -504,7 +504,7 @@ static long compute_dynamic_score(const struct osl_row *aft_row)
 
 static int add_afs_statistics(const struct osl_row *row)
 {
-       uint64_t n, x, s;
+       uint64_t n, x, s, q;
        struct afs_info afsi;
        int ret;
 
@@ -514,14 +514,18 @@ static int add_afs_statistics(const struct osl_row *row)
        n = statistics.num;
        x = afsi.last_played;
        s = statistics.last_played_sum;
-       if (n > 0)
-               statistics.last_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.last_played_qd += q * q * n / (n + 1);
+       }
        statistics.last_played_sum += x;
 
        x = afsi.num_played;
        s = statistics.num_played_sum;
-       if (n > 0)
-               statistics.num_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.num_played_qd += q * q * n / (n + 1);
+       }
        statistics.num_played_sum += x;
        statistics.num++;
        return 1;
@@ -896,6 +900,9 @@ static int reload_current_mood(void)
        int ret;
        char *mood_name = NULL;
 
+       ret = clear_score_table();
+       if (ret < 0)
+               return ret;
        if (!current_mood)
                return 1;
        PARA_NOTICE_LOG("reloading %s\n", current_mood->name?
@@ -918,12 +925,12 @@ static int reload_current_mood(void)
  * This function performs actions required due to the occurrence of the given
  * event. Possible actions include reload of the current mood and update of the
  * score of an audio file.
+ *
+ * \return Standard.
  */
 int moods_event_handler(enum afs_events event, __a_unused struct para_buffer *pb,
                void *data)
 {
-       int ret;
-
        if (!current_mood)
                return 0;
        switch (event) {
@@ -936,10 +943,6 @@ int moods_event_handler(enum afs_events event, __a_unused struct para_buffer *pb
        case BLOB_ADD:
                if (data == moods_table || data == playlists_table)
                        return 1; /* no reload necessary for these */
-               ret = clear_score_table();
-               if (ret < 0)
-                       PARA_CRIT_LOG("clear score table returned %s\n",
-                               para_strerror(-ret));
                return reload_current_mood();
        /* these also require reload of the score table */
        case ATTRIBUTE_ADD: