chiark / gitweb /
Implement 'weight' track preference (defect 10). No UI yet.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sat, 12 Apr 2008 11:39:46 +0000 (12:39 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sat, 12 Apr 2008 11:39:46 +0000 (12:39 +0100)
CHANGES
doc/disorder.1.in
server/choose.c

diff --git a/CHANGES b/CHANGES
index f9c74b9..0acc6f9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,8 @@ is real demand.
 This has been completely rewritten to support new features:
    - tracks in the recently-played list or in the queue are no longer
      eligible for random choice
+   - there is a new 'weight' track preference allowing for non-uniform
+     track selection.  See disorder(1) for details.
    - there is a new configuration item replay_min defining the minimum
      time before a played track can be picked at random.  The default is
      8 hours (which matches the earlier behaviour).
index a056d63..61f6f02 100644 (file)
@@ -299,6 +299,22 @@ if the full version is not present.
 .B unscratched
 The number of times the track has been played to completion without
 being scratched.
+.TP
+.B weight
+The weight for this track.  Weights are non-negative integers which determine
+the relative likelihood of a track being picked at random (i.e. if track A has
+twice the weight of track B then it is twice as likely to be picked at random).
+A track with weight 0 will not be picked at random, though \fBpick_at_random\fR
+is a more sensible way to configure this.
+.IP
+The default weight, used if no weight is set or the weight value is invalid, is
+90000.  Note that many other factors than track weight affect whether a track
+will be played - tracks already in the queue will not be picked at random for
+instance.
+.IP
+The maximum allowed weight is 2147483647.  If you set a larger value it will be
+clamped to this value.  Negative weights will be completely ignored and the
+default value used instead.
 .SH NOTES
 .B disorder
 is locale-aware.
index 6de1b45..06c9601 100644 (file)
@@ -173,6 +173,16 @@ static unsigned long compute_weight(const char *track,
   if(*required_tags && !tag_intersection(track_tags, required_tags))
     return 0;
 
+  /* Use the configured weight if available */
+  if((s = kvp_get(prefs, "weight"))) {
+    long n;
+    errno = 0;
+
+    n = strtol(s, 0, 10);
+    if((errno == 0 || errno == ERANGE) && n >= 0)
+      return n;
+  }
+  
   return 90000;
 }
 
@@ -182,11 +192,15 @@ static int collect_tracks_callback(const char *track,
                                    struct kvp *prefs,
                                   void attribute((unused)) *u,
                                   DB_TXN attribute((unused)) *tid) {
-  const unsigned long weight = compute_weight(track, data, prefs);
+  unsigned long weight = compute_weight(track, data, prefs);
 
   if(weight) {
     struct weighted_track *const t = xmalloc(sizeof *t);
 
+    /* Clamp weight so that we can fit in billions of tracks when we do
+     * arithmetic in long long */
+    if(weight > 0x7fffffff)
+      weight = 0x7fffffff;
     t->next = tracks;
     t->track = track;
     t->weight = weight;