xamplr 1.9.1 → 1.9.2

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