Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2017-08-24 19:17:04 +0300
committerYorick Peterse <yorickpeterse@gmail.com>2017-09-05 12:53:45 +0300
commit42062a454a650d81d9fe6dddde7b39b056ec0a88 (patch)
tree2c4be27afab763e04404ddd32b021a098a5cfc15 /lib/gitlab/issuables_count_for_state.rb
parent3d61421fb2ed22d64a6b20701d600a38db1458f5 (diff)
Re-use issue/MR counts for the pagination system
This changes the issue and MR index pages so the pagination system re-uses the output of the COUNT(*) query used to calculate the number of rows per state (opened, closed, etc). This removes the need for an additional COUNT(*) on both pages.
Diffstat (limited to 'lib/gitlab/issuables_count_for_state.rb')
-rw-r--r--lib/gitlab/issuables_count_for_state.rb50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/gitlab/issuables_count_for_state.rb b/lib/gitlab/issuables_count_for_state.rb
new file mode 100644
index 00000000000..505810964bc
--- /dev/null
+++ b/lib/gitlab/issuables_count_for_state.rb
@@ -0,0 +1,50 @@
+module Gitlab
+ # Class for counting and caching the number of issuables per state.
+ class IssuablesCountForState
+ # The name of the RequestStore cache key.
+ CACHE_KEY = :issuables_count_for_state
+
+ # The state values that can be safely casted to a Symbol.
+ STATES = %w[opened closed merged all].freeze
+
+ # finder - The finder class to use for retrieving the issuables.
+ def initialize(finder)
+ @finder = finder
+ @cache =
+ if RequestStore.active?
+ RequestStore[CACHE_KEY] ||= initialize_cache
+ else
+ initialize_cache
+ end
+ end
+
+ def for_state_or_opened(state = nil)
+ self[state || :opened]
+ end
+
+ # Returns the count for the given state.
+ #
+ # state - The name of the state as either a String or a Symbol.
+ #
+ # Returns an Integer.
+ def [](state)
+ state = state.to_sym if cast_state_to_symbol?(state)
+
+ cache_for_finder[state] || 0
+ end
+
+ private
+
+ def cache_for_finder
+ @cache[@finder]
+ end
+
+ def cast_state_to_symbol?(state)
+ state.is_a?(String) && STATES.include?(state)
+ end
+
+ def initialize_cache
+ Hash.new { |hash, finder| hash[finder] = finder.count_by_state }
+ end
+ end
+end