Class: Higgs::TransactionContext

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/higgs/tman.rb

Constant Summary collapse

CVS_ID =

for ident(1)

'$Id: tman.rb 841 2008-12-24 09:23:20Z toki $'

Instance Method Summary collapse

Constructor Details

#initialize(lock_handler, storage, snapshot, master_cache, secondary_cache, decode, encode) ⇒ TransactionContext

Returns a new instance of TransactionContext.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/higgs/tman.rb', line 171

def initialize(lock_handler, storage, snapshot, master_cache, secondary_cache, decode, encode)
  @lock_handler = lock_handler
  @storage = storage
  @snapshot = snapshot
  @master_cache = master_cache
  @secondary_cache = secondary_cache
  @decode = decode
  @encode = encode

  @local_data_cache = Hash.new{|hash, key|
    if (@snapshot.key? @storage, key) then
      if (string_only(key)) then
        hash[key] = @snapshot.fetch(key, :data) { @master_cache[key] }
      else
        hash[key] = @decode.call(@snapshot.fetch(key, :data) { @master_cache[key] })
      end
    end
  }

  @local_properties_cache = Hash.new{|hash, key|
    hash[key] = @snapshot.fetch(key, :properties) {
      deep_copy(@storage.fetch_properties(key))
    } || { 'system_properties' => {}, 'custom_properties' => {} }
  }

  @locked_map = {}
  @locked_map.default = false
  @update_system_properties = {}
  @update_custom_properties = {}
  @ope_map = {}
end

Instance Method Details

#[](key) ⇒ Object



229
230
231
232
# File 'lib/higgs/tman.rb', line 229

def [](key)
  lock(key)
  (@ope_map[key] != :delete) ? @local_data_cache[key] : nil
end

#[]=(key, value) ⇒ Object



234
235
236
237
238
# File 'lib/higgs/tman.rb', line 234

def []=(key, value)
  lock(key)
  @ope_map[key] = :write
  @local_data_cache[key] = value
end

#change_numberObject



203
204
205
# File 'lib/higgs/tman.rb', line 203

def change_number
  @snapshot.change_number
end

#clearObject



481
482
483
484
485
486
# File 'lib/higgs/tman.rb', line 481

def clear
  for key in keys
    delete(key)
  end
  nil
end

#commit(continue = true) ⇒ Object



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
# File 'lib/higgs/tman.rb', line 509

def commit(continue=true)
  write_list = write_list()
  if (write_list.empty?) then
    return
  end

  @lock_handler.critical{
    @lock_handler.check_collision{|key, type|
      case (type)
      when :data
        @storage.data_change_number(key)
      when :properties
        @storage.properties_change_number(key)
      else
        raise "unknown type: #{type}"
      end
    }

    old_write_list = []
    for ope, key, value in write_list
      case (ope)
      when :write
        if (@storage.key? key) then
          properties = deep_copy(@storage.fetch_properties(key))
          old_write_list << [ :value, key, :data, @master_cache[key] ]
          old_write_list << [ :value, key, :properties, properties ]
          old_write_list << [ :value, key, :identity, @storage.identity(key) ]
          old_write_list << [ :value, key, :string_only, properties['system_properties']['string_only'] ]
          old_write_list << [ :value, key, :data_change_number, @storage.data_change_number(key) ]
          old_write_list << [ :value, key, :properties_change_number, @storage.properties_change_number(key) ]
        else
          old_write_list << [ :none, key ]
        end
      when :system_properties, :custom_properties
        if (@storage.key? key) then
          properties = deep_copy(@storage.fetch_properties(key))
          old_write_list << [ :value, key, :properties, properties ]
          old_write_list << [ :value, key, :properties_change_number, @storage.properties_change_number(key) ]
        else
          old_write_list << [ :none, key ]
        end
      when :delete
        if (@storage.key? key) then
          properties = deep_copy(@storage.fetch_properties(key))
          old_write_list << [ :value, key, :data, @master_cache[key] ]
          old_write_list << [ :value, key, :properties, properties ]
          old_write_list << [ :value, key, :identity, @storage.identity(key) ]
          old_write_list << [ :value, key, :string_only, properties['system_properties']['string_only'] ]
          old_write_list << [ :value, key, :data_change_number, @storage.data_change_number(key) ]
          old_write_list << [ :value, key, :properties_change_number, @storage.properties_change_number(key) ]
        end
      else
        raise "unknown operation: #{ope}"
      end
    end
    @snapshot.write_old_values(old_write_list)

    for ope, key, value in write_list
      case (ope)
      when :write, :delete
        @master_cache.delete(key)
      end
      @local_properties_cache.delete(key)
    end
    @update_system_properties.clear
    @update_custom_properties.clear
    @ope_map.clear

    @storage.write_and_commit(write_list)
    if (continue) then
      @snapshot.ref_count_down
      @snapshot.ref_count_up(@storage.method(:change_number))
    end
  }

  nil
end

#delete(key) ⇒ Object



254
255
256
257
258
259
260
261
262
263
264
# File 'lib/higgs/tman.rb', line 254

def delete(key)
  lock(key)
  if (@ope_map[key] != :delete) then
    @ope_map[key] = :delete
    @update_system_properties.delete(key)
    @update_custom_properties.delete(key)
    @local_properties_cache.delete(key)
    @local_data_cache[key]  # data load from storage
    @local_data_cache.delete(key)
  end
end

#delete_if(*keys) ⇒ Object

:yields: key, value



458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
# File 'lib/higgs/tman.rb', line 458

def delete_if(*keys)        # :yields: key, value
  del_list = []
  if (keys.empty?) then
    each_key do |key|
      if (yield(key, self[key])) then
        del_list << key
      end
    end
  else
    for key in keys
      if (self.key? key) then
        if (yield(key, self[key])) then
          del_list << key
        end
      end
    end
  end
  for key in del_list
    delete(key)
  end
  nil
end

#delete_property(key, name) ⇒ Object



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/higgs/tman.rb', line 393

def delete_property(key, name)
  unless (self.key? key) then # lock
    raise IndexError, "not exist properties at key: #{key}"
  end
  unless (name.kind_of? String) then
    raise TypeError, "can't convert #{name.class} (name) to String"
  end
  properties = @local_properties_cache[key]['custom_properties']
  if (properties.key? name) then
    value = properties.delete(name)
    @update_custom_properties[key] = properties
    return value
  end
  nil
end

#each_keyObject



283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/higgs/tman.rb', line 283

def each_key
  @local_data_cache.each_key do |key|
    lock(key)
    if (@ope_map[key] != :delete) then
      yield(key)
    end
  end
  @snapshot.each_key(@storage) do |key|
    lock(key)
    if (@ope_map[key] != :delete) then
      unless (@local_data_cache.key? key) then
        yield(key)
      end
    end
  end
  self
end

#each_pairObject Also known as: each

:yields: key, value



307
308
309
310
311
# File 'lib/higgs/tman.rb', line 307

def each_pair               # :yields: key, value
  each_key do |key|
    yield(key, self[key])
  end
end

#each_property(key) ⇒ Object

:yields: name, value



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/higgs/tman.rb', line 436

def each_property(key)      # :yields: name, value
  unless (self.key? key) then # lock
    raise IndexError, "not exist properties at key: #{key}"
  end
  if (value = @snapshot.fetch(key, :identity) { @storage.identity(key) }) then
    yield(:identity, value)
  end
  if (value = @snapshot.fetch(key, :data_change_number) { @storage.data_change_number(key) }) then
    yield(:data_change_number, value)
  end
  if (value = @snapshot.fetch(key, :properties_change_number) { @storage.properties_change_number(key) }) then
    yield(:properties_change_number, value)
  end
  @local_properties_cache[key]['system_properties'].each_pair do |name, value|
    yield(name.to_sym, value)
  end
  @local_properties_cache[key]['custom_properties'].each_pair do |name, value|
    yield(name, value)
  end
  self
end

#each_valueObject

:yields: value



301
302
303
304
305
# File 'lib/higgs/tman.rb', line 301

def each_value              # :yields: value
  each_key do |key|
    yield(self[key])
  end
end

#empty?Boolean

Returns:

  • (Boolean)


343
344
345
# File 'lib/higgs/tman.rb', line 343

def empty?
  length == 0
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?, root?

Returns:

  • (Boolean)


266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/higgs/tman.rb', line 266

def key?(key)
  lock(key)
  if (@ope_map[key] != :delete) then
    if (@local_data_cache.key? key) then
      return true
    end
    if (@snapshot.key? @storage, key) then
      return true
    end
  end
  false
end

#keysObject Also known as: roots



315
316
317
318
319
320
321
# File 'lib/higgs/tman.rb', line 315

def keys
  key_list = []
  each_key do |key|
    key_list << key
  end
  key_list
end

#lengthObject Also known as: size



333
334
335
336
337
338
339
# File 'lib/higgs/tman.rb', line 333

def length
  len = 0
  each_key do |key|
    len += 1
  end
  len
end

#lock(key) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/higgs/tman.rb', line 211

def lock(key)
  unless (@locked_map[key]) then
    cnum =  @snapshot.fetch(key, :data_change_number) {
      @storage.data_change_number(key)
    }
    @lock_handler.lock(key, :data, cnum)

    cnum = @snapshot.fetch(key, :properties_change_number) {
      @storage.properties_change_number(key)
    }
    @lock_handler.lock(key, :properties, cnum)

    @locked_map[key] = true
  end

  nil
end

#locked?(key) ⇒ Boolean

Returns:

  • (Boolean)


207
208
209
# File 'lib/higgs/tman.rb', line 207

def locked?(key)
  @locked_map[key]
end

#property(key, name) ⇒ Object



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/higgs/tman.rb', line 347

def property(key, name)
  case (name)
  when Symbol, String
    # good
  else
    raise TypeError, "can't convert #{name.class} (name) to Symbol or String"
  end

  lock(key)
  if (@ope_map[key] != :delete) then
    if (properties = @local_properties_cache[key]) then
      case (name)
      when :identity
        @snapshot.fetch(key, :identity) { @storage.identity(key) }
      when :data_change_number
        @snapshot.fetch(key, :data_change_number) { @storage.data_change_number(key) }
      when :properties_change_number
        @snapshot.fetch(key, :properties_change_number) { @storage.properties_change_number(key) }
      when Symbol
        properties['system_properties'][name.to_s]
      when String
        properties['custom_properties'][name]
      end
    end
  end
end

#property?(key, name) ⇒ Boolean

Returns:

  • (Boolean)


409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/higgs/tman.rb', line 409

def property?(key, name)
  case (name)
  when Symbol, String
    # good
  else
    raise TypeError, "can't convert #{name.class} (name) to Symbol or String"
  end

  if (self.key? key) then   # lock
    case (name)
    when :identity
      return @snapshot.fetch(key, :identity) { @storage.identity(key) } != nil
    when :data_change_number
      return @snapshot.fetch(key, :data_change_number) { @storage.data_change_number(key) } != nil
    when :properties_change_number
      return @snapshot.fetch(key, :properties_change_number) { @storage.properties_change_number(key) } != nil
    when Symbol
      return (@local_properties_cache[key]['system_properties'].key? name.to_s)
    when String
      return (@local_properties_cache[key]['custom_properties'].key? name)
    else
      raise 'Bug: not to reach'
    end
  end
  false
end

#rollbackObject



587
588
589
590
591
592
593
594
# File 'lib/higgs/tman.rb', line 587

def rollback
  @local_data_cache.clear
  @local_properties_cache.clear
  @update_system_properties.clear
  @update_custom_properties.clear
  @ope_map.clear
  nil
end

#set_property(key, name, value) ⇒ Object



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/higgs/tman.rb', line 374

def set_property(key, name, value)
  unless (self.key? key) then # lock
    raise IndexError, "not exist properties at key: #{key}"
  end
  case (name)
  when String
    properties = @local_properties_cache[key]['custom_properties']
    properties[name] = value
    @update_custom_properties[key] = properties
  when :string_only
    properties = @local_properties_cache[key]['system_properties']
    properties['string_only'] = value
    @update_system_properties[key] = properties
  else
    raise TypeError, "can't convert #{name.class} (name) to String"
  end
  nil
end

#update(key, default_value = nil) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/higgs/tman.rb', line 240

def update(key, default_value=nil)
  if (self.key? key) then   # lock
    value = self[key]
  else
    unless (default_value) then
      raise IndexError, "not exist properties at key: #{key}"
    end
    value = default_value
  end
  r = yield(value)
  self[key] = value
  r
end

#valuesObject



325
326
327
328
329
330
331
# File 'lib/higgs/tman.rb', line 325

def values
  value_list = []
  each_value do |value|
    value_list << value
  end
  value_list
end