Class: ArchUnit::Extraction::ExtractionProfile

Inherits:
Object
  • Object
show all
Defined in:
lib/archunit/extraction/extraction_profile.rb

Overview

Mutable per-run timing and counter collector for cold/warm extraction benchmarks.

Constant Summary collapse

STAGES =
%i[
  total
  project_discovery
  source_enumeration
  load_path_discovery
  file_read
  prism_parse
  import_extraction
  target_resolution
  target_index
  edge_classification
  edge_merge
].freeze
COUNTERS =
%i[
  source_files
  imports
  resolution_cache_hits
  resolution_cache_misses
  raw_edges
  merged_edges
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(clock: -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }) ⇒ ExtractionProfile

Returns a new instance of ExtractionProfile.

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
# File 'lib/archunit/extraction/extraction_profile.rb', line 43

def initialize(clock: -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) })
  raise ArgumentError, 'clock must respond to call' unless clock.respond_to?(:call)

  @clock = clock
  @stage_seconds = STAGES.to_h { |stage| [stage, 0.0] }
  @counters = COUNTERS.to_h { |counter| [counter, 0] }
  @cache_hit = false
end

Instance Attribute Details

#counters ⇒ Object (readonly)

Returns the value of attribute counters.



29
30
31
# File 'lib/archunit/extraction/extraction_profile.rb', line 29

def counters
  @counters
end

#stage_seconds ⇒ Object (readonly)

Returns the value of attribute stage_seconds.



29
30
31
# File 'lib/archunit/extraction/extraction_profile.rb', line 29

def stage_seconds
  @stage_seconds
end

Class Method Details

.measure(profile, stage, &operation) ⇒ Object



31
32
33
34
35
# File 'lib/archunit/extraction/extraction_profile.rb', line 31

def self.measure(profile, stage, &operation)
  return operation.call unless profile

  profile.measure(stage, &operation)
end

.validate(value) ⇒ Object

Raises:

  • (ArgumentError)


37
38
39
40
41
# File 'lib/archunit/extraction/extraction_profile.rb', line 37

def self.validate(value)
  return if value.nil? || value.is_a?(self)

  raise ArgumentError, 'profile must be an ExtractionProfile value or nil'
end

Instance Method Details

#cache_hit? ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/archunit/extraction/extraction_profile.rb', line 73

def cache_hit?
  @cache_hit
end

#increment(counter, amount = 1) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/archunit/extraction/extraction_profile.rb', line 60

def increment(counter, amount = 1)
  validate_counter(counter)
  unless amount.is_a?(Integer) && !amount.negative?
    raise ArgumentError, 'counter amount must be a non-negative Integer'
  end

  @counters[counter] += amount
end

#measure(stage) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/archunit/extraction/extraction_profile.rb', line 52

def measure(stage)
  validate_stage(stage)
  started_at = @clock.call
  yield
ensure
  @stage_seconds[stage] += @clock.call - started_at if started_at
end

#record_cache_hit ⇒ Object



69
70
71
# File 'lib/archunit/extraction/extraction_profile.rb', line 69

def record_cache_hit
  @cache_hit = true
end

#to_h ⇒ Object



77
78
79
80
81
82
83
# File 'lib/archunit/extraction/extraction_profile.rb', line 77

def to_h
  {
    cache_hit: cache_hit?,
    stage_seconds: stage_seconds.transform_values { |value| value.round(6) },
    counters: counters.dup
  }
end