summaryrefslogtreecommitdiff
path: root/lib/gitlab/cycle_analytics
diff options
context:
space:
mode:
authorTiago Botelho <tiagonbotelho@hotmail.com>2018-02-15 13:23:39 +0000
committerTiago Botelho <tiagonbotelho@hotmail.com>2018-02-28 10:46:20 +0000
commit335ee79a73fafdf00fac6e8ffc286ce4bad273ff (patch)
treed30033fd007c992448ce02f42e46f9da48e223cb /lib/gitlab/cycle_analytics
parent3f31da9c69c550d1698a1376e37d36f4e6e309b5 (diff)
downloadgitlab-ce-335ee79a73fafdf00fac6e8ffc286ce4bad273ff.tar.gz
Refactors median code to work with both single and multiple projects
Diffstat (limited to 'lib/gitlab/cycle_analytics')
-rw-r--r--lib/gitlab/cycle_analytics/base_query.rb4
-rw-r--r--lib/gitlab/cycle_analytics/base_stage.rb8
-rw-r--r--lib/gitlab/cycle_analytics/usage_data.rb48
3 files changed, 34 insertions, 26 deletions
diff --git a/lib/gitlab/cycle_analytics/base_query.rb b/lib/gitlab/cycle_analytics/base_query.rb
index b9075047487..def9885789e 100644
--- a/lib/gitlab/cycle_analytics/base_query.rb
+++ b/lib/gitlab/cycle_analytics/base_query.rb
@@ -8,14 +8,14 @@ module Gitlab
private
def base_query
- @base_query ||= stage_query([@project.id]) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ @base_query ||= stage_query(@project.id) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
def stage_query(project_ids)
query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id]))
.join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id]))
.project(issue_table[:project_id].as("project_id"))
- .where(issue_table[:project_id].in(project_ids))
+ .where(issue_table[:project_id].in(Array(project_ids)))
.where(issue_table[:created_at].gteq(@options[:from])) # rubocop:disable Gitlab/ModuleWithInstanceVariables
# Load merge_requests
diff --git a/lib/gitlab/cycle_analytics/base_stage.rb b/lib/gitlab/cycle_analytics/base_stage.rb
index 45386fee622..5c3fd901f79 100644
--- a/lib/gitlab/cycle_analytics/base_stage.rb
+++ b/lib/gitlab/cycle_analytics/base_stage.rb
@@ -31,8 +31,12 @@ module Gitlab
interval_query = Arel::Nodes::As.new(cte_table,
subtract_datetimes(stage_query(project_ids), start_time_attrs, end_time_attrs, name.to_s))
- median_datetimes(cte_table, interval_query, name, :project_id)&.each do |project_id, median|
- loader.call(project_id, median)
+ if project_ids.size == 1
+ loader.call(@project.id, median_datetime(cte_table, interval_query, name))
+ else
+ median_datetimes(cte_table, interval_query, name, :project_id)&.each do |project_id, median|
+ loader.call(project_id, median)
+ end
end
end
end
diff --git a/lib/gitlab/cycle_analytics/usage_data.rb b/lib/gitlab/cycle_analytics/usage_data.rb
index 0aefd434e14..5122e3417ca 100644
--- a/lib/gitlab/cycle_analytics/usage_data.rb
+++ b/lib/gitlab/cycle_analytics/usage_data.rb
@@ -5,27 +5,21 @@ module Gitlab
attr_reader :projects, :options
- def initialize(projects, options)
- @projects = projects
- @options = options
+ def initialize
+ @projects = Project.sorted_by_activity.limit(PROJECTS_LIMIT)
+ @options = { from: 7.days.ago }
end
def to_json
total = 0
- values = {}
- medians_per_stage.each do |stage_name, medians|
- medians = medians.map(&:presence).compact
+ values =
+ medians_per_stage.each_with_object({}) do |(stage_name, medians), hsh|
+ calculations = stage_values(medians)
- stage_values = {
- average: calc_average(medians),
- sd: standard_deviation(medians),
- missing: projects.length - medians.length
- }
-
- total += stage_values.values.compact.sum
- values[stage_name] = stage_values
- end
+ total += calculations.values.compact.sum
+ hsh[stage_name] = calculations
+ end
values[:total] = total
@@ -43,26 +37,36 @@ module Gitlab
end
end
+ def stage_values(medians)
+ medians = medians.map(&:presence).compact
+ average = calc_average(medians)
+
+ {
+ average: average,
+ sd: standard_deviation(medians, average),
+ missing: projects.length - medians.length
+ }
+ end
+
def calc_average(values)
return if values.empty?
(values.sum / values.length).to_i
end
- def sample_variance(values)
+ def standard_deviation(values, average)
+ Math.sqrt(sample_variance(values, average)).to_i
+ end
+
+ def sample_variance(values, average)
return 0 if values.length <= 1
- avg = calc_average(values)
sum = values.inject(0) do |acc, val|
- acc + (val - avg)**2
+ acc + (val - average)**2
end
sum / (values.length - 1)
end
-
- def standard_deviation(values)
- Math.sqrt(sample_variance(values)).to_i
- end
end
end
end