Class: Pacer::Filter::PropertyFilter::Filters
- Inherits:
-
Object
- Object
- Pacer::Filter::PropertyFilter::Filters
- Defined in:
- lib/pacer/filter/property_filter/filters.rb
Direct Known Subclasses
Constant Summary collapse
- NodeVisitor =
Pacer::Filter::WhereFilter::NodeVisitor
Instance Attribute Summary collapse
-
#best_index_value ⇒ Object
readonly
Returns the value of attribute best_index_value.
-
#blocks ⇒ Object
Returns the value of attribute blocks.
-
#choose_best_index ⇒ Object
Allow Pacer to use index counts to determine which index has the least number elements for the available keys in the query.
-
#extensions ⇒ Object
readonly
Returns the value of attribute extensions.
-
#graph ⇒ Object
Set which graph this filter is currently operating on.
-
#indices ⇒ Object
Set which indices are available to be used to determine the best_index.
-
#properties ⇒ Object
readonly
Returns the value of attribute properties.
-
#route_modules ⇒ Object
readonly
Returns the value of attribute route_modules.
-
#search_manual_indices ⇒ Object
Allow Pacer to use manual indices without explicitly referencing them by name.
-
#wrapper ⇒ Object
Returns the value of attribute wrapper.
Instance Method Summary collapse
- #any? ⇒ Boolean
- #best_index(element_type) ⇒ Object
- #build_pipeline(route, start_pipe, pipe = nil) ⇒ Object
- #combine_sets ⇒ Object
- #extensions_only? ⇒ Boolean
-
#initialize(graph, filters) ⇒ Filters
constructor
A new instance of Filters.
- #property_keys ⇒ Object
- #remove_property_keys(keys) ⇒ Object
-
#to_predicate ⇒ Object
Not used for regular filtering, but useful to test an element against a complex set of conditions without having to build a route.
- #to_s ⇒ Object
-
#use_lookup! ⇒ Object
Check #lookup in extensions, in preerence to #route_conditions for filters to apply.
Constructor Details
#initialize(graph, filters) ⇒ Filters
Returns a new instance of Filters.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 62 def initialize(graph, filters) if graph.is_a? Pacer::Wrappers::ElementWrapper # this can happen if the starting route is actually a single element. @graph = graph.graph else @graph = graph end @properties = [] @blocks = [] @extensions = [] @wrapper = nil @route_modules = [] @non_ext_props = [] @best_index_value = nil add_filters filters, nil combine_sets end |
Instance Attribute Details
#best_index_value ⇒ Object (readonly)
Returns the value of attribute best_index_value.
39 40 41 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 39 def best_index_value @best_index_value end |
#blocks ⇒ Object
Returns the value of attribute blocks.
40 41 42 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 40 def blocks @blocks end |
#choose_best_index ⇒ Object
Allow Pacer to use index counts to determine which index has the least number elements for the available keys in the query.
46 47 48 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 46 def choose_best_index @choose_best_index end |
#extensions ⇒ Object (readonly)
Returns the value of attribute extensions.
39 40 41 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 39 def extensions @extensions end |
#graph ⇒ Object
this is not threadsafe if you are reusing predefined routes on multiple graphs.
Set which graph this filter is currently operating on
106 107 108 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 106 def graph @graph end |
#indices ⇒ Object
Set which indices are available to be used to determine the best_index.
128 129 130 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 128 def indices @indices end |
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
39 40 41 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 39 def properties @properties end |
#route_modules ⇒ Object (readonly)
Returns the value of attribute route_modules.
39 40 41 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 39 def route_modules @route_modules end |
#search_manual_indices ⇒ Object
Allow Pacer to use manual indices without explicitly referencing them by name.
60 61 62 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 60 def search_manual_indices @search_manual_indices end |
#wrapper ⇒ Object
Returns the value of attribute wrapper.
40 41 42 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 40 def wrapper @wrapper end |
Instance Method Details
#any? ⇒ Boolean
189 190 191 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 189 def any? properties.any? or blocks.any? or route_modules.any? or extensions.any? end |
#best_index(element_type) ⇒ Object
213 214 215 216 217 218 219 220 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 213 def best_index(element_type) result = find_best_index(element_type) # the call to find_best_index produces @best_index_value: if properties.delete @best_index_value @encoded_properties = nil end result end |
#build_pipeline(route, start_pipe, pipe = nil) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 150 def build_pipeline(route, start_pipe, pipe = nil) pipe ||= start_pipe if route self.graph = route.graph route_modules.each do |mod| extension_route = mod.route(Pacer::Route.empty(route)) s, e = extension_route.send :build_pipeline s.setStarts(pipe) if pipe start_pipe ||= s pipe = e end end encoded_properties.each do |key, value| case value when NodeVisitor::Pipe new_pipe = value.build when NodeVisitor::Value # no op else new_pipe = PropertyFilterPipe.new(key, Pacer::Pipes::EQUAL, value) end if new_pipe new_pipe.set_starts pipe if pipe Pacer.debug_pipes << { :name => key, :start => pipe, :end => new_pipe } if Pacer.debug_pipes pipe = new_pipe start_pipe ||= pipe end end blocks.each do |block| # Will work if route is nil. block_pipe = Pacer::Pipes::BlockFilterPipe.new(route, block) block_pipe.set_starts pipe if pipe Pacer.debug_pipes << { :name => 'block', :start => pipe, :end => block_pipe } if Pacer.debug_pipes pipe = block_pipe start_pipe ||= pipe end [start_pipe, pipe] end |
#combine_sets ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 80 def combine_sets is_set = properties.group_by { |p| p[1].is_a? Set } sets = is_set[true] # [["x", Set[]] ...] if sets is_multi = sets.group_by { |a| a.count > 1 } multi = is_multi[true] if multi multi = multi.group_by { |m| m.first } # {"x": [["x", Set[]], ...]} result = multi.map do |multi_set| multi_set[1].reduce do |result, pair| [result[0], result[1].intersection(pair[1])] end end result = result.concat(is_multi[false]) if is_multi[false] result = result.concat(is_set[false]) if is_set[false] @properties = result end end end |
#extensions_only? ⇒ Boolean
193 194 195 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 193 def extensions_only? properties.none? and blocks.none? and route_modules.none? and (extensions.any? or wrapper) end |
#property_keys ⇒ Object
120 121 122 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 120 def property_keys properties.map(&:first).uniq end |
#remove_property_keys(keys) ⇒ Object
115 116 117 118 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 115 def remove_property_keys(keys) properties.delete_if { |a| keys.include? a.first } non_ext_props.delete_if { |a| keys.include? a.first } end |
#to_predicate ⇒ Object
Not used for regular filtering, but useful to test an element against a complex set of conditions without having to build a route.
Returns a proc that can be called with an element to test and returns true if the element matches the conditions.
142 143 144 145 146 147 148 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 142 def to_predicate , pipe = build_pipeline(nil, com.tinkerpop.pipes.util.iterators.ExpandableIterator.new) proc do |e| .add e pipe.next if pipe.hasNext end end |
#to_s ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 197 def to_s strings = [] strings << [wrapper.name] if wrapper strings.concat extensions.map { |e| e.name } strings.concat((non_ext_props - [@best_index_value]).map { |k, v| if v.is_a? Set "#{ k } IN (#{ v.sort.map { |s| s.inspect }.join ', ' })" else "#{ k }==#{ v.inspect }" end }) strings.concat blocks.map { '&block' } strings.concat route_modules.map { |mod| mod.name } strings.join ', ' end |
#use_lookup! ⇒ Object
Check #lookup in extensions, in preerence to #route_conditions for filters to apply.
Designed to allow filters to be defined in extensions that will not be used on every appearance of the extension (too many property filters in a traversal can impose a serious performance penalty. It is expected that lookup filters will only be used for index lookups.
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/pacer/filter/property_filter/filters.rb', line 230 def use_lookup! extensions.each do |ext| if ext.respond_to? :lookup add_filters ext.lookup(graph), ext end end if wrapper and wrapper.respond_to? :lookup add_filters wrapper.lookup(graph), nil end end |