From: Richard Kettlewell Date: Sat, 12 Apr 2008 11:39:46 +0000 (+0100) Subject: Implement 'weight' track preference (defect 10). No UI yet. X-Git-Tag: 4.0~125 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/36a1a882e0852f29a63b4e7cfad5e465dfa14fde?hp=cebe31278d4990696382196884fa42d897b15a3f Implement 'weight' track preference (defect 10). No UI yet. --- diff --git a/CHANGES b/CHANGES index f9c74b9..0acc6f9 100644 --- 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). diff --git a/doc/disorder.1.in b/doc/disorder.1.in index a056d63..61f6f02 100644 --- a/doc/disorder.1.in +++ b/doc/disorder.1.in @@ -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. diff --git a/server/choose.c b/server/choose.c index 6de1b45..06c9601 100644 --- a/server/choose.c +++ b/server/choose.c @@ -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;