Class: Nanoc::Core::ItemRepSelector::ItemRepPriorityQueue

Inherits:
Object
  • Object
show all
Defined in:
lib/nanoc/core/item_rep_selector.rb

Overview

A priority queue that tracks dependencies and can detect circular dependencies.

Instance Method Summary collapse

Constructor Details

#initialize(reps) ⇒ ItemRepPriorityQueue

Returns a new instance of ItemRepPriorityQueue.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/nanoc/core/item_rep_selector.rb', line 14

def initialize(reps)
  # Prio A: most important; prio C: least important.
  @prio_a = nil
  @prio_b = reps.dup
  @prio_c = []

  # List of reps that we’ve already seen. Reps from `reps` will end up
  # in here. Reps can end up in here even *before* they come from
  # `reps`, when they are part of a dependency.
  @seen = Set.new

  # List of reps that have already been completed (yielded followed by
  # `#mark_ok`).
  @completed = Set.new

  # Record (hard) dependencies. Used for detecting cycles.
  @dependencies = Hash.new { |hash, key| hash[key] = Set.new }
end

Instance Method Details

#mark_failed(dep) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/nanoc/core/item_rep_selector.rb', line 62

def mark_failed(dep)
  record_dependency(dep)

  # `@this` depends on `dep`, so `dep` has to be compiled first. Thus,
  # move `@this` into priority C, and `dep` into priority A.

  # Put `@this` (item rep that needs `dep` to be compiled first) into
  # priority C (lowest prio).
  @prio_c.push(@this) unless @prio_c.include?(@this)

  # Put `dep` (item rep that needs to be compiled first, before
  # `@this`) into priority A (highest prio).
  @prio_a = dep

  # Remember that we’ve prioritised `dep`. This particular element will
  # come from @prio_b at some point in the future, so we’ll have to skip
  # it then.
  @seen << dep
end

#mark_okObject



58
59
60
# File 'lib/nanoc/core/item_rep_selector.rb', line 58

def mark_ok
  @completed << @this
end

#nextObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/nanoc/core/item_rep_selector.rb', line 33

def next
  # Read prio A
  @this = @prio_a
  if @this
    @prio_a = nil
    return @this
  end

  # Read prio B
  @this = @prio_b.shift
  @this = @prio_b.shift while @seen.include?(@this)
  if @this
    return @this
  end

  # Read prio C
  @this = @prio_c.pop
  @this = @prio_c.pop while @completed.include?(@this)
  if @this
    return @this
  end

  nil
end