There's no need to get authors, description and last modification time of a project that's not being shown on a current page. We can only tell that in advance if the list is sorted by pathname. --- gitweb/gitweb.perl | 47 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 34 insertions(+), 13 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 135ca55..45584f4 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -4608,12 +4608,30 @@ sub format_sort_th { return $sort_th; } +sub git_try_to_order { + my ($projects, $order) = @_; + + my %order_info = ( + project => { key => 'path', type => 'str' }, + descr => { key => 'descr_long', type => 'str' }, + owner => { key => 'owner', type => 'str' }, + age => { key => 'age', type => 'num' } + ); + my $oi = $order_info{$order}; + return undef unless exists $projects->[0]->{$oi->{'key'}}; + if ($oi->{'type'} eq 'str') { + @$projects = sort {$a->{$oi->{'key'}} cmp $b->{$oi->{'key'}}} @$projects; + } else { + @$projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @$projects; + } + return 1; +} + sub git_project_list_body { # actually uses global variable $project my ($projlist, $order, $from, $to, $extra, $no_header) = @_; my $check_forks = gitweb_check_feature('forks'); - my @projects = fill_project_list_info($projlist, $check_forks); $order ||= $default_projects_order; $page ||= 0; @@ -4622,26 +4640,29 @@ sub git_project_list_body { $to = $from + $projects_per_page - 1 unless defined $to; } $from = 0 unless defined $from; - $to = $#projects if (!defined $to || $#projects < $to); + $to = $#$projlist if (!defined $to || $#$projlist < $to); my $prev_link = $cgi->a({-href => href(-replay=>1, page=>$page-1), -accesskey => "p", -title => "Alt-p"}, "prev") if ($page > 0); my $next_link = $cgi->a({-href => href(-replay=>1, page=>$page+1), -accesskey => "n", -title => "Alt-n"}, "next") if ($#$projlist > $to); - my %order_info = ( - project => { key => 'path', type => 'str' }, - descr => { key => 'descr_long', type => 'str' }, - owner => { key => 'owner', type => 'str' }, - age => { key => 'age', type => 'num' } - ); - my $oi = $order_info{$order}; - if ($oi->{'type'} eq 'str') { - @projects = sort {$a->{$oi->{'key'}} cmp $b->{$oi->{'key'}}} @projects; - } else { - @projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @projects; + # If we're paginating and can order the list now (by pathname), we + # don't need to do an unnecessary and expensive query of the details + # of the projects we're not going to display. Attempt the sort and + # remove the other projects from the list if the sort is successful. + # Can't be used with ctags, since it needs a complete project list. + my $ordered = git_try_to_order($projlist, $order) + unless gitweb_check_feature('ctags'); + if ($ordered) { + @$projlist = @$projlist[$from..$to]; + $to -= $from; + $from = 0; } + my @projects = fill_project_list_info($projlist, $check_forks); + git_try_to_order(\@projects, $order) unless $ordered; + my $show_ctags = gitweb_check_feature('ctags'); if ($show_ctags) { my %ctags; -- 1.7.2.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html