xamplr 1.9.1 → 1.9.2

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.
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 9
4
- :patch: 1
4
+ :patch: 2
5
5
  :build:
@@ -43,7 +43,9 @@ module Xampl
43
43
  end
44
44
 
45
45
  def FromXML.registered(name)
46
+ #puts "registered by ns tag: #{ @@by_ns_tag.keys.sort.inspect }"
46
47
  klass = @@by_ns_tag[name]
48
+ #puts "registered by tag: #{ @@by_tag.keys.sort.inspect }"
47
49
  klass = @@by_tag[name] unless klass
48
50
  klass = [] unless klass
49
51
  return klass
@@ -137,6 +139,7 @@ module Xampl
137
139
  klasses = FromXML.registered(klass_name)
138
140
  if (0 == klasses.size) then
139
141
  # The class has not been registered (either it was never generated, or it was never loaded)
142
+ puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] Don't know about class name: #{ klass_name }"
140
143
  # puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] @@by_ns_tag: #{ @@by_ns_tag.inspect }"
141
144
  # puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] @@by_tag: #{ @@by_tag.inspect }"
142
145
  xml_text = XMLText.new
@@ -5,13 +5,14 @@ module Xampl
5
5
  class PersistXML < Visitor
6
6
  attr_accessor :ns_to_prefix, :start_body, :body, :out, :mentions
7
7
 
8
- def initialize(out="", mentions=nil)
8
+ def initialize(out="", mentions=nil, substitutions={})
9
9
  super()
10
10
 
11
11
  @out = out
12
12
  @was_attr = false
13
13
 
14
14
  @mentions = mentions
15
+ @pid_substitutions = substitutions
15
16
 
16
17
  @ns_to_prefix = {}
17
18
  @start_body = nil
@@ -103,11 +104,19 @@ module Xampl
103
104
 
104
105
  def attribute(xampl)
105
106
  @attr_list = []
107
+ pattr = xampl.indexed_by.to_s
108
+
106
109
  if (nil != xampl.attributes) then
107
110
  xampl.attributes.each do |attr_spec|
108
111
  prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
109
- value = xampl.instance_variable_get(attr_spec[0])
110
- # @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") unless nil == value
112
+ value = nil
113
+ if pattr == attr_spec[1] then
114
+ value = @pid_substitutions[xampl]
115
+ # puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] xampl: #{ xampl }, substitute: #{ value }" if value
116
+ value = xampl.instance_variable_get(attr_spec[0]) unless value
117
+ else
118
+ value = xampl.instance_variable_get(attr_spec[0])
119
+ end
111
120
  @attr_list << (" " << prefix << attr_spec[1] << '="' << attr_esc(value) << '"') unless nil == value
112
121
  end
113
122
  end
@@ -120,8 +129,9 @@ module Xampl
120
129
  xampl.attributes.each do |attr_spec|
121
130
  if pattr == attr_spec[1] then
122
131
  prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
123
- value = xampl.instance_variable_get(attr_spec[0])
124
- # @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") unless nil == value
132
+ value = @pid_substitutions[xampl]
133
+ # puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] xampl: #{ xampl }, substitute: #{ value }" if value
134
+ value = xampl.instance_variable_get(attr_spec[0]) unless value
125
135
  @attr_list << (" " << prefix << attr_spec[1] << '="' << attr_esc(value) << '"') unless nil == value
126
136
  break
127
137
  end
@@ -242,6 +252,11 @@ module Xampl
242
252
  def to_xml(out="", skip=[])
243
253
  PersistXML.new(out).start(self).done
244
254
  end
255
+
256
+ def substituting_to_xml(opts={})
257
+ substitutions = opts[:substitutions] || {}
258
+ PersistXML.new("", [], substitutions).start(self).done
259
+ end
245
260
  end
246
261
 
247
262
  end
@@ -1,5 +1,7 @@
1
1
  require "xamplr/persistence"
2
2
 
3
+ require 'set'
4
+
3
5
  module Xampl
4
6
  class Persister
5
7
  attr_accessor :name,
@@ -10,7 +12,8 @@ module Xampl
10
12
  :total_sync_count, :total_rollback_count,
11
13
  :cache_hits, :total_cache_hits,
12
14
  :last_write_count,
13
- :rolled_back
15
+ :rolled_back,
16
+ :expunged
14
17
  attr_reader :syncing, :format
15
18
 
16
19
  def initialize(name=nil, format=nil)
@@ -18,6 +21,7 @@ module Xampl
18
21
  @format = format
19
22
  @automatic = false
20
23
  @changed = {}
24
+ @expunged = Set.new
21
25
  @cache_hits = 0
22
26
  @total_cache_hits = 0
23
27
  @read_count = 0
@@ -167,6 +171,10 @@ module Xampl
167
171
  end
168
172
  end
169
173
 
174
+ def expunge(xampl)
175
+ false
176
+ end
177
+
170
178
  def lookup(klass, pid)
171
179
  #raise XamplException.new(:live_across_rollback) if @rolled_back
172
180
  #puts "#{File.basename(__FILE__)} #{__LINE__} LOOKUP:: klass: #{klass} pid: #{pid}"
@@ -264,6 +272,9 @@ module Xampl
264
272
 
265
273
  @changed = {}
266
274
 
275
+ puts "SOME NOT EXPUNGED: #{ @expunged.inspect }" unless 0 == @expunged.size
276
+ @expunged = Set.new
277
+
267
278
  @total_read_count = @total_read_count + @read_count
268
279
  @total_write_count = @total_write_count + @write_count
269
280
  @total_cache_hits = @total_cache_hits + @cache_hits
@@ -134,7 +134,7 @@ module Xampl
134
134
  end
135
135
 
136
136
  def read(klass, pid, target=nil)
137
- # puts "#{File.basename(__FILE__)} #{__LINE__} READ:: klass: #{klass} pid: #{pid} target: [[#{target}]], PM: #{ self }"
137
+ # puts "#{File.basename(__FILE__)} #{__LINE__} READ:: klass: #{klass} pid: #{pid} target: [[#{target}]], PM: #{ self }"
138
138
 
139
139
  xampl, target = read_from_cache(klass, pid, target)
140
140
  return xampl if xampl and !target
@@ -98,7 +98,11 @@ module Xampl
98
98
  end
99
99
 
100
100
  note_errors("TC[[#{ @filename }]]:: open [#{ @filename }] error: %s\n") do
101
- @tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB | TDB::OTSYNC ) #TDB::OTSYNC slows it down by almost 50 times
101
+ if Xampl.raw_persister_options[:otsync] then
102
+ @tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB | TDB::OTSYNC ) #TDB::OTSYNC slows it down by almost 50 times
103
+ else
104
+ @tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB)
105
+ end
102
106
  end
103
107
 
104
108
  # Don't care if there are errors (in fact, if the index exists a failure is the expected thing)
@@ -109,9 +113,11 @@ module Xampl
109
113
  $numeric_indexes.each do | index_name |
110
114
  @tc_db.setindex(index_name, TDB::ITDECIMAL | TDB::ITKEEP)
111
115
  end
116
+
117
+ optimise
112
118
  end
113
119
 
114
- def optimise(opts)
120
+ def optimise(opts={})
115
121
  return unless @tc_db
116
122
 
117
123
  if opts[:indexes_only] then
@@ -359,6 +365,9 @@ module Xampl
359
365
 
360
366
  def do_sync_write
361
367
  begin
368
+ #@start = Time.now
369
+ #@last = Time.now
370
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
362
371
  # puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] **************************"
363
372
  # callers = caller(0)
364
373
  # puts " 0 #{ callers[0] }"
@@ -371,9 +380,11 @@ module Xampl
371
380
  note_errors("TC[[#{ @filename }]]:: tranbegin error: %s\n") do
372
381
  @tc_db.tranbegin
373
382
  end
383
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
374
384
 
375
385
  @changed.each do |xampl, ignore|
376
386
  write(xampl)
387
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
377
388
  end
378
389
  rescue => e
379
390
  msg = "no TC.abort attempted"
@@ -388,9 +399,11 @@ module Xampl
388
399
  raise RuntimeError, "TokyoCabinetPersister Error:: #{ msg }/#{ e }", e.backtrace
389
400
  else
390
401
  # puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] COMMIT"
402
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
391
403
  note_errors("TC[[#{ @filename }]]:: trancommit error: %s\n") do
392
404
  @tc_db.trancommit
393
405
  end
406
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
394
407
  ensure
395
408
  # puts " num records: #{ @tc_db.rnum() }"
396
409
  # puts "#{ __FILE__ }:#{ __LINE__ } keys..."
@@ -401,6 +414,7 @@ module Xampl
401
414
  # end
402
415
 
403
416
  # close
417
+ #puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] time: #{ Time.now - @start }/#{ Time.now - @last }"; @last = Time.now
404
418
  end
405
419
  end
406
420
 
@@ -435,14 +449,42 @@ module Xampl
435
449
  results
436
450
  end
437
451
 
452
+ def remove_all_mention(root, xampl)
453
+ xampl.remove_from(root)
454
+ root.children.each do | child |
455
+ remove_all_mention(child, xampl)
456
+ end
457
+ end
458
+
459
+ def expunge(xampl)
460
+ #NOTE -- this *must* be in a transaction
461
+ #NOTE -- the expunge operation is in two steps and is completed in write
462
+
463
+ mentions = Xampl.find_mentions_of(xampl)
464
+ mentions.each do | has_a_xampl |
465
+ # xampl.remove_from(has_a_xampl)
466
+ remove_all_mention(has_a_xampl, xampl)
467
+ end
468
+ xampl.changed
469
+ self.expunged << xampl
470
+
471
+ false
472
+ end
473
+
438
474
  def write(xampl)
439
475
  raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
440
476
 
477
+ expunging = self.expunged.include?(xampl)
478
+ self.expunged.delete(xampl) if expunging
479
+ # if expunging
480
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] EXPUNGING #{ xampl }/#{ expunging }"
481
+ # end
482
+
441
483
  place_dir = xampl.class.name.split("::")
442
484
  place = File.join( place_dir, xampl.get_the_index)
443
485
  place_dir = File.join( @files_dir, place_dir )
444
486
  mentions = Set.new
445
- data = represent(xampl, mentions)
487
+ xampl_in_xml = represent(xampl, mentions)
446
488
 
447
489
  #get rid of any supplimentary indexes associated with this xampl object
448
490
  # TODO -- This can be slow
@@ -458,83 +500,95 @@ module Xampl
458
500
  query.searchout
459
501
  end
460
502
 
461
- # TODO -- This can be slow
462
- mentions.each do | mention |
463
- mention_place = File.join(mention.class.name.split("::"), mention.get_the_index)
464
- #TODO -- will repeadedly changing a persisted xampl object fragment the TC db?
465
-
466
- pk = @tc_db.genuid
467
- mention_hash = {
468
- 'xampl-from' => place,
469
- 'mentioned_class' => xampl.class.name,
503
+ if expunging then
504
+ file_place = "#{ @files_dir }/#{ place }"
505
+ File.delete(file_place) if File.exists?(file_place)
506
+ note_errors("TC[[#{ place }]]:: write error: %s\n") do
507
+ @tc_db.out(place)
508
+ end
509
+
510
+ uncache(xampl)
511
+ else
512
+ if Xampl.raw_persister_options[:mentions] then
513
+ # TODO -- This can be slow
514
+ mentions.each do | mention |
515
+ mention_place = File.join(mention.class.name.split("::"), mention.get_the_index)
516
+ #TODO -- will repeadedly changing a persisted xampl object fragment the TC db?
517
+
518
+ pk = @tc_db.genuid
519
+ mention_hash = {
520
+ 'xampl-from' => place,
521
+ 'mentioned_class' => xampl.class.name,
522
+ 'pid' => xampl.get_the_index,
523
+ 'xampl-to' => mention_place
524
+ }
525
+
526
+ note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
527
+ @tc_db.put(pk, mention_hash)
528
+ end
529
+ end
530
+ end
531
+
532
+ xampl_hash = {
533
+ 'class' => xampl.class.name,
470
534
  'pid' => xampl.get_the_index,
471
- 'xampl-to' => mention_place
535
+ 'time-stamp' => @time_stamp,
536
+ 'xampl' => xampl_in_xml
472
537
  }
473
538
 
474
- note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
475
- @tc_db.put(pk, mention_hash)
539
+ primary_description, secondary_descriptions = xampl.describe_yourself
540
+ if primary_description then
541
+ xampl_hash = primary_description.merge(xampl_hash)
476
542
  end
477
- end
478
543
 
479
- xampl_hash = {
480
- 'class' => xampl.class.name,
481
- 'pid' => xampl.get_the_index,
482
- 'time-stamp' => @time_stamp,
483
- 'xampl' => data
484
- }
485
-
486
- # puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] #{ xampl.class.name } ... describe"
487
- primary_description, secondary_descriptions = xampl.describe_yourself
488
- if primary_description then
489
- xampl_hash = primary_description.merge(xampl_hash)
490
- end
491
-
492
- note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
493
- if Xampl.raw_persister_options[:write_through] then
494
- FileUtils.mkdir_p(place_dir) unless File.exist?(place_dir)
495
- file_place = "#{ @files_dir }/#{ place }"
496
- File.open(file_place, "w")do |out|
497
- out.write xampl_hash['xampl']
498
- if :sync == Xampl.raw_persister_options[:write_through] then
499
- out.fsync
500
- if $is_darwin then
501
- out.fcntl(51, 0) # Attempt an F_FULLFSYNC fcntl to commit data to disk (darwin *ONLY*)
544
+ note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
545
+ if Xampl.raw_persister_options[:write_through] then
546
+ FileUtils.mkdir_p(place_dir) unless File.exist?(place_dir)
547
+ file_place = "#{ @files_dir }/#{ place }"
548
+ File.open(file_place, "w") do |out|
549
+ out.write xampl_hash['xampl']
550
+ if :sync == Xampl.raw_persister_options[:write_through] then
551
+ out.fsync
552
+ if $is_darwin then
553
+ out.fcntl(51, 0) # Attempt an F_FULLFSYNC fcntl to commit data to disk (darwin *ONLY*)
554
+ end
502
555
  end
503
556
  end
504
- end
505
557
 
558
+ end
559
+ @tc_db.put(place, xampl_hash)
506
560
  end
507
- @tc_db.put(place, xampl_hash)
508
- end
509
561
 
510
- #TODO -- smarter regarding when to delete (e.g. mentions)
511
- if xampl.should_schedule_delete? and xampl.scheduled_for_deletion_at then
512
- secondary_descriptions = [] unless secondary_descriptions
513
- secondary_descriptions << { 'scheduled-delete-at' => xampl.scheduled_for_deletion_at }
514
- elsif xampl.scheduled_for_deletion_at then
515
- #TODO -- puts "#{ __FILE__ }:#{ __LINE__ } HOW TO DO THIS without violating xampl's change rules????? "
516
- #xampl.scheduled_for_deletion_at = nil
517
- end
562
+ #TODO -- smarter regarding when to delete (e.g. mentions)
563
+ if xampl.should_schedule_delete? and xampl.scheduled_for_deletion_at then
564
+ secondary_descriptions = [] unless secondary_descriptions
565
+ secondary_descriptions << { 'scheduled-delete-at' => xampl.scheduled_for_deletion_at }
566
+ elsif xampl.scheduled_for_deletion_at then
567
+ #TODO -- puts "#{ __FILE__ }:#{ __LINE__ } HOW TO DO THIS without violating xampl's change rules????? "
568
+ #xampl.scheduled_for_deletion_at = nil
569
+ end
518
570
 
519
- if secondary_descriptions then
520
- xampl_hash = {
521
- 'class' => xampl.class.name,
522
- 'pid' => xampl.get_the_index,
523
- 'xampl-place' => place
524
- }
571
+ if secondary_descriptions then
572
+ xampl_hash = {
573
+ 'class' => xampl.class.name,
574
+ 'pid' => xampl.get_the_index,
575
+ 'xampl-place' => place
576
+ }
525
577
 
526
- secondary_descriptions.each do | secondary_description |
527
- description = secondary_description.merge(xampl_hash)
578
+ secondary_descriptions.each do | secondary_description |
579
+ description = secondary_description.merge(xampl_hash)
528
580
 
529
- note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
530
- pk = @tc_db.genuid
531
- @tc_db.put(pk, description)
581
+ note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
582
+ pk = @tc_db.genuid
583
+ @tc_db.put(pk, description)
584
+ end
532
585
  end
533
586
  end
587
+
588
+ @write_count = @write_count + 1
589
+ xampl.changes_accepted
534
590
  end
535
591
 
536
- @write_count = @write_count + 1
537
- xampl.changes_accepted
538
592
  return true
539
593
  end
540
594
 
@@ -1,4 +1,4 @@
1
-
1
+ #encoding: utf-8
2
2
  module Xampl
3
3
 
4
4
  class CountingVisitor < Visitor
@@ -188,7 +188,12 @@ module Xampl
188
188
 
189
189
  def persist(out="", mentions=nil, rules=nil)
190
190
  persist_xml_new = PersistXML.new(out, mentions)
191
- return persist_xml_new.start(self).done
191
+
192
+ # start = Time.now
193
+ r = persist_xml_new.start(self).done
194
+ # done = Time.now
195
+ # puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] SIZE: #{ r.size }, Time: #{ done - start } #{ self }"
196
+ return r
192
197
  end
193
198
 
194
199
  ################################################################################################
@@ -5,6 +5,7 @@ module Xampl
5
5
 
6
6
  attr_reader :persister
7
7
  attr_accessor :load_needed
8
+ attr_accessor :must_be_mentioned
8
9
 
9
10
  def persist_required
10
11
  return true
data/xamplr.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{xamplr}
8
- s.version = "1.9.1"
8
+ s.version = "1.9.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bob Hutchison"]
12
- s.date = %q{2010-01-12}
12
+ s.date = %q{2010-01-20}
13
13
  s.description = %q{xamplr is the ruby version of xampl.}
14
14
  s.email = %q{hutch@recursive.ca}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xamplr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Hutchison
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-12 00:00:00 -05:00
12
+ date: 2010-01-20 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency