[Slim-Checkins] r11162 - /trunk/server/Plugins/RandomPlay/Plugin.pm
dsully at svn.slimdevices.com
dsully at svn.slimdevices.com
Mon Jan 8 14:36:23 PST 2007
Author: dsully
Date: Mon Jan 8 14:36:23 2007
New Revision: 11162
URL: http://svn.slimdevices.com?rev=11162&view=rev
Log:
Bug: 4477
Description: Don't use RAND() when looking for tracks - it's too slow.
Modified:
trunk/server/Plugins/RandomPlay/Plugin.pm
Modified: trunk/server/Plugins/RandomPlay/Plugin.pm
URL: http://svn.slimdevices.com/trunk/server/Plugins/RandomPlay/Plugin.pm?rev=11162&r1=11161&r2=11162&view=diff
==============================================================================
--- trunk/server/Plugins/RandomPlay/Plugin.pm (original)
+++ trunk/server/Plugins/RandomPlay/Plugin.pm Mon Jan 8 14:36:23 2007
@@ -126,27 +126,43 @@
}
}
- # Search the database for the number of track we need. Use MySQL's
- # RAND() function to get back a random list. Restrict by the genre's we've selected.
- my @results = ();
- my $rs = Slim::Schema->rs($type)->search($find, {
-
- 'order_by' => \'RAND()',
- 'join' => \@joins,
- });
+ # Search the database for the number of track we need.
+ # Restrict by the genre's we've selected.
+ my $rs = Slim::Schema->rs($type)->search($find, { 'join' => \@joins });
+
+ my @idList = $rs->distinct->get_column('me.id')->all;
if ($limit) {
- @results = $rs->slice(0, ($limit-1));
+ # Get a fixed selection of random keys, make sure they don't duplicate.
+ my %random = ();
+ my $max = $limit;
+
+ while ($max) {
+
+ my $i = $idList[ rand @idList ];
+
+ if (exists $random{$i}) {
+ next;
+ }
+
+ $random{$i} = 1;
+
+ $max--;
+ }
+
+ @idList = keys %random;
} else {
- @results = $rs->all;
- }
-
- $log->info(sprintf("Find returned %i items", scalar @results));
+ Slim::Player::Playlist::fischer_yates_shuffle(\@idList);
+ }
+
+ $log->info(sprintf("Find returned %i items", scalar @idList));
# Pull the first track off to add / play it if needed.
+ my @results = Slim::Schema->rs($type)->search({ 'id' => { 'in' => \@idList } })->all;
+
my $obj = shift @results;
if (!$obj || !ref($obj)) {
@@ -271,10 +287,10 @@
$log->debug("Called with type $type");
- if (!$mixInfo{$client->masterOrSelf->id}) {
-
- #init hash for each new client
- $mixInfo{$client->masterOrSelf->id}->{'type'} = undef;
+ if (!$mixInfo{$client->masterOrSelf->id} || !$mixInfo{$client->masterOrSelf->id}->{'type'}) {
+
+ # init hash for each new client
+ $mixInfo{$client->masterOrSelf->id}->{'type'} = '';
}
$type ||= 'track';
@@ -287,6 +303,7 @@
my $startTime = undef;
if ($continuousMode && $type && (!$mixInfo{$client->masterOrSelf->id}->{'type'} || $mixInfo{$client->masterOrSelf->id}->{'type'} ne $type)) {
+
$startTime = time();
}
@@ -303,7 +320,7 @@
# Add new tracks if there aren't enough after the current track
my $numRandomTracks = Slim::Utils::Prefs::get('plugin_random_number_of_tracks');
- if (! $addOnly) {
+ if (!$addOnly) {
$numItems = $numRandomTracks;
@@ -316,7 +333,7 @@
$log->debug("$songsRemaining items remaining so not adding new track");
}
- } elsif ($type ne 'disable' && ($type ne $mixInfo{$client->masterOrSelf->id}->{'type'} || ! $addOnly || $songsRemaining <= 0)) {
+ } elsif ($type ne 'disable' && ($type ne $mixInfo{$client->masterOrSelf->id}->{'type'} || !$addOnly || $songsRemaining <= 0)) {
# Old artist/album/year is finished or new random mix started. Add a new one
$numItems = 1;
@@ -411,8 +428,7 @@
}
}
- # Do a show briefly the first time things are added, or every time a new album/artist/year
- # is added
+ # Do a show briefly the first time things are added, or every time a new album/artist/year is added
if (!$addOnly || $type ne $mixInfo{$client->masterOrSelf->id}->{'type'} || $type ne 'track') {
if ($type eq 'track') {
@@ -444,18 +460,20 @@
# the display messes up
if (Slim::Buttons::Common::mode($client) !~ /^SCREENSAVER./) {
- $client->showBriefly(string('PLUGIN_RANDOM'),
- string('PLUGIN_RANDOM_DISABLED'));
+ $client->showBriefly(
+ string('PLUGIN_RANDOM'),
+ string('PLUGIN_RANDOM_DISABLED')
+ );
}
$mixInfo{$client->masterOrSelf->id} = undef;
} else {
- $log->info(
+ $log->info(sprintf(
"Playing %s %s mode with %i items",
$continuousMode ? 'continuous' : 'static', $type, Slim::Player::Playlist::count($client)
- );
+ ));
# $startTime will only be defined if this is a new (or restarted) mix
if (defined $startTime) {
More information about the checkins
mailing list