chiark / gitweb /
Bias up recently added tracks. See new_bias and new_bias_age in
[disorder] / server / choose.c
index 4e1b3266cff077894d5d6ac0228745b1406924c8..dbb962c1ee8a80633d2554c341142438bfaff277 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * This file is part of DisOrder 
  * Copyright (C) 2008 Richard Kettlewell
+ * Copyright (C) 2008 Mark Wooding
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,6 +57,8 @@
 #include "queue.h"
 #include "server-queue.h"
 
+#define BASE_WEIGHT 90000
+
 static DB_TXN *global_tid;
 
 static const struct option options[] = {
@@ -120,7 +123,7 @@ static unsigned long compute_weight(const char *track,
                                     struct kvp *prefs) {
   const char *s;
   char **track_tags;
-  time_t last, now;
+  time_t last, now = time(0);
 
   /* Reject tracks not in any collection (race between edit config and
    * rescan) */
@@ -141,7 +144,6 @@ static unsigned long compute_weight(const char *track,
   /* Reject tracks played within the last 8 hours */
   if((s = kvp_get(prefs, "played_time"))) {
     last = atoll(s);
-    now = time(0);
     if(now < last + config->replay_min)
       return 0;
   }
@@ -171,23 +173,49 @@ static unsigned long compute_weight(const char *track,
     if((errno == 0 || errno == ERANGE) && n >= 0)
       return n;
   }
+
+  /* Bias up tracks that were recently added */
+  if((s = kvp_get(data, "_noticed"))) {
+    const time_t noticed = atoll(s);
+
+    if(noticed + config->new_bias_age < now)
+      /* Currently we just step up the weight of tracks that are in range.  A
+       * more sophisticated approach would be to linearly decay from new_bias
+       * down to BASE_WEIGHT over the course of the new_bias_age interval
+       * starting when the track is added. */
+      return config->new_bias;
+  }
   
-  return 90000;
+  return BASE_WEIGHT;
 }
 
-/** @brief Pick a random integer uniformly from [0, limit) */
-static void random_bytes(unsigned char *buf, size_t n) {
-  static int fd = -1;
-  int r;
+static unsigned char random_buffer[4096];
+static size_t random_left;
 
-  if(fd < 0) {
-    if((fd = open("/dev/urandom", O_RDONLY)) < 0)
-      fatal(errno, "opening /dev/urandom");
+/** @brief Fill [buf, buf+n) with random bytes */
+static void random_bytes(unsigned char *buf, size_t n) {
+  while(n > 0) {
+    if(random_left > 0) {
+      const size_t this_time = n > random_left ? random_left : n;
+
+      memcpy(buf, random_buffer + random_left - this_time, this_time);
+      n -= this_time;
+      random_left -= this_time;
+    } else {
+      static int fd = -1;
+      int r;
+
+      if(fd < 0) {
+        if((fd = open("/dev/urandom", O_RDONLY)) < 0)
+          fatal(errno, "opening /dev/urandom");
+      }
+      if((r = read(fd, random_buffer, sizeof random_buffer)) < 0)
+        fatal(errno, "reading /dev/urandom");
+      if((size_t)r < sizeof random_buffer)
+        fatal(0, "short read from /dev/urandom");
+      random_left = sizeof random_buffer;
+    }
   }
-  if((r = read(fd, buf, n)) < 0)
-    fatal(errno, "reading /dev/urandom");
-  if((size_t)r < n)
-    fatal(0, "short read from /dev/urandom");
 }
 
 /** @brief Pick a random integer uniformly from [0, limit) */