andromeda 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,7 +36,7 @@ module Andromeda
36
36
  end
37
37
  end
38
38
 
39
- class SendError < RuntimeError ; end
39
+ class SendError < RuntimeError ; end
40
40
  class ExecError < RuntimeError ; end
41
41
 
42
42
  end
@@ -2,7 +2,7 @@ module Andromeda
2
2
 
3
3
  module Guides
4
4
 
5
- class Guide
5
+ class Guide
6
6
  def track(spot, key, suggested_track = nil)
7
7
  raise NoMethodError
8
8
  end
@@ -11,7 +11,7 @@ module Andromeda
11
11
  return plan.copy if was_suggested
12
12
  if plan.frozen? then plan else plan.copy end
13
13
  end
14
- end
14
+ end
15
15
 
16
16
  class Track
17
17
  def follow(*args, &thunk) ; thunk.call *args end
@@ -1,8 +1,7 @@
1
1
  module Andromeda
2
-
3
2
  module Guides
4
3
 
5
- class Guide
4
+ class Guide
6
5
  include Andromeda::Impl::To_S
7
6
 
8
7
  def track(spot, label, suggested_track = nil)
@@ -20,7 +19,7 @@ module Andromeda
20
19
  if plan.frozen? then plan else plan.identical_copy end
21
20
  end
22
21
 
23
- end
22
+ end
24
23
 
25
24
  class Track
26
25
  include Andromeda::Impl::To_S
@@ -1,19 +1,19 @@
1
1
  module Andromeda
2
2
 
3
- class Id < Impl::XorId
4
- # Default length of generated ids
5
- DEFAULT_NUM_BYTES = 8
3
+ class Id < Impl::XorId
4
+ # Default length of generated ids
5
+ DEFAULT_NUM_BYTES = 8
6
6
 
7
- # @param [Bool] random
8
- def initialize(random = true)
9
- super DEFAULT_NUM_BYTES, random
10
- end
7
+ # @param [Bool] random
8
+ def initialize(random = true)
9
+ super DEFAULT_NUM_BYTES, random
10
+ end
11
11
 
12
- # @return [Id] empty (zero) id
13
- def self.zero
14
- @id = self.new false unless defined? @id
15
- @id
16
- end
17
- end
12
+ # @return [Id] empty (zero) id
13
+ def self.zero
14
+ @id = self.new false unless defined? @id
15
+ @id
16
+ end
17
+ end
18
18
 
19
19
  end
@@ -2,7 +2,7 @@ module Andromeda
2
2
 
3
3
  module Impl
4
4
 
5
- module ClassAttr
5
+ module ClassAttr
6
6
 
7
7
  protected
8
8
 
@@ -24,7 +24,7 @@ module Andromeda
24
24
  dest_set = get_attr_set var_name, false
25
25
  instance_variable_set var_name, dest_set.union(name_set)
26
26
  end
27
- end
27
+ end
28
28
 
29
29
  end
30
30
 
@@ -0,0 +1,89 @@
1
+ module Andromeda
2
+
3
+ module Impl
4
+
5
+ # Generator for random xorable ids (used for markers)
6
+ class XorId
7
+ include To_S
8
+
9
+ protected
10
+
11
+ def initialize(len, random = true, init_data = nil)
12
+ raise ArgumentError unless len.kind_of?(Fixnum)
13
+ raise ArgumentError unless len >= 0
14
+
15
+ @data = if init_data
16
+ init_data
17
+ else
18
+ if random
19
+ then len.times.map { Id.rnd_byte }
20
+ else len.times.map { 0 } end
21
+ end
22
+ end
23
+
24
+ public
25
+
26
+ def clone_to_copy? ; false end
27
+ def identical_copy ; self end
28
+
29
+ def length ; @data.length end
30
+ def zero? ; each { |b| return false unless b == 0 } ; true end
31
+
32
+ def [](key) ; @data[key] end
33
+
34
+ def same_length?(obj) ; self.length == obj.length end
35
+
36
+ def each ; this = self ; 0.upto(length-1).each { |i| yield this[i] } end
37
+ def each_with_index ; this = self ; 0.upto(length-1).each { |i| yield i, this[i] } end
38
+
39
+ # Compare self to b
40
+ # @param [Id] b
41
+ def ==(b)
42
+ return true if self.equal? b
43
+ return false if b.nil?
44
+ return false unless b.class.equal? self.class
45
+ return false unless same_length? b
46
+ zip_bytes(b) { |i, j| return false if i != j }
47
+ true
48
+ end
49
+
50
+ def hash ; @data.hash end
51
+
52
+ # xor self and b's ids component-wise
53
+ # @param [Array<Fixnum>] b
54
+ # @return [Id]
55
+ def xor(b)
56
+ r = []
57
+ zip_bytes(b) { |i,j| r << (i ^ j) }
58
+ Id.new r.length, false, r
59
+ end
60
+
61
+ def to_short_s
62
+ r = ''
63
+ each { |b| r << Id.two_char_hex_str(b.to_s(16)) }
64
+ r
65
+ end
66
+
67
+ def inspect ; to_s end
68
+
69
+ private
70
+
71
+ def zip_bytes(b)
72
+ a = self
73
+ 0.upto(length-1).each { |i| yield a[i], b[i] }
74
+ end
75
+
76
+ def self.rnd_byte ; Random.rand(256) end
77
+
78
+ def self.two_char_hex_str(s)
79
+ case s.length
80
+ when 0 then '00'
81
+ when 1 then "0#{s}"
82
+ else s
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -8,21 +8,21 @@ module Andromeda
8
8
  extend Impl::ClassAttr
9
9
 
10
10
  def self.spot_names(inherit = true) ; get_attr_set '@spot_names', inherit end
11
- def self.attr_spot_names(inherit = true) ; get_attr_set '@attr_spot_names', inherit end
12
- def self.meth_spot_names(inherit = true) ; get_attr_set '@meth_spot_names', inherit end
11
+ def self.spot_attr_names(inherit = true) ; get_attr_set '@spot_attr_names', inherit end
12
+ def self.spot_meth_names(inherit = true) ; get_attr_set '@spot_meth_names', inherit end
13
13
  def self.name_spot(*names) ; name_attr_set '@spot_names', *names end
14
14
 
15
- def self.meth_spot(name, opts = {})
15
+ def self.spot_meth(name, opts = {})
16
16
  name_spot name
17
- name_attr_set '@meth_spot_names', name
17
+ name_attr_set '@spot_meth_names', name
18
18
  define_method :"#{name}" do ||
19
19
  mk_spot name, opts = {}
20
20
  end
21
21
  end
22
22
 
23
- def self.attr_spot(*names)
23
+ def self.spot_attr(*names)
24
24
  name_spot *names
25
- name_attr_set '@attr_spot_names', *names
25
+ name_attr_set '@spot_attr_names', *names
26
26
  attr_writer *names
27
27
  names.each do |name|
28
28
  define_method :"#{name}" do ||
@@ -46,7 +46,7 @@ module Andromeda
46
46
  @id = Id.new
47
47
  set_from_config init_from_config, config
48
48
  @tags ||= {}
49
- @guide ||= init_guide
49
+ self.guide=(init_guide) unless @guide
50
50
  end
51
51
 
52
52
  def initialize_copy(other)
@@ -54,36 +54,41 @@ module Andromeda
54
54
  @tags ||= {}
55
55
  end
56
56
 
57
- def init_guide ; Guides::DefaultGuide.instance end
57
+ def init_guide ; Guides.default end
58
58
 
59
59
  def tags ; @tags end
60
60
  def to_short_s ; " id=#{id.to_short_s}t" end
61
61
  alias_method :inspect, :to_s
62
62
 
63
63
  def guide=(new_guide)
64
- new_guide = new_guide.instance if new_guide.is_a?(Class) && new_guide.include?(Singleton)
65
- @guide = new_guide
64
+ @guide = if new_guide.is_a?(Class)
65
+ if new_guide.include?(Singleton)
66
+ then new_guide.instance
67
+ else new_guide.new end
68
+ else
69
+ new_guide
70
+ end
66
71
  end
67
72
 
68
- # Overload to map all incoming data, default to data
69
- def data_map(name, data) ; data end
73
+ # Override to map all incoming data, default to data
74
+ def map_data(name, data) ; data end
70
75
 
71
- # Overload to extract the data key from mapped, incoming data, defaults to name
76
+ # Override to extract the data key from mapped, incoming data, defaults to name
72
77
  def data_key(name, data) ; name end
73
78
 
74
- # Overload to determine the target spot name from the key, defaults to name
79
+ # Override to determine the target spot name from the key, defaults to name
75
80
  def key_spot(name, key) ; name end
76
81
 
77
- # Overload to determine the target track label from the key, defaults to ket
82
+ # Override to determine the target track label from the key, defaults to key
78
83
  def key_label(name, key) ; key end
79
84
 
80
- # Overload to extract the data value from mapped, incoming data, defaults to data
85
+ # Override to extract the data value from mapped, incoming data, defaults to data
81
86
  def data_val(name, data) ; data end
82
87
 
83
- # Overload to compute additional tags
88
+ # Override to compute additional tags
84
89
  def data_tag(name, key, val, tags_in) ; { name: name } end
85
90
 
86
- # Overload to filter the data events that should be processed, defaults to true
91
+ # Override to filter the data events that should be processed, defaults to true
87
92
  def selects?(name, key, val, tags_in) ; true end
88
93
 
89
94
  def post_data(spot_, track_in, data, tags_in = {})
@@ -93,7 +98,7 @@ module Andromeda
93
98
  name = spot_.name
94
99
  details = { name: name, data: data, tags_in: tags_in, spot: spot_ }
95
100
  begin
96
- data = data_map name, data
101
+ data = map_data name, data
97
102
  key = data_key name, data
98
103
  name = key_spot name, key
99
104
 
@@ -133,19 +138,23 @@ module Andromeda
133
138
  end
134
139
 
135
140
  def spot_name?(name) ; spot_names.include? name end
136
- def attr_spot_name?(name) ; attr_spot_names.include? name end
137
- def meth_spot_name?(name) ; meth_spot_names.include? name end
141
+ def spot_attr_name?(name) ; spot_attr_names.include? name end
142
+ def spot_meth_name?(name) ; spot_meth_names.include? name end
138
143
  def signal_name?(name) ; signal_names.include? name end
139
144
 
140
145
  def spot_names ; self.class.spot_names end
141
- def attr_spot_names ; self.class.attr_spot_names end
142
- def meth_spot_names ; self.class.meth_spot_names end
146
+ def spot_attr_names ; self.class.spot_attr_names end
147
+ def spot_meth_names ; self.class.spot_meth_names end
143
148
  def signal_names ; self.class.signal_names end
144
149
 
145
150
  def current_scope ; tags[:scope] end
146
151
  def current_name ; tags[:name] end
147
152
 
148
- def >>(spot) ; @emit = spot.entry ; spot.dest end
153
+ def >>(spot)
154
+ @emit = spot.entry
155
+ d = spot.dest
156
+ if d then d else spot end
157
+ end
149
158
 
150
159
  def entry ; enter end
151
160
  def dest ; emit end
@@ -156,7 +165,7 @@ module Andromeda
156
165
 
157
166
  protected
158
167
 
159
- attr_spot :emit
168
+ spot_attr :emit
160
169
 
161
170
  def exit ; emit end
162
171
 
@@ -0,0 +1,48 @@
1
+ module Andromeda
2
+
3
+ module Impl
4
+
5
+ module To_S
6
+
7
+ def to_s(short = false)
8
+ if short
9
+ to_short_s
10
+ else
11
+ super_str = super()
12
+ class_name = self.class.name.split('::')[-1]
13
+ obj_id = object_id.to_s(16)
14
+ "\#<#{class_name}:0x#{obj_id}#{to_s(true)}>"
15
+ end
16
+ end
17
+
18
+ def to_short_s ; '' end
19
+
20
+ def self.short_s(v = value)
21
+ return ":#{v}" if v.is_a?(Symbol)
22
+ return "'#{v}'" if v.is_a?(String)
23
+ return 'nil' unless v
24
+ "#{v}"
25
+ end
26
+
27
+ end
28
+
29
+ # Shared base class of Spot and Impl::PrePlan
30
+ class ConnectorBase
31
+ # @return [Spot] entry.intern nil
32
+ def start ; entry.intern(nil) end
33
+
34
+ # post_to nil, data, tags_in
35
+ #
36
+ # @return [self]
37
+ def post(data, tags_in = {}) ; post_to nil, data, tags_in end
38
+
39
+ alias_method :<<, :post
40
+
41
+ # post_to LocalTrack.instance, data, tags_in
42
+ #
43
+ # @return [self]
44
+ def post_local(data, tags_in = {}) ; post_to Guides::LocalTrack.instance, data, tags_in end
45
+ end
46
+
47
+ end
48
+ end
@@ -1,172 +1,172 @@
1
1
  module Andromeda
2
2
 
3
- module Kit
4
-
5
- module Transf
6
- attr_accessor :filter
7
- attr_accessor :mapper
8
-
9
- def deliver_data(name, meth, key, val, tags_in)
10
- if signal_name?(name)
11
- super name, meth, key, val, tags_in
12
- else
13
- filter_ = filter
14
- mapper_ = mapper
15
- if !(filter_ && filter_.call(val))
16
- super name, meth, key, (if mapper_ then mapper_.call(val) else val end), tags_in
17
- end
18
- end
19
- end
20
- end
21
-
22
- class Tee < Plan
23
- attr_accessor :level
24
- attr_accessor :other
25
- attr_accessor :delay
26
-
27
- def initialize(config = {})
28
- config = { nick: config } unless config.is_a? Hash || config.is_a?(Spot)
29
- config = { other: config } unless config.is_a? Hash
30
- super config
31
-
32
- @level ||= :info
33
- end
34
-
35
- def initialize_copy(other)
36
- @level = other.level.identical_copy
37
- @delay = other.delay.identical_copy
38
- end
39
-
40
- def on_enter(key, val)
41
- log_ = log
42
- level_ = level
43
- sleep delay.to_i if delay
44
- if log_ && level_
45
- cur_name = current_name
46
- key_str = Andromeda::Impl::To_S.short_s key
47
- val_str = Andromeda::Impl::To_S.short_s val
48
- log_str = "#{to_s}.#{cur_name}(#{key_str}, #{val_str})"
49
- tags.each_pair { |k, v| log_str << " #{k}=#{Andromeda::Impl::To_S.short_s(v)}" }
50
- log_str << " tid=0x#{Thread.current.object_id.to_s(16)}"
51
- log_.send level, log_str
52
- end
53
- other_ = other
54
- other_ << val if other_
55
- super key, val
56
- end
57
- end
58
-
59
- class Targeting < Plan
60
- attr_accessor :targets
61
-
62
- def initialize(config = {})
63
- super config
64
- @targets ||= {}
65
- end
66
-
67
- def target_values ; t = targets ; t.values rescue t end
68
- end
69
-
70
- class Broadc < Targeting
71
- def on_enter(key, val)
72
- target_values { |t| intern(t) << val rescue nil }
73
- end
74
- end
75
-
76
- class Switch < Targeting
77
- def on_enter(key, val)
78
- (intern(key) rescue exit) << val rescue nil
79
- end
80
- end
81
-
82
- class SinglePlan < Plan
83
- def init_guide ; Guides::SinglePoolGuide.new end
84
- end
85
-
86
- class InlineKeyRouter < SinglePlan
87
- def key_spot(name, key) ; key end
88
- end
89
-
90
- class Gatherer < SinglePlan
91
- include Transf
92
- end
93
-
94
- class Reducer < Gatherer
95
- attr_accessor :state
96
- attr_accessor :reducer
97
-
98
- attr_spot :new_state
99
-
100
- def on_enter(key, val)
101
- reducer_ = reducer
102
-
103
- state_ = state
104
- new_ = reducer_.call state_, key, val
105
- unless new_ == state_
106
- state = new_
107
- new_state << state if new_state
108
- end
109
- end
110
- end
111
-
112
- class FileReader < Plan
113
- attr_reader :path
114
- attr_reader :mode
115
-
116
- def initialize(config = {})
117
- super config
118
- @mode ||= init_mode
119
- end
120
-
121
- def data_tag(name, key, val, tags_in)
122
- tags_out = super
123
- tags_out[:first] = val.first rescue 0
124
- tags_out[:last] = val.last rescue -1
125
- tags_out
126
- end
127
-
128
- def init_mode ; 'r' end
129
-
130
- protected
131
-
132
- def on_enter(key, val)
133
- file = File.open path, mode
134
- begin
135
- file.seek tags[:first]
136
- tags[:last] = file.size - 1 if tags[:last] < 0
137
- tags[:num] = tags[:last] - tags[:first]
138
- if block_given? then yield file else super key, val end
139
- ensure
140
- file.close
141
- end
142
- end
143
-
144
- end
145
-
146
- class FileChunker < FileReader
147
- attr_reader :num_chunks
148
-
149
- def initialize(config = {})
150
- super config
151
- @num_chunks ||= Guides::PoolGuide.num_procs
152
- end
153
-
154
- def on_enter(key, val)
155
- num_c = num_chunks
156
- super key, val do |f|
157
- fst = tags[:first]
158
- lst = tags[:last]
159
- sz = tags[:num] / num_c rescue 1
160
- sz = 1 if sz < 0
161
- while fst <= lst
162
- nxt = fst + sz
163
- nxt = lst if nxt > lst
164
- exit << Range.new(fst, nxt)
165
- fst = nxt + 1
166
- end
167
- end
168
- end
169
- end
170
-
171
- end
3
+ module Kit
4
+
5
+ module Transf
6
+ attr_accessor :filter
7
+ attr_accessor :mapper
8
+
9
+ def deliver_data(name, meth, key, val, tags_in)
10
+ if signal_name?(name)
11
+ super name, meth, key, val, tags_in
12
+ else
13
+ filter_ = filter
14
+ mapper_ = mapper
15
+ if !(filter_ && filter_.call(val))
16
+ super name, meth, key, (if mapper_ then mapper_.call(val) else val end), tags_in
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class Tee < Plan
23
+ attr_accessor :level
24
+ spot_attr :other
25
+ attr_accessor :delay
26
+
27
+ def initialize(config = {})
28
+ config = { nick: config } unless config.is_a? Hash || config.is_a?(Spot)
29
+ config = { other: config } unless config.is_a? Hash
30
+ super config
31
+
32
+ @level ||= :info
33
+ end
34
+
35
+ def initialize_copy(other)
36
+ @level = other.level.identical_copy
37
+ @delay = other.delay.identical_copy
38
+ end
39
+
40
+ def on_enter(key, val)
41
+ log_ = log
42
+ level_ = level
43
+ sleep delay.to_i if delay
44
+ if log_ && level_
45
+ cur_name = current_name
46
+ key_str = Andromeda::Impl::To_S.short_s key
47
+ val_str = Andromeda::Impl::To_S.short_s val
48
+ log_str = "#{to_s}.#{cur_name}(#{key_str}, #{val_str})"
49
+ tags.each_pair { |k, v| log_str << " #{k}=#{Andromeda::Impl::To_S.short_s(v)}" }
50
+ log_str << " tid=0x#{Thread.current.object_id.to_s(16)}"
51
+ log_.send level, log_str
52
+ end
53
+ other_ = other
54
+ other_ << val if other_
55
+ super key, val
56
+ end
57
+ end
58
+
59
+ class Targeting < Plan
60
+ attr_accessor :targets
61
+
62
+ def initialize(config = {})
63
+ super config
64
+ @targets ||= {}
65
+ end
66
+
67
+ def target_values ; t = targets ; t.values rescue t end
68
+ end
69
+
70
+ class Broadc < Targeting
71
+ def on_enter(key, val)
72
+ target_values { |t| intern(t) << val rescue nil }
73
+ end
74
+ end
75
+
76
+ class Switch < Targeting
77
+ def on_enter(key, val)
78
+ (intern(key) rescue exit) << val rescue nil
79
+ end
80
+ end
81
+
82
+ class SinglePlan < Plan
83
+ def init_guide ; Guides::SinglePoolGuide.new end
84
+ end
85
+
86
+ class InlineKeyRouter < SinglePlan
87
+ def key_spot(name, key) ; key end
88
+ end
89
+
90
+ class Gatherer < SinglePlan
91
+ include Transf
92
+ end
93
+
94
+ class Reducer < Gatherer
95
+ attr_accessor :state
96
+ attr_accessor :reducer
97
+
98
+ spot_attr :new_state
99
+
100
+ def on_enter(key, val)
101
+ reducer_ = reducer
102
+
103
+ state_ = state
104
+ new_ = reducer_.call state_, key, val
105
+ unless new_ == state_
106
+ state = new_
107
+ new_state << state if new_state
108
+ end
109
+ end
110
+ end
111
+
112
+ class FileReader < Plan
113
+ attr_reader :path
114
+ attr_reader :mode
115
+
116
+ def initialize(config = {})
117
+ super config
118
+ @mode ||= init_mode
119
+ end
120
+
121
+ def data_tag(name, key, val, tags_in)
122
+ tags_out = super
123
+ tags_out[:first] = val.first rescue 0
124
+ tags_out[:last] = val.last rescue -1
125
+ tags_out
126
+ end
127
+
128
+ def init_mode ; 'r' end
129
+
130
+ protected
131
+
132
+ def on_enter(key, val)
133
+ file = File.open path, mode
134
+ begin
135
+ file.seek tags[:first]
136
+ tags[:last] = file.size - 1 if tags[:last] < 0
137
+ tags[:num] = tags[:last] - tags[:first]
138
+ if block_given? then yield file else super key, val end
139
+ ensure
140
+ file.close
141
+ end
142
+ end
143
+
144
+ end
145
+
146
+ class FileChunker < FileReader
147
+ attr_reader :num_chunks
148
+
149
+ def initialize(config = {})
150
+ super config
151
+ @num_chunks ||= Guides::PoolGuide.num_procs
152
+ end
153
+
154
+ def on_enter(key, val)
155
+ num_c = num_chunks
156
+ super key, val do |f|
157
+ fst = tags[:first]
158
+ lst = tags[:last]
159
+ sz = tags[:num] / num_c rescue 1
160
+ sz = 1 if sz < 0
161
+ while fst <= lst
162
+ nxt = fst + sz
163
+ nxt = lst if nxt > lst
164
+ exit << Range.new(fst, nxt)
165
+ fst = nxt + 1
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ end
172
172
  end