[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