class Flor::Pro::Sort
Public Instance Methods
Source
# File lib/flor/pcore/sort.rb, line 52 def pre_execute @node['atts'] = [] @node['col'] = nil # collection @node['fun'] = nil # function unatt_unkeyed_children end
Source
# File lib/flor/pcore/sort.rb, line 82 def receive_last @node['col'] ||= node_payload_ret if @node['col'].empty? wrap('ret' => @node['col']) elsif @node['fun'] quick_sort else default_sort end end
Source
# File lib/flor/pcore/sort.rb, line 62 def receive_non_att if @node['ranges'] quick_partition_receive else r = payload['ret'] if Flor.is_func_tree?(r) @node['fun'] ||= r elsif Flor.is_collection?(r) @node['col'] ||= r end super end end
Calls superclass method
Flor::Procedure#receive_non_att
Protected Instance Methods
Source
# File lib/flor/pcore/sort.rb, line 114 def default_sort col = @node['col'] classes = col.collect(&:class).uniq f = (classes.count > 1 || [ Hash ].include?(classes[0])) ? lambda { |e| e.is_a?(String) ? e : JSON.dump(e) } : lambda { |e| e } ret = col.sort_by(&f) ret = col.inject({}) { |h, (k, v)| h[k] = v; h } if col.is_a?(Hash) wrap('ret' => ret) end
When no function is given, turns to a collection of string (or JSON representations) and sorts
Source
# File lib/flor/pcore/sort.rb, line 174 def quick_compare(ra, a, b) col = @node['col'] va, vb = col[a], col[b] ra['kab'], ra['kba'] = quick_kab(va, vb) kab = ra['kab'] if kab && @node['memo'].has_key?(kab) quick_partition_receive(ra['sub'], @node['memo'][kab]) else apply(@node['fun'], [ [ 'a', va ], [ 'b', vb ] ], tree[2]) .tap { |ms| ra['sub'] = Flor.sub_nid(ms.first['nid']) } end end
Source
# File lib/flor/pcore/sort.rb, line 160 def quick_kab(va, vb) return [] unless @node['memo'] kab = [ va, vb ] .collect { |e| case e when Array, Hash, String then Digest::SHA256.hexdigest(JSON.dump(e)) else JSON.dump(e) end } [ kab.join('__'), kab.reverse.join('__') ] end
Source
# File lib/flor/pcore/sort.rb, line 190 def quick_partition_execute(lo, hi) return [] if lo >= hi ra = @node['ranges']["#{lo}_#{hi}"] ||= { 'i' => lo, 'j' => lo } quick_compare(ra, ra['j'], hi) # compare element at j with pivot (element at hi) end
Source
# File lib/flor/pcore/sort.rb, line 200 def quick_partition_receive(sn=from_sub_nid, r=:none) rk, ra = @node['ranges'].find { |_, v| v['sub'] == sn } lo, hi = rk.split('_').collect(&:to_i) i, j = ra['i'], ra['j'] if r == :none ret = payload_ret r = ret == true || (ret.is_a?(Numeric) && ret < 0) if m = @node['memo'] m[ra['kab']], m[ra['kba']] = r, ! r end end if r quick_swap(i, j) ra['i'] = i = (i + 1) end ra['j'] = j = (j + 1) return quick_partition_execute(lo, hi) if j < hi # loop on # partition loop is over... quick_swap(i, hi) @node['ranges'].delete(rk) # partition at i... ms = quick_partition_execute(lo, i - 1) + quick_partition_execute(i + 1, hi) if ms.any? ms elsif @node['ranges'].any? [] else # quicksort is over col = @node['col'] wrap('ret' => (@node['colk'] === 'object' ? Hash[col] : col)) end end
Source
# File lib/flor/pcore/sort.rb, line 136 def quick_sort col = @node['col'] @node['colk'] = col.is_a?(Hash) ? 'object' : 'array' @node['col'] = col.to_a @node['ranges'] = {} @node['memo'] = att('memo', 'cache') == false ? nil : {} quick_partition_execute(0, col.length - 1) end
A quicksort drives the game
Source
# File lib/flor/pcore/sort.rb, line 152 def quick_swap(a, b) return if a == b col = @node['col'] col[a], col[b] = col[b], col[a] end
Source
# File lib/flor/pcore/sort.rb, line 97 def receive_argument @node['args'] << payload['ret'] if children[@ncid] execute_child(@ncid) else iterate end end