Class: Percolate::Facet::TagFacet::TagPoset
- Inherits:
-
Object
- Object
- Percolate::Facet::TagFacet::TagPoset
- Defined in:
- lib/percolate/facet/tag_facet.rb
Overview
A data structure representing the partial order induced on collections of tags.
Instance Attribute Summary collapse
-
#supersets ⇒ Object
readonly
Returns the value of attribute supersets.
-
#tags ⇒ Object
readonly
Returns the value of attribute tags.
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Instance Method Summary collapse
-
#initialize(tags = [], value = nil, supersets = []) ⇒ TagPoset
constructor
The constructor.
-
#insert(tags, value, visited = Set.new) ⇒ Object
Inserts the given collection of tags and its associated value into the partial order.
-
#matches(tags, visited = Set.new) ⇒ Array
Calculates the best matches for the given collection of tags.
-
#merge(other) ⇒ TagPoset
Merges the given TagPoset with this one.
-
#merge!(other, visited = Set.new) ⇒ TagPoset
Mutatively merges the given TagPoset with this one.
-
#transitives(remainder, visited = Set.new) ⇒ Array
Finds transitive supersets that contain the given collection of tags.
Constructor Details
#initialize(tags = [], value = nil, supersets = []) ⇒ TagPoset
The constructor.
67 68 69 70 71 |
# File 'lib/percolate/facet/tag_facet.rb', line 67 def initialize( = [], value = nil, supersets = []) = @value = value @supersets = supersets end |
Instance Attribute Details
#supersets ⇒ Object (readonly)
Returns the value of attribute supersets.
60 61 62 |
# File 'lib/percolate/facet/tag_facet.rb', line 60 def supersets @supersets end |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
60 61 62 |
# File 'lib/percolate/facet/tag_facet.rb', line 60 def end |
#value ⇒ Object (readonly)
Returns the value of attribute value.
60 61 62 |
# File 'lib/percolate/facet/tag_facet.rb', line 60 def value @value end |
Instance Method Details
#insert(tags, value, visited = Set.new) ⇒ Object
Inserts the given collection of tags and its associated value into the partial order.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/percolate/facet/tag_facet.rb', line 78 def insert(, value, visited = Set.new) = .sort # We got an exact match. Override the value and return. if == @value = value return value end n_supersets = 0 subset_indices = [] @supersets.each_with_index do |superset, i| if superset. - == [] superset.insert(, value, visited) if !visited.add?(superset.).nil? n_supersets = n_supersets + 1 elsif - superset. == [] subset_indices.push(i) end end # We visited a superset; there's no more work to be done in this frame. if n_supersets > 0 return value end if !subset_indices.empty? # The tags are a subset of at least one superset; insert them in between this poset and the superset(s). tp = TagPoset.new(, value, subset_indices.map { |i| @supersets[i] }) subset_indices.each { |i| @supersets[i] = nil } @supersets = @supersets.select { |item| !item.nil? }.to_a else # The tags are not a subset of any superset; insert them separately. tp = TagPoset.new(, value, transitives()) end # Insert the new poset with binary search for stability. insertion_index = (0...@supersets.size).bsearch { |i| (@supersets[i]. <=> ) >= 0 } || @supersets.size @supersets.insert(insertion_index, tp) value end |
#matches(tags, visited = Set.new) ⇒ Array
Calculates the best matches for the given collection of tags.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/percolate/facet/tag_facet.rb', line 166 def matches(, visited = Set.new) = .sort matches = [] n_supersets = 0 @supersets.each do |superset| if superset. - == [] matches.concat(superset.matches(, visited)) if !visited.add?(superset.).nil? n_supersets = n_supersets + 1 end end # We didn't visit a superset; push on the associated value as a best match. if n_supersets == 0 && !@value.nil? matches.push(@value) end matches end |
#merge(other) ⇒ TagPoset
Merges the given Percolate::Facet::TagFacet::TagPoset with this one.
192 193 194 |
# File 'lib/percolate/facet/tag_facet.rb', line 192 def merge(other) TagPoset.new.merge!(self).merge!(other) end |
#merge!(other, visited = Set.new) ⇒ TagPoset
Mutatively merges the given Percolate::Facet::TagFacet::TagPoset with this one.
201 202 203 204 205 206 207 208 209 |
# File 'lib/percolate/facet/tag_facet.rb', line 201 def merge!(other, visited = Set.new) insert(other., other.value) other.supersets.each do |superset| merge!(superset, visited) if !visited.add?(superset.).nil? end self end |
#transitives(remainder, visited = Set.new) ⇒ Array
Finds transitive supersets that contain the given collection of tags.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/percolate/facet/tag_facet.rb', line 130 def transitives(remainder, visited = Set.new) transitives = [] @supersets.each do |superset| r_remainder = remainder - superset. if r_remainder != [] r_transitives = superset.transitives(r_remainder, visited) r_transitives = r_transitives.select do |r_superset| transitives.select do |superset| superset. - r_superset. == [] end.empty? end.to_a transitives = transitives.select do |superset| r_transitives.select do |r_superset| r_superset. - superset. == [] end.empty? end.to_a transitives.concat(r_transitives) else transitives.push(superset) end if !visited.add?(superset.).nil? end transitives end |