omf_oml 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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