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
|