diff options
author | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-01-30 14:28:15 +0300 |
---|---|---|
committer | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-02-28 13:46:19 +0300 |
commit | a7b3f11edd626b7ba2fe4101951d2c9fe884b04a (patch) | |
tree | d3f63140f355976608830af8ea9c2b4f16ba1330 /lib/gitlab/cycle_analytics | |
parent | 4371f845649deaf6bf31f0a675b33f1d58f64de4 (diff) |
Adds get all medians to Cycle Analytics model
Diffstat (limited to 'lib/gitlab/cycle_analytics')
-rw-r--r-- | lib/gitlab/cycle_analytics/base_query.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/cycle_analytics/base_stage.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/cycle_analytics/usage_data.rb | 64 |
3 files changed, 74 insertions, 5 deletions
diff --git a/lib/gitlab/cycle_analytics/base_query.rb b/lib/gitlab/cycle_analytics/base_query.rb index 8b3bc3e440d..fee46fc0dda 100644 --- a/lib/gitlab/cycle_analytics/base_query.rb +++ b/lib/gitlab/cycle_analytics/base_query.rb @@ -14,7 +14,7 @@ module Gitlab def stage_query 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])) - .where(issue_table[:project_id].eq(@project.id)) # rubocop:disable Gitlab/ModuleWithInstanceVariables + .where(issue_table[:project_id].in(project_ids)) # rubocop:disable Gitlab/ModuleWithInstanceVariables .where(issue_table[:created_at].gteq(@options[:from])) # rubocop:disable Gitlab/ModuleWithInstanceVariables # Load merge_requests @@ -22,9 +22,14 @@ module Gitlab .on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])) .join(mr_metrics_table) .on(mr_table[:id].eq(mr_metrics_table[:merge_request_id])) + .project(issue_table[:project_id].as("project_id")) query end + + def project_ids + @projects.map(&:id) + end end end end diff --git a/lib/gitlab/cycle_analytics/base_stage.rb b/lib/gitlab/cycle_analytics/base_stage.rb index cac31ea8cff..c9de27ec481 100644 --- a/lib/gitlab/cycle_analytics/base_stage.rb +++ b/lib/gitlab/cycle_analytics/base_stage.rb @@ -3,8 +3,8 @@ module Gitlab class BaseStage include BaseQuery - def initialize(project:, options:) - @project = project + def initialize(projects:, options:) + @projects = projects @options = options end @@ -20,7 +20,7 @@ module Gitlab raise NotImplementedError.new("Expected #{self.name} to implement title") end - def median + def medians cte_table = Arel::Table.new("cte_table_for_#{name}") # Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time). @@ -31,7 +31,7 @@ module Gitlab cte_table, subtract_datetimes(base_query.dup, start_time_attrs, end_time_attrs, name.to_s)) - median_datetime(cte_table, interval_query, name) + median_datetimes(cte_table, interval_query, name) end def name diff --git a/lib/gitlab/cycle_analytics/usage_data.rb b/lib/gitlab/cycle_analytics/usage_data.rb new file mode 100644 index 00000000000..43ec9f9c493 --- /dev/null +++ b/lib/gitlab/cycle_analytics/usage_data.rb @@ -0,0 +1,64 @@ +module Gitlab + module CycleAnalytics + class UsageData + PROJECTS_LIMIT = 10 + + attr_reader :projects, :options + + def initialize(projects, options) + @projects = projects + @options = options + end + + def to_json + total = 0 + values = {} + + medians_per_stage.each do |stage_name, medians| + medians = medians.compact + + 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 + + values[:total] = total + + { avg_cycle_analytics: values } + end + + private + + def medians_per_stage + @medians_per_stage ||= ::CycleAnalytics.all_medians_per_stage(projects, options) + end + + def calc_average(values) + return if values.empty? + + (values.sum / values.length).to_i + end + + def sample_variance(values) + return 0 if values.length <= 1 + + avg = calc_average(values) + sum = values.inject(0) do |acc, val| + acc + (val - avg)**2 + end + + sum / (values.length - 1) + end + + def standard_deviation(values) + Math.sqrt(sample_variance(values)).to_i + end + end + end +end + |