summaryrefslogtreecommitdiff
path: root/lib/banzai
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2016-05-30 15:56:50 +0200
committerYorick Peterse <yorickpeterse@gmail.com>2016-06-02 14:01:42 +0200
commit01575e9966805fa4c12a7a56361f511b3b61e309 (patch)
treed5120613919d475313e48e87ef19ada3f7cb9475 /lib/banzai
parent8a6c3f27e9dfea2c151657045e17fe66ad81b5e5 (diff)
downloadgitlab-ce-01575e9966805fa4c12a7a56361f511b3b61e309.tar.gz
Reduce Namespace queries in UserReferenceFilterbanzai-user-filter-queries
This changes UserReferenceFilter so it operates using the following steps: 1. Grab all username references from the input document. 2. Query the corresponding Namespace objects using a single query. 3. Iterate over all nodes to build links while re-using the objects queried in step 2. The impact of these changes is that a comment mentioning 5 different usernames no longer runs 5 different queries (1 for every username), instead it only runs a single query.
Diffstat (limited to 'lib/banzai')
-rw-r--r--lib/banzai/filter/user_reference_filter.rb29
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb
index 331d8007257..5b0a6d8541b 100644
--- a/lib/banzai/filter/user_reference_filter.rb
+++ b/lib/banzai/filter/user_reference_filter.rb
@@ -29,7 +29,7 @@ module Banzai
ref_pattern = User.reference_pattern
ref_pattern_start = /\A#{ref_pattern}\z/
- each_node do |node|
+ nodes.each do |node|
if text_node?(node)
replace_text_when_pattern_matches(node, ref_pattern) do |content|
user_link_filter(content)
@@ -59,7 +59,7 @@ module Banzai
self.class.references_in(text) do |match, username|
if username == 'all'
link_to_all(link_text: link_text)
- elsif namespace = Namespace.find_by(path: username)
+ elsif namespace = namespaces[username]
link_to_namespace(namespace, link_text: link_text) || match
else
match
@@ -67,6 +67,31 @@ module Banzai
end
end
+ # Returns a Hash containing all Namespace objects for the username
+ # references in the current document.
+ #
+ # The keys of this Hash are the namespace paths, the values the
+ # corresponding Namespace objects.
+ def namespaces
+ @namespaces ||=
+ Namespace.where(path: usernames).each_with_object({}) do |row, hash|
+ hash[row.path] = row
+ end
+ end
+
+ # Returns all usernames referenced in the current document.
+ def usernames
+ refs = Set.new
+
+ nodes.each do |node|
+ node.to_html.scan(User.reference_pattern) do
+ refs << $~[:user]
+ end
+ end
+
+ refs.to_a
+ end
+
private
def urls