Class: RSpecTracer::Tracker::DependencyGraph Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec_tracer/tracker/dependency_graph.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Directed bipartite graph over (example_id, file path). The forward map answers “which files does this example depend on?”; the memoized inverse answers “which examples depend on this file?” in O(1) per lookup.

The graph is append-only during a run. ‘register_example` is called once per example at example-finished time with the Input set that CoverageAdapter + IOHooks + DeclaredGlobs collected. The inverse is invalidated on every register_example and lazily rebuilt on the next `examples_depending_on` call.

Keyed by file path, not Input identity


An earlier design framed the inverse as “input_identity -> Set<example_id>”, which embeds the Input#kind (e.g. “ruby:lib/foo.rb” vs “declared:lib/foo.rb”). In practice the change-set that drives filtering comes from diffing Snapshot.all_files digests, which is keyed by path only - the kind that observed the file is not recoverable from a digest mismatch. Keying the graph by path eliminates that recovery burden and matches 1.x’s dependency.json shape exactly (Hash[example_id => Set<path>]), keeping the Snapshot byte-compatible. Kind-aware filtering, if ever needed, can layer on top without changing the graph shape.

API accepts Set<Input>, Set<String>, or any mix - anything that responds to :path is treated as an Input; otherwise ‘.to_s`. This keeps observer call sites terse (pass the Input set directly) without forcing Snapshot-load sites to reconstruct Input objects from paths.

Instance Method Summary collapse

Constructor Details

#initializeDependencyGraph

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.



41
42
43
44
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 41

def initialize
  @forward = {}
  @inverse_index = nil
end

Instance Method Details

#dependency_hashObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Snapshot projection. ‘dependency_hash` feeds Snapshot.dependency; `reverse_dependency_hash` feeds Snapshot.reverse_dependency. Both return fresh Sets per value so downstream mutation can’t leak into the graph’s state.



93
94
95
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 93

def dependency_hash
  @forward.transform_values(&:dup)
end

#empty?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.

Returns:

  • (Boolean)


68
69
70
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 68

def empty?
  @forward.empty?
end

#example_idsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.



62
63
64
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 62

def example_ids
  @forward.keys
end

#examples_depending_on(change_set) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

O(|change_set| x avg-examples-per-file). ‘change_set` can be a Set<Input>, Set<String>, or any mix - coerced the same way `register_example` coerces its inputs arg.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 75

def examples_depending_on(change_set)
  return Set.new if @forward.empty?

  paths = coerce_paths(change_set)
  return Set.new if paths.empty?

  affected = Set.new
  paths.each do |path|
    ids = inverse_index[path]
    affected.merge(ids) if ids
  end
  affected
end

#paths_for(example_id) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.



56
57
58
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 56

def paths_for(example_id)
  @forward[example_id] || Set.new
end

#register_example(example_id, inputs) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.



48
49
50
51
52
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 48

def register_example(example_id, inputs)
  @forward[example_id] = coerce_paths(inputs)
  @inverse_index = nil
  self
end

#reverse_dependency_hashObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method on the tracer pipeline.



99
100
101
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 99

def reverse_dependency_hash
  inverse_index.transform_values(&:dup)
end