Commit 99e02eab authored by Byron Jones's avatar Byron Jones

Bug 1028795: pre-load all related bugs during show_bug initialisation

r=sgreen,a=sgreen
parent a26d34af
......@@ -504,6 +504,49 @@ sub preload {
# If we don't do this, can_see_bug will do one call per bug in
# the dependency and duplicate lists, in Bugzilla::Template::get_bug_link.
$user->visible_bugs(\@all_dep_ids);
foreach my $bug (@$bugs) {
$bug->_preload_referenced_bugs();
}
}
# Helps load up bugs referenced in comments by retrieving them with a single
# query from the database and injecting bug objects into the object-cache.
sub _preload_referenced_bugs {
my $self = shift;
my @referenced_bug_ids;
# inject current duplicates into the object-cache first
foreach my $bug (@{ $self->duplicates }) {
$bug->object_cache_set()
unless Bugzilla::Bug->object_cache_get($bug->id);
}
# preload bugs from comments
require Bugzilla::Template;
foreach my $comment (@{ $self->comments }) {
if ($comment->type == CMT_HAS_DUPE || $comment->type == CMT_DUPE_OF) {
# duplicate bugs that aren't currently in $self->duplicates
push @referenced_bug_ids, $comment->extra_data
unless Bugzilla::Bug->object_cache_get($comment->extra_data);
}
else {
# bugs referenced in comments
Bugzilla::Template::quoteUrls($comment->body, undef, undef, undef,
sub {
my $bug_id = $_[0];
push @referenced_bug_ids, $bug_id
unless Bugzilla::Bug->object_cache_get($bug_id);
});
}
}
# inject into object-cache
my $referenced_bugs = Bugzilla::Bug->new_from_list(
[ uniq @referenced_bug_ids ]);
foreach my $bug (@$referenced_bugs) {
$bug->object_cache_set();
}
}
sub possible_duplicates {
......@@ -3879,10 +3922,23 @@ sub EmitDependList {
# Creates a lot of bug objects in the same order as the input array.
sub _bugs_in_order {
my ($self, $bug_ids) = @_;
my $bugs = $self->new_from_list($bug_ids);
my %bug_map = map { $_->id => $_ } @$bugs;
my @result = map { $bug_map{$_} } @$bug_ids;
return \@result;
my %bug_map;
# there's no need to load bugs from the database if they are already in the
# object-cache
my @missing_ids;
foreach my $bug_id (@$bug_ids) {
if (my $bug = Bugzilla::Bug->object_cache_get($bug_id)) {
$bug_map{$bug_id} = $bug;
}
else {
push @missing_ids, $bug_id;
}
}
my $bugs = $self->new_from_list(\@missing_ids);
foreach my $bug (@$bugs) {
$bug_map{$bug->id} = $bug;
}
return [ map { $bug_map{$_} } @$bug_ids ];
}
# Get the activity of a bug, starting from $starttime (if given).
......
......@@ -196,6 +196,23 @@ sub initialize {
}
# Provides a mechanism for objects to be cached in the request_cache
sub object_cache_get {
my ($class, $id) = @_;
return $class->_object_cache_get(
{ id => $id, cache => 1},
$class
);
}
sub object_cache_set {
my $self = shift;
return $self->_object_cache_set(
{ id => $self->id, cache => 1 },
$self
);
}
sub _object_cache_get {
my $class = shift;
my ($param) = @_;
......@@ -1446,6 +1463,58 @@ Returns C<1> if the passed-in value is true, C<0> otherwise.
=back
=head2 CACHE FUNCTIONS
=over
=item C<object_cache_get>
=over
=item B<Description>
Class function which returns an object from the object-cache for the provided
C<$id>.
=item B<Params>
Takes an integer C<$id> of the object to retrieve.
=item B<Returns>
Returns the object from the cache if found, otherwise returns C<undef>.
=item B<Example>
my $bug_from_cache = Bugzilla::Bug->object_cache_get(35);
=back
=item C<object_cache_set>
=over
=item B<Description>
Object function which injects the object into the object-cache, using the
object's C<id> as the key.
=item B<Params>
(none)
=item B<Returns>
(nothing)
=item B<Example>
$bug->object_cache_set();
=back
=back
=head1 CLASS FUNCTIONS
=over
......
......@@ -147,9 +147,10 @@ sub get_format {
# If you want to modify this routine, read the comments carefully
sub quoteUrls {
my ($text, $bug, $comment, $user) = @_;
my ($text, $bug, $comment, $user, $bug_link_func) = @_;
return $text unless $text;
$user ||= Bugzilla->user;
$bug_link_func ||= \&get_bug_link;
# We use /g for speed, but uris can have other things inside them
# (http://foo/bug#3 for example). Filtering that out filters valid
......@@ -203,7 +204,7 @@ sub quoteUrls {
map { qr/$_/ } grep($_, Bugzilla->params->{'urlbase'},
Bugzilla->params->{'sslbase'})) . ')';
$text =~ s~\b(${urlbase_re}\Qshow_bug.cgi?id=\E([0-9]+)(\#c([0-9]+))?)\b
~($things[$count++] = get_bug_link($3, $1, { comment_num => $5, user => $user })) &&
~($things[$count++] = $bug_link_func->($3, $1, { comment_num => $5, user => $user })) &&
("\x{FDD2}" . ($count-1) . "\x{FDD3}")
~egox;
......@@ -250,7 +251,7 @@ sub quoteUrls {
$text =~ s~\b($bug_re(?:$s*,?$s*$comment_re)?|$comment_re)
~ # We have several choices. $1 here is the link, and $2-4 are set
# depending on which part matched
(defined($2) ? get_bug_link($2, $1, { comment_num => $3, user => $user }) :
(defined($2) ? $bug_link_func->($2, $1, { comment_num => $3, user => $user }) :
"<a href=\"$current_bugurl#c$4\">$1</a>")
~egx;
......@@ -266,7 +267,7 @@ sub quoteUrls {
my $length = $+[0] - $-[0];
my $match = $1;
$match =~ s/((?:#$s*)?(\d+))/get_bug_link($2, $1);/eg;
$match =~ s/((?:#$s*)?(\d+))/$bug_link_func->($2, $1);/eg;
# Replace the old string with the linkified one.
substr($text, $offset, $length) = $match;
}
......@@ -289,7 +290,7 @@ sub quoteUrls {
$text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ )
(\d+)
(?=\ \*\*\*\Z)
~get_bug_link($1, $1, { user => $user })
~$bug_link_func->($1, $1, { user => $user })
~egmx;
# Now remove the encoding hacks in reverse order
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment