Class: RSpecTracer::Tracker::DependencyGraph Private
- Inherits:
-
Object
- Object
- RSpecTracer::Tracker::DependencyGraph
- 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
-
#dependency_hash ⇒ Object
private
Snapshot projection.
-
#empty? ⇒ Boolean
private
Internal method on the tracer pipeline.
-
#example_ids ⇒ Object
private
Internal method on the tracer pipeline.
-
#examples_depending_on(change_set) ⇒ Object
private
O(|change_set| x avg-examples-per-file).
-
#initialize ⇒ DependencyGraph
constructor
private
Internal method on the tracer pipeline.
-
#paths_for(example_id) ⇒ Object
private
Internal method on the tracer pipeline.
-
#register_example(example_id, inputs) ⇒ Object
private
Internal method on the tracer pipeline.
-
#reverse_dependency_hash ⇒ Object
private
Internal method on the tracer pipeline.
Constructor Details
#initialize ⇒ DependencyGraph
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_hash ⇒ 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.
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.
68 69 70 |
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 68 def empty? @forward.empty? end |
#example_ids ⇒ 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.
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_hash ⇒ 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.
99 100 101 |
# File 'lib/rspec_tracer/tracker/dependency_graph.rb', line 99 def reverse_dependency_hash inverse_index.transform_values(&:dup) end |