[Slim-Checkins] r11445 - in /trunk/server/Slim: Player/Playlist.pm Plugin/RandomPlay/Plugin.pm
adrian at svn.slimdevices.com
adrian at svn.slimdevices.com
Thu Feb 15 09:45:08 PST 2007
Author: adrian
Date: Thu Feb 15 09:45:08 2007
New Revision: 11445
URL: http://svn.slimdevices.com?rev=11445&view=rev
Log:
Bug: 4724 (related)
Description: ensure random play adds each group of tracks in a random
order. Reduce cpu hit by caching list of ids and useing for next call.
Modified:
trunk/server/Slim/Player/Playlist.pm
trunk/server/Slim/Plugin/RandomPlay/Plugin.pm
Modified: trunk/server/Slim/Player/Playlist.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Player/Playlist.pm?rev=11445&r1=11444&r2=11445&view=diff
==============================================================================
--- trunk/server/Slim/Player/Playlist.pm (original)
+++ trunk/server/Slim/Player/Playlist.pm Thu Feb 15 09:45:08 2007
@@ -730,7 +730,8 @@
$log->info("Checking if persistPlaylists is set..");
- if (!$client || !Slim::Utils::Prefs::get('persistPlaylists')) {
+ if (!$client || !Slim::Utils::Prefs::get('persistPlaylists') ||
+ exists &Slim::Plugin::RandomPlay::Plugin::active && Slim::Plugin::RandomPlay::Plugin::active($client) ) {
return;
}
Modified: trunk/server/Slim/Plugin/RandomPlay/Plugin.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Plugin/RandomPlay/Plugin.pm?rev=11445&r1=11444&r2=11445&view=diff
==============================================================================
--- trunk/server/Slim/Plugin/RandomPlay/Plugin.pm (original)
+++ trunk/server/Slim/Plugin/RandomPlay/Plugin.pm Thu Feb 15 09:45:08 2007
@@ -89,71 +89,95 @@
# Find tracks matching parameters and add them to the playlist
sub findAndAdd {
- my ($client, $type, $find, $limit, $addOnly) = @_;
+ my ($client, $type, $find, $limit, $idList, $addOnly) = @_;
$log->info(sprintf("Starting random selection of %s items for type: $type", defined($limit) ? $limit : 'unlimited'));
- my @joins = ();
-
- # Pull in the right tables to do our searches
- if ($type eq 'track' || $type eq 'year') {
-
- if ($find->{'genreTracks.genre'}) {
-
- push @joins, 'genreTracks';
- }
-
- } elsif ($type eq 'album') {
-
- if ($find->{'genreTracks.genre'}) {
-
- push @joins, { 'tracks' => 'genreTracks' };
+ my @results;
+
+ if ($limit && scalar @$idList) {
+
+ # use previous id list as same find criteria as last call, select a random set of them
+ my @randomIds;
+
+ for (my $i = 0; $i < $limit && scalar @$idList; ++$i) {
+
+ push @randomIds, (splice @$idList, rand @$idList, 1);
+ }
+
+ # Turn ids into tracks, note this will reorder ids so needs use of RAND() in SQL statement to maintain randomness
+ @results = Slim::Schema->rs($type)->search({ 'id' => { 'in' => \@randomIds } }, { 'order_by' => \'RAND()' })->all;
+
+ } else {
+
+ # Search the database for all items of $type which match find criteria
+
+ my @joins = ();
+
+ # Pull in the right tables to do our searches
+ if ($type eq 'track' || $type eq 'year') {
+
+ if ($find->{'genreTracks.genre'}) {
+
+ push @joins, 'genreTracks';
+ }
+
+ } elsif ($type eq 'album') {
+
+ if ($find->{'genreTracks.genre'}) {
+
+ push @joins, { 'tracks' => 'genreTracks' };
+
+ } else {
+
+ push @joins, 'tracks';
+ }
+
+ } elsif ($type eq 'contributor') {
+
+ if ($find->{'genreTracks.genre'}) {
+
+ push @joins, { 'contributorTracks' => { 'track' => 'genreTracks' } };
+
+ } else {
+
+ push @joins, { 'contributorTracks' => 'track' };
+ }
+ }
+
+ my $rs = Slim::Schema->rs($type)->search($find, { 'join' => \@joins });
+
+ if ($limit) {
+
+ # Get ids for all results from find and store in @$idList so they can be used in repeat calls
+ @$idList = $rs->distinct->get_column('me.id')->all;
+
+ # Get a random selection for this call
+ my @randomIds;
+
+ for (my $i = 0; $i < $limit && scalar @$idList; ++$i) {
+
+ push @randomIds, (splice @$idList, rand @$idList, 1);
+ }
+
+ # Turn ids into tracks, note this will reorder ids so needs use of RAND() in SQL statement to maintain randomness
+ @results = Slim::Schema->rs($type)->search({ 'id' => { 'in' => \@randomIds } }, { 'order_by' => \'RAND()' })->all;
} else {
- push @joins, 'tracks';
- }
-
- } elsif ($type eq 'contributor') {
-
- if ($find->{'genreTracks.genre'}) {
-
- push @joins, { 'contributorTracks' => { 'track' => 'genreTracks' } };
-
- } else {
-
- push @joins, { 'contributorTracks' => 'track' };
- }
- }
-
- # 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;
-
- if ($limit) {
-
- # Get a fixed selection of random keys, make sure they don't duplicate.
- my @allIds = $rs->distinct->get_column('me.id')->all;
-
- for (my $i = 0; $i < $limit && @allIds; ++$i) {
-
- push @idList, (splice @allIds, rand @allIds, 1);
- }
-
- } else {
-
- @idList = $rs->distinct->get_column('me.id')->all;
-
- Slim::Player::Playlist::fischer_yates_shuffle(\@idList);
- }
-
- $log->info(sprintf("Find returned %i items", scalar @idList));
+ # We want all results from the result set, but need to randomise them
+ my @all = $rs->all;
+
+ while (@all) {
+
+ push @results, (splice @all, rand @all, 1);
+ }
+ }
+ }
+
+ $log->info(sprintf("Find returned %i items", scalar @results));
# 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)) {
@@ -278,11 +302,7 @@
$log->debug("Called with type $type");
- if (!$mixInfo{$client->masterOrSelf->id} || !$mixInfo{$client->masterOrSelf->id}->{'type'}) {
-
- # init hash for each new client
- $mixInfo{$client->masterOrSelf->id}->{'type'} = '';
- }
+ $mixInfo{$client->masterOrSelf->id}->{'type'} ||= '';
$type ||= 'track';
$type = lc($type);
@@ -293,9 +313,11 @@
# If this is a new mix, store the start time
my $startTime = undef;
- if ($continuousMode && $type && (!$mixInfo{$client->masterOrSelf->id}->{'type'} || $mixInfo{$client->masterOrSelf->id}->{'type'} ne $type)) {
-
- $startTime = time();
+ if ($type ne $mixInfo{$client->masterOrSelf->id}->{'type'}) {
+
+ $mixInfo{$client->masterOrSelf->id}->{'idList'} = undef;
+
+ $startTime = time() if $continuousMode;
}
my $songIndex = Slim::Player::Source::streamingSongIndex($client);
@@ -407,6 +429,7 @@
$type eq 'year' ? 'track' : $type,
$find,
$type eq 'year' ? undef : $numItems,
+ $mixInfo{$client->masterOrSelf->id}->{'idList'} ||= [],
# 2nd time round just add tracks to end
$i == 0 ? $addOnly : 1
);
@@ -466,6 +489,8 @@
$continuousMode ? 'continuous' : 'static', $type, Slim::Player::Playlist::count($client)
));
+ $mixInfo{$client->masterOrSelf->id}->{'type'} = $type;
+
# $startTime will only be defined if this is a new (or restarted) mix
if (defined $startTime) {
@@ -473,7 +498,6 @@
# Do this last to prevent menu items changing too soon
$log->info("New mix started at $startTime");
- $mixInfo{$client->masterOrSelf->id}->{'type'} = $type;
$mixInfo{$client->masterOrSelf->id}->{'startTime'} = $startTime;
}
}
@@ -920,6 +944,12 @@
}
}
+sub active {
+ my $client = shift;
+
+ return $mixInfo{$client->masterOrSelf->id} ? 1 : 0;
+}
+
1;
__END__
More information about the checkins
mailing list