diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2017-08-24 19:17:04 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2017-09-05 12:53:45 +0300 |
commit | 42062a454a650d81d9fe6dddde7b39b056ec0a88 (patch) | |
tree | 2c4be27afab763e04404ddd32b021a098a5cfc15 /lib/gitlab/issuables_count_for_state.rb | |
parent | 3d61421fb2ed22d64a6b20701d600a38db1458f5 (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.rb | 50 |
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 |