From 30084ede70b1f17b620f5bb5d38ccabb3321f5df Mon Sep 17 00:00:00 2001 From: Max Kanat-Alexander Date: Thu, 8 Jul 2010 19:00:31 -0700 Subject: Bug 576670: Optimize Search.pm's "init" method for being called many times in a loop r=glob, a=mkanat --- Bugzilla.pm | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'Bugzilla.pm') diff --git a/Bugzilla.pm b/Bugzilla.pm index 33df05efb..6ecbc27db 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -523,6 +523,45 @@ sub switch_to_main_db { return $class->dbh_main; } +sub fields { + my ($class, $criteria) = @_; + $criteria ||= {}; + my $cache = $class->request_cache; + + # We create an advanced cache for fields by type, so that we + # can avoid going back to the database for every fields() call. + # (And most of our fields() calls are for getting fields by type.) + # + # We also cache fields by name, because calling $field->name a few + # million times can be slow in calling code, but if we just do it + # once here, that makes things a lot faster for callers. + if (!defined $cache->{fields}) { + my @all_fields = Bugzilla::Field->get_all; + my (%by_name, %by_type); + foreach my $field (@all_fields) { + my $name = $field->name; + $by_type{$field->type}->{$name} = $field; + $by_name{$name} = $field; + } + $cache->{fields} = { by_type => \%by_type, by_name => \%by_name }; + } + + my $fields = $cache->{fields}; + my %requested; + if (my $types = $criteria->{type}) { + $types = ref($types) ? $types : [$types]; + %requested = map { %{ $fields->{by_type}->{$_} || {} } } @$types; + } + else { + %requested = %{ $fields->{by_name} }; + } + + my $do_by_name = $criteria->{by_name}; + + return $do_by_name ? \%requested : [values %requested]; +} + +# DEPRECATED. Use fields() instead. sub get_fields { my $class = shift; my $criteria = shift; @@ -768,6 +807,30 @@ Essentially, causes calls to Cuser> to return C. This has effect of logging out a user for the current request only; cookies and database sessions are left intact. +=item C + +This is the standard way to get arrays or hashes of L +objects when you need them. It takes the following named arguments +in a hashref: + +=over + +=item C + +If false (or not specified), this method will return an arrayref of +the requested fields. The order of the returned fields is random. + +If true, this method will return a hashref of fields, where the keys +are field names and the valules are L objects. + +=item C + +Either a single C constant or an arrayref of them. If specified, +the returned fields will be limited to the types in the list. If you don't +specify this argument, all fields will be returned. + +=back + =item C Call either Cerror_mode(Bugzilla::Constants::ERROR_MODE_DIE)> -- cgit v1.2.3-24-g4f1b