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

candidates_csv_presenter.rb « ml « presenters « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8e2baf6bd28ec6fb860dee0922c200f4ed79fc07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# frozen_string_literal: true

module Ml
  class CandidatesCsvPresenter
    CANDIDATE_ASSOCIATIONS = [:latest_metrics, :params, :experiment].freeze
    # This file size limit is mainly to avoid the generation to hog resources from the server. The value is arbitrary
    # can be update once we have better insight into usage.
    TARGET_FILESIZE = 2.megabytes

    def initialize(candidates)
      @candidates = candidates
    end

    def present
      CsvBuilder.new(@candidates, headers, CANDIDATE_ASSOCIATIONS).render(TARGET_FILESIZE)
    end

    private

    def headers
      metric_names = columns_names(&:metrics)
      param_names = columns_names(&:params)

      candidate_to_metrics = @candidates.to_h do |candidate|
        [candidate.id, candidate.latest_metrics.to_h { |m| [m.name, m.value] }]
      end

      candidate_to_params = @candidates.to_h do |candidate|
        [candidate.id, candidate.params.to_h { |m| [m.name, m.value] }]
      end

      {
        project_id: 'project_id',
        experiment_iid: ->(c) { c.experiment.iid },
        candidate_iid: 'internal_id',
        name: 'name',
        external_id: 'eid',
        start_time: 'start_time',
        end_time: 'end_time',
        **param_names.index_with { |name| ->(c) { candidate_to_params.dig(c.id, name) } },
        **metric_names.index_with { |name| ->(c) { candidate_to_metrics.dig(c.id, name) } }
      }
    end

    def columns_names(&selector)
      @candidates.flat_map(&selector).map(&:name).uniq
    end
  end
end