summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2014-07-03 09:36:08 +0200
committerByron Jones <glob@mozilla.com>2014-07-03 09:36:08 +0200
commit99e02eab80679cb1ac4ede7c4d8054b8a2164bad (patch)
tree6b406d68f5f9c0a260f44366b9ecf4d2b2604586 /Bugzilla
parenta26d34af37d00485846cdf3978b726824f6138d4 (diff)
downloadbugzilla-99e02eab80679cb1ac4ede7c4d8054b8a2164bad.tar.gz
bugzilla-99e02eab80679cb1ac4ede7c4d8054b8a2164bad.tar.xz
Bug 1028795: pre-load all related bugs during show_bug initialisation
r=sgreen,a=sgreen
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Bug.pm64
-rw-r--r--Bugzilla/Object.pm69
-rw-r--r--Bugzilla/Template.pm11
3 files changed, 135 insertions, 9 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index cb132f31d..b762a6500 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -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).
diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm
index e5704b3b1..f20803632 100644
--- a/Bugzilla/Object.pm
+++ b/Bugzilla/Object.pm
@@ -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
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index d1457a4fa..8fe50fa4f 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -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