File: held_results.rb

package info (click to toggle)
ruby-benchmark-memory 0.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 300 kB
  • sloc: ruby: 1,121; makefile: 7; sh: 4
file content (106 lines) | stat: -rw-r--r-- 2,694 bytes parent folder | download
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# frozen_string_literal: true

require 'forwardable'
require 'benchmark/memory/held_results/entry_serializer'

module Benchmark
  module Memory
    # Collate results that should be held until the next run.
    class HeldResults
      extend Forwardable

      # Instantiate a new set of held results on a path.
      #
      # @param path [String, IO] The path to write held results to.
      def initialize(path = nil)
        @path = path
        @results = {}
      end

      # @return [String, IO] The path to write held results to.
      attr_accessor :path

      # @return [Hash{String => Measurement}] Held results from previous runs.
      attr_reader :results

      # Allow Hash-like access to the results without asking for them.
      def_delegator :@results, :[]

      # Add a result to the held results.
      #
      # @param entry [Report::Entry] The entry to hold.
      #
      # @return [void]
      def add_result(entry)
        with_hold_file('a') do |file|
          file.write EntrySerializer.new(entry)
          file.write "\n"
        end
      end

      # Check whether any results have been stored.
      #
      # @return [Boolean]
      def any?
        if @path.is_a?(String)
          File.exist?(@path)
        else
          @path.size.positive?
        end
      end

      # Clean up the results after all results have been collated.
      #
      # @return [void]
      def cleanup
        File.delete(@path) if @path.is_a?(String) && File.exist?(@path)
      end

      # Check whether to hold results.
      #
      # @return [Boolean]
      def holding?
        !!@path
      end

      # Check whether an entry has been added to the results.
      #
      # @param entry [#label] The entry to check.
      #
      # @return [Boolean]
      def include?(entry)
        holding? && any? && results.key?(entry.label)
      end

      # Load results from the serialized output.
      #
      # @return [void]
      def load
        return unless holding? && any?

        results = with_hold_file do |file|
          file.map { |line| EntrySerializer.load(line) }
        end
        @results = results.map { |result| [result.label, result.measurement] }.to_h
      end

      private

      # Execute a block on the hold file.
      #
      # @param access_mode [String] The mode to use when opening the file.
      # @param _block [Proc] The block to execute on each line of the file.
      #
      # @return [void]
      def with_hold_file(access_mode = 'r', &block)
        return unless @path

        if @path.is_a?(String)
          File.open(@path, access_mode, &block)
        else
          yield @path
        end
      end
    end
  end
end