omf_oml 0.9.6 → 0.9.7

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.
@@ -6,12 +6,12 @@ require 'omf_oml/schema'
6
6
 
7
7
 
8
8
  module OMF::OML
9
-
9
+
10
10
  # This table maintains the most recently added
11
- # row with a unique entry in the +index+ column.
11
+ # row with a unique entry in the +index+ column.
12
12
  #
13
13
  class OmlIndexedTable < OmlTable
14
-
14
+
15
15
  # Shadow an existing table and maintain an index on 'index_col'.
16
16
  #
17
17
  # source_table - Table to shadow
@@ -25,10 +25,10 @@ module OMF::OML
25
25
  end
26
26
  ix_table
27
27
  end
28
-
28
+
29
29
  attr_reader :index_col
30
-
31
- #
30
+
31
+ #
32
32
  # index_col - Name of column to index
33
33
  # schema - Table schema
34
34
  #
@@ -36,9 +36,9 @@ module OMF::OML
36
36
  super name, schema, {}, &on_before_row_added
37
37
  @index_col = index_col
38
38
  @index2row = {} # each row is associated with an instance of the index
39
- @index = schema.index_for_col(index_col)
40
- end
41
-
39
+ @index = @schema.index_for_col(index_col)
40
+ end
41
+
42
42
  def _add_row_finally(row)
43
43
  key = row[@index]
44
44
  row_id = @index2row[key]
@@ -48,13 +48,13 @@ module OMF::OML
48
48
  end
49
49
  current_row = @rows[row_id]
50
50
  return nil if current_row == row
51
-
52
- if current_row
51
+
52
+ if current_row
53
53
  _notify_content_changed(:removed, [current_row])
54
54
  end
55
55
  @rows[row_id] = row
56
56
  return row
57
- end
57
+ end
58
58
 
59
59
  end # class
60
60
 
@@ -7,32 +7,32 @@ require 'omf_oml'
7
7
 
8
8
 
9
9
  module OMF::OML
10
-
11
- class OmlNetworkAlreadyExistException < Exception; end
10
+
11
+ class OmlNetworkAlreadyExistException < Exception; end
12
12
  class OmlNodeAlreadyExistException < Exception; end
13
- class OmlLinkAlreadyExistException < Exception; end
13
+ class OmlLinkAlreadyExistException < Exception; end
14
14
 
15
15
  class UnknownOmlNodeException < Exception; end
16
-
17
- class SameNameOnUpdateException < Exception; end
18
-
16
+
17
+ class SameNameOnUpdateException < Exception; end
18
+
19
19
  # This class represents a network consisting of nodes and links with their respective
20
20
  # attributes.
21
21
  #
22
22
  class OmlNetwork < OMF::Common::LObject
23
23
  include MonitorMixin
24
-
24
+
25
25
  @@name2network = {}
26
-
26
+
27
27
  # Return a named network
28
28
  #
29
29
  def self.[](name)
30
30
  @@name2network[name]
31
31
  end
32
-
32
+
33
33
  attr_reader :name
34
34
 
35
- #
35
+ #
36
36
  # name - Name of table
37
37
  # opts -
38
38
  #
@@ -42,7 +42,7 @@ module OMF::OML
42
42
  @attributes = attributes
43
43
  @nodes = {}
44
44
  @name2node = {}
45
- @links = {}
45
+ @links = {}
46
46
  @name2link = {}
47
47
  @epoch = 0 # increment whenever an element is being updated
48
48
  @updateListeners = {}
@@ -53,13 +53,13 @@ module OMF::OML
53
53
  end
54
54
  @@name2network[name] = self
55
55
  end
56
- end
56
+ end
57
57
  end
58
-
58
+
59
59
  def nodes()
60
60
  @nodes.values
61
61
  end
62
-
62
+
63
63
  # Return the node named +name+. If the node doesn't exist and
64
64
  # +new_opts+ is a Hash, create a new one and return that.
65
65
  #
@@ -75,7 +75,7 @@ module OMF::OML
75
75
  def links()
76
76
  @links.values
77
77
  end
78
-
78
+
79
79
  # Return the link named +name+. If the link doesn't exist and
80
80
  # +new_opts+ is a Hash, create a new one and return that.
81
81
  #
@@ -88,7 +88,7 @@ module OMF::OML
88
88
  link
89
89
  end
90
90
 
91
-
91
+
92
92
  # Register a callback to be called every time network elements change
93
93
  # The callback is provided with an arrach of changed elements.
94
94
  #
@@ -102,7 +102,7 @@ module OMF::OML
102
102
  @updateListeners.delete(name)
103
103
  end
104
104
  end
105
-
105
+
106
106
  # NOTE: May need a monitor if used in multi-threaded environments
107
107
  #
108
108
  def create_node(name = nil, attributes = {})
@@ -117,18 +117,18 @@ module OMF::OML
117
117
  node
118
118
  end
119
119
  end
120
-
120
+
121
121
  #
122
122
  # opts
123
123
  # :from - fromNode if +fromNode+ is nil
124
124
  # :to - toNode if +toNode+ is nil
125
125
  # ... - rest of options passed on to +NetworkLink+ constructor
126
- #
126
+ #
127
127
  def create_link(name = nil, fromNode = nil, toNode = nil, attributes = {})
128
128
  name = name.to_sym if name
129
129
  fromNode = attributes.delete(:from) unless fromNode
130
130
  toNode = attributes.delete(:to) unless toNode
131
-
131
+
132
132
  synchronize do
133
133
  if name && @name2link[name]
134
134
  raise OmlLinkAlreadyExistException.new(name)
@@ -145,11 +145,11 @@ module OMF::OML
145
145
  link
146
146
  end
147
147
  end
148
-
148
+
149
149
  # To have the update listeners only called once when multiple elements are changed at once, perform the
150
150
  # changes within a +transaction+ block. The listeners are then called once with an array containing
151
151
  # all updated elements.
152
- #
152
+ #
153
153
  def transaction(&block)
154
154
  updated = UpdateSet.new
155
155
  synchronize do
@@ -157,7 +157,7 @@ module OMF::OML
157
157
 
158
158
  @in_transaction = true
159
159
  block.call
160
- @in_transaction = true
160
+ @in_transaction = true
161
161
  end
162
162
  unless updated.empty?
163
163
  @updateListeners.values.each do |l|
@@ -165,7 +165,7 @@ module OMF::OML
165
165
  end
166
166
  end
167
167
  end
168
-
168
+
169
169
  def node_schema(schema = nil)
170
170
  if schema
171
171
  @node_schema = OmlSchema.create(schema)
@@ -174,7 +174,7 @@ module OMF::OML
174
174
  end
175
175
  @node_schema
176
176
  end
177
-
177
+
178
178
  def link_schema(schema = nil)
179
179
  if schema
180
180
  @link_schema = OmlSchema.create(schema)
@@ -186,15 +186,15 @@ module OMF::OML
186
186
  @link_schema
187
187
  end
188
188
 
189
-
189
+
190
190
  def describe
191
191
  nh = {}
192
192
  @nodes.each do |id, node| nh[id] = node.describe end
193
193
  lh = {}
194
194
  @links.each do |id, link| lh[id] = link.describe end
195
- {:nodes => nh, :links => lh}
195
+ {:nodes => nh, :links => lh}
196
196
  end
197
-
197
+
198
198
  # Creates two tables, one capturing the link state and one for the node state.
199
199
  # Returns the two tables in a hash with keys 'nodes' and 'links'.
200
200
  #
@@ -203,12 +203,12 @@ module OMF::OML
203
203
  # @nodes.each do |id, n|
204
204
  # node_table.add_row @node_schema.hash_to_row(n.attributes)
205
205
  # end
206
- #
206
+ #
207
207
  # link_table = OmlTable.new 'links', @link_schema, table_opts
208
208
  # @links.each do |id, l|
209
209
  # link_table.add_row @link_schema.hash_to_row(l.attributes)
210
210
  # end
211
- #
211
+ #
212
212
  # on_update "__to_tables_#{node_table.object_id}" do |a|
213
213
  # a.each do |e|
214
214
  # if e.kind_of? NetworkNode
@@ -221,16 +221,17 @@ module OMF::OML
221
221
  # {:nodes => node_table, :links => link_table}
222
222
  # #{:nodes => to_table(:nodes, table_opts), :links => to_table(:links, table_opts)}
223
223
  # end
224
-
225
- # Create a table to track an aspect of this network.
224
+
225
+ # Create a table to track an aspect of this network.
226
226
  #
227
- # aspect - Either :nodes or :links
227
+ # aspect - Either :nodes or :links
228
228
  #
229
229
  def to_table(aspect, table_opts = {})
230
230
  aspect = aspect.to_sym
231
231
  case aspect
232
232
  when :nodes
233
233
  table = OmlTable.create @name + '/nodes', @node_schema, table_opts
234
+ #puts "TABLE SCHEME >>>> #{table.schema}"
234
235
  table.add_rows(@nodes.map do |id, n|
235
236
  @node_schema.hash_to_row(n.attributes)
236
237
  end)
@@ -239,27 +240,34 @@ module OMF::OML
239
240
  e.kind_of?(NetworkNode) ? @node_schema.hash_to_row(e.attributes) : nil
240
241
  end.compact
241
242
  table.add_rows(nodes) unless nodes.empty?
242
- end
243
-
243
+ end
244
+
244
245
  when :links
245
246
  table = OmlTable.create @name + '/links', @link_schema, table_opts
246
247
  # @links.each do |id, l|
247
248
  # table.add_row @link_schema.hash_to_row(l.attributes)
248
249
  # end
249
250
  table.add_rows(@links.map do |id, n|
251
+ # puts @link_schema.hash_to_row(n.attributes).inspect
252
+ # puts table.schema
253
+ # table.add_row @link_schema.hash_to_row(n.attributes)
254
+ # puts table.rows.inspect
255
+ # exit
256
+
250
257
  @link_schema.hash_to_row(n.attributes)
251
258
  end)
259
+ #puts table.rows.inspect
252
260
  on_update "__to_tables_links_#{table.object_id}" do |a|
253
261
  links = a.map do |e|
254
262
  e.kind_of?(NetworkLink) ? @link_schema.hash_to_row(e.attributes) : nil
255
263
  end.compact
256
264
  table.add_rows(links) unless links.empty?
257
- end
258
-
265
+ end
266
+
259
267
  else
260
268
  raise "Unknown aspect '#{aspect}'. Should be either 'nodes' or 'links'."
261
269
  end
262
-
270
+
263
271
  # on_update "__to_tables_#{table.object_id}" do |a|
264
272
  # a.each do |e|
265
273
  # if aspect == :nodes && e.kind_of?(NetworkNode)
@@ -270,22 +278,22 @@ module OMF::OML
270
278
  # end
271
279
  # end
272
280
  # end
273
-
281
+
274
282
  table
275
283
  end
276
-
277
-
284
+
285
+
278
286
  def to_json
279
287
  describe.to_json
280
288
  end
281
-
282
-
283
-
289
+
290
+
291
+
284
292
  def updated(element)
285
293
  synchronize do
286
294
  if @in_transaction
287
295
  @updated << element
288
- return
296
+ return
289
297
  end
290
298
  end
291
299
  uset = UpdateSet.new
@@ -296,10 +304,10 @@ module OMF::OML
296
304
  end
297
305
 
298
306
  end # OMLNetwork
299
-
300
- class NetworkElementAttributeException < Exception; end
301
307
 
302
-
308
+ class NetworkElementAttributeException < Exception; end
309
+
310
+
303
311
  # This class represents an abstract network element and shouldn't be used directly.
304
312
  #
305
313
  class NetworkElement < OMF::Common::LObject
@@ -307,7 +315,7 @@ module OMF::OML
307
315
  attr_reader :name
308
316
  attr_reader :el_id
309
317
  attr_reader :attributes
310
-
318
+
311
319
  def initialize(name, attributes, network)
312
320
  super name
313
321
  @attributes = attributes.dup
@@ -322,15 +330,15 @@ module OMF::OML
322
330
 
323
331
  @network = network
324
332
  end
325
-
333
+
326
334
  def [](name)
327
335
  @attributes[name]
328
336
  end
329
-
337
+
330
338
  def []=(name, value)
331
339
  @attributes[name] = _set(value, @attributes[name])
332
340
  end
333
-
341
+
334
342
  # Update the element's attributes. The +attributes+ argument
335
343
  # is expected to be a hash with the key identifying the attribute
336
344
  # name and the value being the new value to set that attribute to.
@@ -340,54 +348,54 @@ module OMF::OML
340
348
  self[name] = value
341
349
  end
342
350
  end
343
-
351
+
344
352
  # Return the current state of the network element as hash
345
353
  #
346
354
  def describe
347
- @attributes
355
+ @attributes
348
356
  end
349
-
357
+
350
358
  def node?
351
359
  false
352
360
  end
353
-
361
+
354
362
  def link?
355
363
  false
356
364
  end
357
-
365
+
358
366
  protected
359
-
367
+
360
368
  def _set(value, old_value)
361
369
  if value != old_value
362
370
  @network.updated(self)
363
371
  end
364
372
  value
365
373
  end
366
-
367
- end # NetworkElement
368
-
374
+
375
+ end # NetworkElement
376
+
369
377
  # This class represents a network node. Should NOT be created directly, but only through
370
378
  # +OmlNetwork#create_node+ method
371
379
  #
372
380
  class NetworkNode < NetworkElement
373
-
381
+
374
382
  def initialize(name, attributes, network)
375
383
  super
376
384
  end
377
-
385
+
378
386
  def node?
379
387
  true
380
388
  end
381
- end # NetworkNode
389
+ end # NetworkNode
382
390
 
383
- # This class represents a network link between two nodes.
391
+ # This class represents a network link between two nodes.
384
392
  # Should NOT be created directly, but only through
385
393
  # +OmlNetwork#create_node+ method
386
394
  #
387
395
  class NetworkLink < NetworkElement
388
396
  attr_reader :from # node
389
397
  attr_reader :to # node
390
-
398
+
391
399
  def initialize(name, fromNode, toNode, attributes, network)
392
400
  super name, attributes, network
393
401
  if fromNode
@@ -395,26 +403,26 @@ module OMF::OML
395
403
  #puts ">>>> NODE: #{fromNode.inspect}"
396
404
  @attributes[:from_id] = fromNode.el_id
397
405
  end
398
- if toNode
406
+ if toNode
399
407
  @toNode = toNode
400
408
  @attributes[:to_id] = toNode.el_id
401
409
  end
402
410
  end
403
-
411
+
404
412
  def from=(node)
405
- @attributes[:from_id] = node.el_id if node
413
+ @attributes[:from_id] = node.el_id if node
406
414
  @fromNode = _set(node, @fromNode)
407
415
  end
408
416
 
409
417
  def to=(node)
410
- @attributes[:to_id] = node.el_id if node
418
+ @attributes[:to_id] = node.el_id if node
411
419
  @toNode = _set(node, @toNode)
412
420
  end
413
-
421
+
414
422
  def link?
415
423
  true
416
424
  end
417
- end # NetworkLink
425
+ end # NetworkLink
418
426
 
419
427
  # This set may hold a set of nodes and links which have been
420
428
  # updated during a transaction. It supports the +describe+
@@ -425,16 +433,16 @@ module OMF::OML
425
433
  def describe()
426
434
  nh = {}
427
435
  lh = {}
428
-
429
- self.each do |el|
436
+
437
+ self.each do |el|
430
438
  d = el.describe
431
439
  if el.kind_of? NetworkNode
432
440
  nh[el.el_id] = d
433
441
  else
434
442
  lh[el.el_id] = d
435
- end
443
+ end
436
444
  end
437
- {:nodes => nh, :links => lh}
445
+ {:nodes => nh, :links => lh}
438
446
  end
439
447
  end
440
448
  end
@@ -442,26 +450,26 @@ end
442
450
  if $0 == __FILE__
443
451
  require 'json'
444
452
  include OMF::Common::OML
445
-
453
+
446
454
  nw = OmlNetwork.new
447
-
455
+
448
456
  cnt = 3
449
- cnt.times do |i|
457
+ cnt.times do |i|
450
458
  nw.create_node "n#{i}", :x => i
451
459
  end
452
- cnt.times do |i|
460
+ cnt.times do |i|
453
461
  nw.create_link "l#{i}", "n#{i}", "n#{(i + 1) % cnt}", :y => i
454
462
  end
455
-
463
+
456
464
  puts nw.describe.to_json
457
-
465
+
458
466
  nw.on_update do |els|
459
467
  puts "UPDATED: #{els}"
460
468
  end
461
469
  nw.nodes.first[:x] = 20
462
-
463
- nw.transaction do
470
+
471
+ nw.transaction do
464
472
  nw.nodes.first[:x] = 30
465
- nw.links.first[:y] = 20
473
+ nw.links.first[:y] = 20
466
474
  end
467
- end
475
+ end
data/lib/omf_oml/table.rb CHANGED
@@ -8,28 +8,28 @@ require 'omf_oml/schema'
8
8
 
9
9
 
10
10
  module OMF::OML
11
-
11
+
12
12
  # This class represents a database like table holding a sequence of OML measurements (rows) according
13
13
  # a common schema.
14
14
  #
15
15
  class OmlTable < OMF::Common::LObject
16
-
16
+
17
17
  def self.create(tname, schema, opts = {}, &on_before_row_added)
18
18
  if (index = opts.delete(:index))
19
19
  require 'omf_oml/indexed_table'
20
- OmlIndexedTable.new(tname, index, schema, &on_before_row_added)
20
+ OmlIndexedTable.new(tname, index, schema, &on_before_row_added)
21
21
  else
22
22
  OmlTable.new(tname, schema, opts, &on_before_row_added)
23
23
  end
24
24
  end
25
25
  include MonitorMixin
26
-
26
+
27
27
  attr_reader :name
28
28
  attr_accessor :max_size
29
29
  attr_reader :schema
30
30
  attr_reader :offset
31
-
32
- #
31
+
32
+ #
33
33
  # tname - Name of table
34
34
  # schema - OmlSchema or Array containing [name, type*] for every column in table
35
35
  # Table adds a '__id__' column at the beginning which keeps track of the rows unique id
@@ -39,7 +39,6 @@ module OMF::OML
39
39
  #
40
40
  def initialize(tname, schema, opts = {}, &on_before_row_added)
41
41
  super tname
42
-
43
42
  #@endpoint = endpoint
44
43
  @name = tname
45
44
  @schema = OmlSchema.create(schema)
@@ -61,12 +60,12 @@ module OMF::OML
61
60
  @max_size = opts[:max_size]
62
61
  @on_content_changed = {}
63
62
  end
64
-
63
+
65
64
  def rows
66
65
  #@indexed_rows ? @indexed_rows.values : @rows
67
66
  @rows
68
67
  end
69
-
68
+
70
69
  # Register +callback+ to be called to process any newly
71
70
  # offered row before it being added to internal storage.
72
71
  # The callback's argument is the new row (TODO: in what form)
@@ -76,12 +75,12 @@ module OMF::OML
76
75
  def on_before_row_added(&callback)
77
76
  @on_before_row_added = callback
78
77
  end
79
-
78
+
80
79
  # Register callback for when the content of the table is changes. The key
81
80
  # allows for the callback to be removed by calling this method
82
- # without a block. . If the
81
+ # without a block. . If the
83
82
  # optional 'offset' value is set to zero or a positive value,
84
- # then the currently stored values starting at this index are being
83
+ # then the currently stored values starting at this index are being
85
84
  # immediately sent to 'proc'. The 'proc' is expected to receive two
86
85
  # parameters, an 'action' and the content changed. The 'action' is either
87
86
  # ':added', or ':removed' and the content is an array of rows.
@@ -101,7 +100,7 @@ module OMF::OML
101
100
  @on_content_changed.delete key
102
101
  end
103
102
  end
104
-
103
+
105
104
  def on_row_added(key, &block)
106
105
  on_content_changed(key) do |action, rows|
107
106
  if action == :added
@@ -109,8 +108,8 @@ module OMF::OML
109
108
  end
110
109
  end
111
110
  end
112
-
113
- # NOTE: +on_row_added+ callbacks are done within the monitor.
111
+
112
+ # NOTE: +on_row_added+ callbacks are done within the monitor.
114
113
  #
115
114
  def add_row(row, needs_casting = false)
116
115
  synchronize do
@@ -119,13 +118,13 @@ module OMF::OML
119
118
  end
120
119
  end
121
120
  end
122
-
121
+
123
122
  def <<(row)
124
123
  add_row(row)
125
124
  end
126
-
125
+
127
126
  # Return a new table which shadows this table but only contains
128
- # rows with unique values in the column 'col_name' and of these the
127
+ # rows with unique values in the column 'col_name' and of these the
129
128
  # latest added rows to this table.
130
129
  #
131
130
  # col_name - Name of column to use for indexing
@@ -134,7 +133,7 @@ module OMF::OML
134
133
  require 'omf_oml/indexed_table'
135
134
  OmlIndexedTable.shadow(self, col_name)
136
135
  end
137
-
136
+
138
137
  # Add an array of rows to this table
139
138
  #
140
139
  def add_rows(rows, needs_casting = false)
@@ -146,7 +145,7 @@ module OMF::OML
146
145
  end
147
146
  end
148
147
  end
149
-
148
+
150
149
  # Return a new table which only contains the rows of this
151
150
  # table whose value in column 'col_name' is equal to 'col_value'
152
151
  #
@@ -177,23 +176,23 @@ module OMF::OML
177
176
  debug "Created sliced table from '#{@name}' (rows: #{st.rows.length}-#{@rows.length})"
178
177
  st
179
178
  end
180
-
179
+
181
180
  # Return table as an array of rows
182
181
  #
183
182
  def to_a
184
183
  @rows.dup
185
184
  end
186
-
185
+
187
186
  def describe()
188
187
  rows
189
188
  end
190
-
189
+
191
190
  def data_sources
192
191
  self
193
192
  end
194
-
193
+
195
194
  private
196
-
195
+
197
196
  # NOT synchronized
198
197
  #
199
198
  def _add_row(row, needs_casting = false)
@@ -205,12 +204,12 @@ module OMF::OML
205
204
  if @on_before_row_added
206
205
  row = @on_before_row_added.call(row)
207
206
  end
208
- return nil unless row
207
+ return nil unless row
209
208
 
210
209
  row.insert(0, @row_id += 1) if @add_index
211
210
  _add_row_finally(row)
212
211
  end
213
-
212
+
214
213
  # Finally add 'row' to internal storage. This would be the method to
215
214
  # override in sub classes as this is thread safe and all other pre-storage
216
215
  # test have been performed. Should return the row added, or nil if nothing
@@ -221,7 +220,7 @@ module OMF::OML
221
220
  # @indexed_rows[row[@index_col]] = row
222
221
  # return
223
222
  # end
224
-
223
+
225
224
  @rows << row
226
225
  if @max_size && @max_size > 0 && (s = @rows.size) > @max_size
227
226
  if (removed_row = @rows.shift) # not necessarily fool proof, but fast
@@ -231,7 +230,7 @@ module OMF::OML
231
230
  end
232
231
  row
233
232
  end
234
-
233
+
235
234
  def _notify_content_changed(action, rows)
236
235
  @on_content_changed.each_value do |proc|
237
236
  #puts "call: #{proc.inspect}"
@@ -1,6 +1,6 @@
1
1
 
2
2
  module OMF
3
3
  module OML
4
- VERSION = '0.9.6'
4
+ VERSION = '0.9.7'
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omf_oml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-30 00:00:00.000000000 Z
12
+ date: 2013-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel