class Vernier::Result

def each_sample

def each_sample
  return enum_for(__method__) unless block_given?
  samples.size.times do |sample_idx|
    weight = weights[sample_idx]
    stack_idx = samples[sample_idx]
    yield stack(stack_idx), weight
  end
end

def elapsed_seconds

def elapsed_seconds
  (end_time - started_at) / 1_000_000_000.0
end

def inspect

def inspect
  "#<#{self.class} #{elapsed_seconds} seconds, #{threads.count} threads, #{samples.count} samples, #{samples.uniq.size} unique>"
end

def main_thread

def main_thread
  threads.values.detect {|x| x[:is_main] }
end

def sample_categories; threads.values.flat_map { _1[:sample_categories] }; end

def sample_categories; threads.values.flat_map { _1[:sample_categories] }; end

def samples; threads.values.flat_map { _1[:samples] }; end

def samples; threads.values.flat_map { _1[:samples] }; end

def stack(idx)

def stack(idx)
  stack_table.stack(idx)
end

def started_at

Realtime in nanoseconds since the unix epoch
def started_at
  started_at_mono_ns = meta[:started_at]
  current_time_mono_ns = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
  current_time_real_ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
  (current_time_real_ns - current_time_mono_ns + started_at_mono_ns)
end

def to_cpuprofile

def to_cpuprofile
  Output::Cpuprofile.new(self).output
end

def to_firefox(gzip: false)

def to_firefox(gzip: false)
  Output::Firefox.new(self).output(gzip:)
end

def total_bytes

def total_bytes
  weights.sum
end

def weights; threads.values.flat_map { _1[:weights] }; end

TODO: remove these
def weights; threads.values.flat_map { _1[:weights] }; end

def write(out:, format: "firefox")

def write(out:, format: "firefox")
  case format
  when "cpuprofile"
    File.binwrite(out, to_cpuprofile)
  when nil, "firefox"
    gzip = out.end_with?(".gz")
    File.binwrite(out, to_firefox(gzip:))
  else
    raise ArgumentError, "unknown format: #{format}"
  end
end