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 +1 -1
- data/lib/xamplr/from-xml.rb +3 -0
- data/lib/xamplr/persist-to-xml.rb +20 -5
- data/lib/xamplr/persister.rb +12 -1
- data/lib/xamplr/persisters/caching.rb +1 -1
- data/lib/xamplr/persisters/tokyo-cabinet.rb +117 -63
- data/lib/xamplr/visitors.rb +1 -1
- data/lib/xamplr/xampl-object.rb +6 -1
- data/lib/xamplr/xampl-persisted-object.rb +1 -0
- data/xamplr.gemspec +2 -2
- metadata +2 -2
data/VERSION.yml
CHANGED
data/lib/xamplr/from-xml.rb
CHANGED
@@ -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 =
|
110
|
-
|
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
|
124
|
-
#
|
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
|
data/lib/xamplr/persister.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
462
|
-
|
463
|
-
|
464
|
-
#
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
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
|
-
'
|
535
|
+
'time-stamp' => @time_stamp,
|
536
|
+
'xampl' => xampl_in_xml
|
472
537
|
}
|
473
538
|
|
474
|
-
|
475
|
-
|
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
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
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
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
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
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
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
|
-
|
527
|
-
|
578
|
+
secondary_descriptions.each do | secondary_description |
|
579
|
+
description = secondary_description.merge(xampl_hash)
|
528
580
|
|
529
|
-
|
530
|
-
|
531
|
-
|
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
|
|
data/lib/xamplr/visitors.rb
CHANGED
data/lib/xamplr/xampl-object.rb
CHANGED
@@ -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
|
-
|
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
|
################################################################################################
|
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.
|
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
|
+
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.
|
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
|
+
date: 2010-01-20 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|