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 f9c74b9a5790ea48eb7ca364a627bafd3ed109b9..0acc6f90bf6d4b4130646add2018b459679ca26d 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
 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).
    - 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 a056d63c00262221d386231066cb379e26478527..61f6f02d3b95ecd5f92e918d74c697a1afcaafbc 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.
 .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.
 .SH NOTES
 .B disorder
 is locale-aware.
index 6de1b45d9faa718bd37bf680ccbeb64b427c4137..06c9601b76e90a2b197961f34b7e915d0980ea0b 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;
 
   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;
 }
 
   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) {
                                    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);
 
 
   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;
     t->next = tracks;
     t->track = track;
     t->weight = weight;