xamplr 1.2.0 → 1.3.15
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +12 -0
- data/CHANGES.txt +37 -0
- data/COPYING +661 -0
- data/Makefile +13 -0
- data/README.rdoc +24 -4
- data/Rakefile +2 -2
- data/VERSION.yml +3 -2
- data/bin/xampl-gen +17 -0
- data/docs/intro/.gitignore +1 -0
- data/docs/intro/example1/example1.rb +6 -0
- data/docs/intro/example1/xml/hello.xml +1 -0
- data/docs/intro/example2/example2.rb +38 -0
- data/docs/intro/example2/project-generator.rb +22 -0
- data/docs/intro/example2/xml/hello.xml +2 -0
- data/docs/intro/example3/example3.rb +30 -0
- data/docs/intro/example3/example3a.rb +16 -0
- data/docs/intro/example3/generated.png +0 -0
- data/docs/intro/example3/grab-yuml.rb +10 -0
- data/docs/intro/example3/greeter.rb +15 -0
- data/docs/intro/example3/greeting.rb +9 -0
- data/docs/intro/example3/project-generator.rb +25 -0
- data/docs/intro/example3/xml/greeter.xml +6 -0
- data/docs/intro/example4/example4.rb +27 -0
- data/docs/intro/example4/example4a.rb +19 -0
- data/docs/intro/example4/grab-yuml.rb +10 -0
- data/docs/intro/example4/greeter.rb +15 -0
- data/docs/intro/example4/greeting.rb +9 -0
- data/docs/intro/example4/project-generator.rb +25 -0
- data/docs/intro/example4/xml/greeter.xml +6 -0
- data/docs/intro/grab-yuml.rb +10 -0
- data/docs/intro/project-generator.rb +51 -0
- data/docs/intro/xampl.lyx +1494 -0
- data/docs/intro/xampl.pdf +0 -0
- data/examples/employees/final/xampl-gen.rb +38 -0
- data/examples/employees/final/xml/ddd-final.xml +86 -0
- data/examples/employees/final-xampl/xampl-gen.rb +38 -0
- data/examples/employees/final-xampl/xml/ddd-final-xampl.xml +86 -0
- data/examples/employees/first/xampl-gen.rb +38 -0
- data/examples/employees/first/xml/ddd-first.xml +48 -0
- data/examples/employees/twist/twist.graphml +333 -0
- data/examples/employees/twist/xampl-gen.rb +38 -0
- data/examples/employees/twist/xml/twist.xml +90 -0
- data/examples/employees/xamplr-twist.xml +2 -0
- data/examples/employees/yuml-diagrams/DDD-final-approach.graphml +393 -0
- data/examples/employees/yuml-diagrams/DDD-final-xampl-approach.graphml +265 -0
- data/examples/employees/yuml-diagrams/DDD-ideal-final-approach.graphml +357 -0
- data/examples/employees/yuml-diagrams/ddd-final.png +0 -0
- data/examples/employees/yuml-diagrams/ddd-final.yuml +8 -0
- data/examples/employees/yuml-diagrams/ddd-first.png +0 -0
- data/examples/employees/yuml-diagrams/ddd-first.yuml +7 -0
- data/examples/employees/yuml-diagrams/final-yed.png +0 -0
- data/examples/employees/yuml-diagrams/first-yed.png +0 -0
- data/examples/employees/yuml-diagrams/twist.png +0 -0
- data/examples/employees/yuml-diagrams/twist.yuml +12 -0
- data/examples/employees/yuml-diagrams/xamplr-final-no-mixins.png +0 -0
- data/examples/employees/yuml-diagrams/xamplr-final-simplified.png +0 -0
- data/examples/employees/yuml-diagrams/xamplr-final-with-mixins.png +0 -0
- data/examples/employees/yuml-diagrams/yuml-simplified.txt +19 -0
- data/examples/employees/yuml-diagrams/yuml-with-mixins.txt +53 -0
- data/examples/employees/yuml-diagrams/yuml.txt +27 -0
- data/examples/hobbies/Makefile +5 -0
- data/examples/hobbies/hobbies.rb +193 -0
- data/examples/hobbies/project-generator.rb +25 -0
- data/examples/hobbies/xampl-gen.rb +38 -0
- data/examples/hobbies/xml/hobby.xml +3 -0
- data/examples/hobbies/xml/people.xml +5 -0
- data/examples/random-people/.gitignore +2 -0
- data/examples/random-people/Makefile +5 -1
- data/examples/random-people/xampl-gen.rb +5 -2
- data/examples/random-people-shared-addresses/.gitignore +2 -0
- data/examples/random-people-shared-addresses/Makefile +8 -9
- data/examples/random-people-shared-addresses/batch-load-users-profiled.rb +91 -0
- data/examples/random-people-shared-addresses/batch-load-users-safe.rb +81 -0
- data/examples/random-people-shared-addresses/batch-load-users.rb +59 -63
- data/examples/random-people-shared-addresses/xampl-gen.rb +2 -0
- data/examples/read-testing/.gitignore +2 -0
- data/examples/read-testing/rrr.rb +2 -1
- data/examples/read-testing/xampl-gen.rb +2 -0
- data/examples/tokyo-cabinet-experimental/.gitignore +2 -0
- data/examples/tokyo-cabinet-experimental/xampl-gen.rb +2 -0
- data/examples/write-testing/README +4 -0
- data/examples/write-testing/RESULTS.home +33 -0
- data/examples/write-testing/RESULTS.raconteur +33 -0
- data/examples/write-testing/write-speed-test.rb +40 -0
- data/lib/xamplr/.cvsignore +1 -0
- data/lib/xamplr/TODO +2 -1
- data/lib/xamplr/exceptions.rb +24 -1
- data/lib/xamplr/from-xml.rb +13 -5
- data/lib/xamplr/graphml-out.rb +6 -25
- data/lib/xamplr/indexed-array.rb +10 -2
- data/lib/xamplr/persist-to-xml.rb +6 -7
- data/lib/xamplr/persistence.rb +132 -48
- data/lib/xamplr/persister.rb +48 -25
- data/lib/xamplr/persisters/filesystem.rb +8 -2
- data/lib/xamplr/persisters/tokyo-cabinet.rb +243 -63
- data/lib/xamplr/persisters/tokyo-cabinet.rb.1-DB +694 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb.N-DB +692 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb.NICE-TRY +807 -0
- data/lib/xamplr/templates/.cvsignore +3 -0
- data/lib/xamplr/templates/child_indexed.template +6 -6
- data/lib/xamplr/templates/element_data.template +2 -1
- data/lib/xamplr/templates/element_empty.template +2 -10
- data/lib/xamplr/templates/element_mixed.template +2 -1
- data/lib/xamplr/templates/element_simple.template +2 -1
- data/lib/xamplr/templates/package.template +13 -1
- data/lib/xamplr/visitor.rb +7 -6
- data/lib/xamplr/visitors.rb +2 -1
- data/lib/xamplr/xampl-cl-gen.rb +89 -0
- data/lib/xamplr/xampl-generator.rb +86 -50
- data/lib/xamplr/xampl-object.rb +51 -0
- data/lib/xamplr/xampl-persisted-object.rb +13 -4
- data/lib/xamplr/yuml-out.rb +129 -0
- data/lib/xamplr-generator.rb +0 -1
- data/lib/xamplr.rb +18 -18
- data/regression/tc-indexes-crossing-pid-boundaries/Makefile +14 -0
- data/regression/tc-indexes-crossing-pid-boundaries/bad-idea.rb +40 -0
- data/regression/tc-indexes-crossing-pid-boundaries/fail-badly.rb +17 -0
- data/regression/tc-indexes-crossing-pid-boundaries/fail.rb +11 -0
- data/regression/tc-indexes-crossing-pid-boundaries/fucking-bad-idea.rb +44 -0
- data/regression/tc-indexes-crossing-pid-boundaries/setup.rb +15 -0
- data/regression/tc-indexes-crossing-pid-boundaries/xml/bad-idea.xml +4 -0
- data/regression/tightly-nested-mutual-mentions/Makefile +14 -0
- data/regression/tightly-nested-mutual-mentions/build.rb +31 -0
- data/regression/tightly-nested-mutual-mentions/load.rb +21 -0
- data/regression/tightly-nested-mutual-mentions/repo-keep.tgz +0 -0
- data/regression/tightly-nested-mutual-mentions/setup.rb +8 -0
- data/regression/tightly-nested-mutual-mentions/xampl-gen.rb +36 -0
- data/regression/tightly-nested-mutual-mentions/xml/stuff.xml +7 -0
- data/xamplr.gemspec +322 -0
- metadata +116 -13
- data/test/test_helper.rb +0 -10
- data/test/xamplr_test.rb +0 -7
data/lib/xamplr/persister.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "xamplr/persistence"
|
3
2
|
|
4
3
|
module Xampl
|
@@ -41,6 +40,11 @@ module Xampl
|
|
41
40
|
self.sync
|
42
41
|
end
|
43
42
|
|
43
|
+
def shutdown
|
44
|
+
# self.sync
|
45
|
+
# self.close
|
46
|
+
end
|
47
|
+
|
44
48
|
def busy(yes)
|
45
49
|
if yes then
|
46
50
|
@busy_count += 1
|
@@ -204,7 +208,15 @@ module Xampl
|
|
204
208
|
|
205
209
|
def put_changed(msg="")
|
206
210
|
puts "Changed::#{msg}:"
|
207
|
-
@changed.each { | xampl, ignore | puts "
|
211
|
+
@changed.each { | xampl, ignore | puts " #{xampl.tag} #{xampl.get_the_index}" }
|
212
|
+
end
|
213
|
+
|
214
|
+
def start_sync_write
|
215
|
+
#only if needed
|
216
|
+
end
|
217
|
+
|
218
|
+
def done_sync_write
|
219
|
+
# only if needed
|
208
220
|
end
|
209
221
|
|
210
222
|
def do_sync_write
|
@@ -220,29 +232,39 @@ module Xampl
|
|
220
232
|
def sync
|
221
233
|
#raise XamplException.new(:live_across_rollback) if @rolled_back
|
222
234
|
begin
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
235
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNC changed: #{@changed.size}" if 0 < @changed.size
|
236
|
+
# @changed.each do | key, value |
|
237
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] key: #{key.class.name}, pid: #{key.get_the_index}"
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# if 0 < @changed.size then
|
241
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNC changed: #{@changed.size}"
|
242
|
+
# caller(0).each do | trace |
|
243
|
+
# next if /xamplr/ =~ trace
|
244
|
+
# puts " #{trace}"
|
245
|
+
# break if /actionpack/ =~ trace
|
246
|
+
# end
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNC changed: #{@changed.size}"
|
250
|
+
if 0 < @changed.size then
|
251
|
+
begin
|
252
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNC changed: #{@changed.size}"
|
253
|
+
busy(true)
|
254
|
+
# if @syncing then
|
255
|
+
# puts "\n\n\n\n#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNCING IS ALREADY TRUE!!!!!!\n\n\n"
|
256
|
+
# end
|
257
|
+
@syncing = true
|
258
|
+
|
259
|
+
start_sync_write
|
260
|
+
do_sync_write
|
261
|
+
ensure
|
262
|
+
done_sync_write
|
263
|
+
@syncing = false
|
264
|
+
end
|
265
|
+
else
|
266
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] SYNC, noting changed"
|
267
|
+
end
|
246
268
|
|
247
269
|
@changed = {}
|
248
270
|
|
@@ -260,6 +282,7 @@ module Xampl
|
|
260
282
|
return @last_write_count
|
261
283
|
ensure
|
262
284
|
busy(false)
|
285
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] **** SYNCING IS FALSE"
|
263
286
|
@syncing = false
|
264
287
|
end
|
265
288
|
end
|
@@ -25,7 +25,6 @@ module Xampl
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
28
|
def write(xampl)
|
30
29
|
#raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index or xampl.ignore_when_no_index
|
31
30
|
raise XamplException.new("no_index_so_no_persist [#{xampl.class.name}]") unless xampl.get_the_index or xampl.ignore_when_no_index
|
@@ -39,7 +38,14 @@ module Xampl
|
|
39
38
|
|
40
39
|
representation = represent(xampl)
|
41
40
|
if representation then
|
42
|
-
File.open(place, "w")
|
41
|
+
File.open(place, "w")do |out|
|
42
|
+
out.puts representation
|
43
|
+
out.fsync
|
44
|
+
if $is_darwin then
|
45
|
+
out.fcntl(51, 0) # Attempt an F_FULLFSYNC fcntl to commit data to disk
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
43
49
|
@write_count = @write_count + 1
|
44
50
|
end
|
45
51
|
xampl.changes_accepted
|
@@ -5,29 +5,49 @@ module Xampl
|
|
5
5
|
require 'xamplr/persisters/caching'
|
6
6
|
require 'set'
|
7
7
|
|
8
|
-
# require 'ruby-prof'
|
8
|
+
# require 'ruby-prof'
|
9
9
|
|
10
10
|
class TokyoCabinetPersister < AbstractCachingPersister
|
11
11
|
include TokyoCabinet
|
12
12
|
|
13
13
|
def note_errors(msg="TokyoCabinet Error:: %s\n")
|
14
|
-
|
14
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] START"
|
15
|
+
# puts "--------------------------------------------------"
|
16
|
+
# caller(0).each { |trace| puts " #{trace}" }
|
17
|
+
# puts "--------------------------------------------------\n\n"
|
18
|
+
exception = nil
|
19
|
+
begin
|
20
|
+
result = yield
|
21
|
+
rescue => e
|
22
|
+
exception = e
|
23
|
+
end
|
15
24
|
|
16
25
|
rmsg = nil
|
17
26
|
unless result then
|
18
27
|
rmsg = sprintf(msg, @tc_db.errmsg(@tc_db.ecode))
|
28
|
+
STDERR.puts "NOTE: TokyoCabinet Error!"
|
19
29
|
STDERR.printf(rmsg)
|
20
30
|
STDERR.puts "---------"
|
21
31
|
caller(0).each do |trace|
|
22
32
|
STDERR.puts(trace)
|
23
33
|
end
|
24
34
|
STDERR.puts "---------"
|
35
|
+
|
36
|
+
# STDOUT.puts "NOTE: TokyoCabinet Error!"
|
37
|
+
# STDOUT.printf(rmsg)
|
38
|
+
# STDOUT.puts "---------"
|
39
|
+
# caller(0).each do |trace|
|
40
|
+
# STDOUT.puts(trace)
|
41
|
+
# end
|
42
|
+
# STDOUT.puts "---------"
|
25
43
|
end
|
44
|
+
raise exception if exception
|
26
45
|
return rmsg
|
27
46
|
end
|
28
47
|
|
29
|
-
$lexical_indexes = Set.new(%w{ class pid time-stamp
|
30
|
-
|
48
|
+
$lexical_indexes = Set.new(%w{ class pid time-stamp xampl-from xampl-to xampl-place }) unless defined?($lexical_indexes)
|
49
|
+
|
50
|
+
$numeric_indexes = Set.new(%w{ scheduled-delete-at }) unless defined?($numeric_indexes)
|
31
51
|
|
32
52
|
def TokyoCabinetPersister.add_lexical_indexs(indexes)
|
33
53
|
$lexical_indexes.merge(indexes)
|
@@ -40,31 +60,54 @@ module Xampl
|
|
40
60
|
def initialize(name=nil, format=nil, root=File.join(".", "repo"))
|
41
61
|
super(root, name, format)
|
42
62
|
|
43
|
-
|
63
|
+
@files_dir = "#{ @root_dir }/files"
|
64
|
+
# FileUtils.mkdir_p(@root_dir) unless File.exist?(@root_dir)
|
65
|
+
FileUtils.mkdir_p(@files_dir) unless File.exist?(@files_dir)
|
44
66
|
@filename = "#{@root_dir}/repo.tct"
|
67
|
+
@tc_db = nil
|
68
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] file: #{ @filename }, db: #{ @tc_db.class.name }"
|
45
69
|
|
46
70
|
open_tc_db()
|
47
71
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
72
|
+
# note_errors("TC[[#{ @filename }]]:: optimisation error: %s\n") do
|
73
|
+
# @tc_db.optimize(-1, -1, -1, TDB::TDEFLATE)
|
74
|
+
# end
|
75
|
+
# note_errors("TC[[#{ @filename }]]:: close error: %s\n") do
|
76
|
+
# @tc_db.close
|
77
|
+
# end
|
78
|
+
|
79
|
+
begin
|
80
|
+
note_errors("TC[[#{ @filename }]]:: close error in initialize: %s\n") do
|
81
|
+
@tc_db.close
|
82
|
+
end
|
83
|
+
@tc_db = nil
|
84
|
+
rescue => e
|
85
|
+
puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] OH CRAP!!! #{ e }"
|
86
|
+
end
|
54
87
|
end
|
55
88
|
|
56
89
|
def open_tc_db
|
57
|
-
|
58
|
-
#
|
59
|
-
#
|
60
|
-
|
90
|
+
# if @tcdb then
|
91
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] ALREADY OPEN #{ @filename }"
|
92
|
+
# else
|
93
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] OPEN #{ @filename }"
|
94
|
+
## callers = caller(0)
|
95
|
+
## puts " 0 #{ callers[0] }"
|
96
|
+
## puts " 1 #{ callers[1] }"
|
97
|
+
## puts " 2 #{ callers[2] }"
|
98
|
+
# #puts "#{File.basename(__FILE__)}:#{__LINE__} callers..."
|
99
|
+
# #caller(0).each { | trace | puts " #{trace}"}
|
100
|
+
# end
|
101
|
+
|
102
|
+
return if @tc_db # if there is a tc_db then it is already open
|
103
|
+
|
61
104
|
@tc_db = TDB.new
|
62
105
|
note_errors("TC[[#{ @filename }]]:: tuning error: %s\n") do
|
63
106
|
@tc_db.tune(-1, -1, -1, TDB::TDEFLATE)
|
64
107
|
end
|
65
108
|
|
66
109
|
note_errors("TC[[#{ @filename }]]:: open [#{ @filename }] error: %s\n") do
|
67
|
-
@tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB ) #TDB::OTSYNC slows it down by almost 50 times
|
110
|
+
@tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB | TDB::OTSYNC ) #TDB::OTSYNC slows it down by almost 50 times
|
68
111
|
end
|
69
112
|
|
70
113
|
# Don't care if there are errors (in fact, if the index exists a failure is the expected thing)
|
@@ -96,13 +139,24 @@ module Xampl
|
|
96
139
|
end
|
97
140
|
|
98
141
|
def close
|
142
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] CLOSE #{ @filename }"
|
143
|
+
# callers = caller(0)
|
144
|
+
# puts " 0 #{ callers[0] }"
|
145
|
+
# puts " 1 #{ callers[1] }"
|
146
|
+
# puts " 2 #{ callers[2] }"
|
147
|
+
|
99
148
|
if @tc_db then
|
100
|
-
|
101
|
-
|
102
|
-
@
|
149
|
+
begin
|
150
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] NO SELF SYNC?? [#{ @currently_syncing }] --> db: #{ @tc_db.class.name }"
|
151
|
+
self.sync unless @currently_syncing
|
152
|
+
rescue => e
|
153
|
+
puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] OH CRAP!!! #{ e }"
|
154
|
+
ensure
|
155
|
+
note_errors("TC[[#{ @filename }]]:: close error: %s\n") do
|
156
|
+
@tc_db.close
|
157
|
+
end
|
158
|
+
@tc_db = nil
|
103
159
|
end
|
104
|
-
@tc_db = nil
|
105
|
-
# puts "#{File.basename(__FILE__)}:#{__LINE__} close tc db: #{ @filename }"
|
106
160
|
end
|
107
161
|
end
|
108
162
|
|
@@ -155,9 +209,9 @@ module Xampl
|
|
155
209
|
end
|
156
210
|
|
157
211
|
if hint then
|
158
|
-
return results, the_hint
|
212
|
+
return results.uniq, the_hint
|
159
213
|
else
|
160
|
-
return results
|
214
|
+
return results.uniq
|
161
215
|
end
|
162
216
|
end
|
163
217
|
|
@@ -199,9 +253,9 @@ module Xampl
|
|
199
253
|
end
|
200
254
|
|
201
255
|
if hint then
|
202
|
-
return results, the_hint
|
256
|
+
return results.uniq, the_hint
|
203
257
|
else
|
204
|
-
return results
|
258
|
+
return results.uniq
|
205
259
|
end
|
206
260
|
end
|
207
261
|
|
@@ -219,10 +273,15 @@ module Xampl
|
|
219
273
|
result_keys = query.search
|
220
274
|
end
|
221
275
|
|
276
|
+
results = result_keys.collect do |key|
|
277
|
+
meta = @tc_db[ key ]
|
278
|
+
meta['xampl-place'] || meta['place']
|
279
|
+
end
|
280
|
+
|
222
281
|
if hint then
|
223
|
-
return
|
282
|
+
return results.uniq, the_hint
|
224
283
|
else
|
225
|
-
return
|
284
|
+
return results.uniq
|
226
285
|
end
|
227
286
|
end
|
228
287
|
|
@@ -255,7 +314,7 @@ module Xampl
|
|
255
314
|
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
256
315
|
|
257
316
|
query = TableQuery.new(@tc_db)
|
258
|
-
query.add_condition('
|
317
|
+
query.add_condition('xampl-to', :equals, place)
|
259
318
|
result_keys = query.search
|
260
319
|
|
261
320
|
class_cache = {}
|
@@ -263,8 +322,8 @@ module Xampl
|
|
263
322
|
result = @tc_db[ key ]
|
264
323
|
next unless result
|
265
324
|
|
266
|
-
mentioner = result['
|
267
|
-
class_name = result['
|
325
|
+
mentioner = result['xampl-from']
|
326
|
+
class_name = result['mentioned_class']
|
268
327
|
result_class = class_cache[class_name]
|
269
328
|
unless result_class then
|
270
329
|
class_name.split("::").each do | chunk |
|
@@ -280,30 +339,43 @@ module Xampl
|
|
280
339
|
|
281
340
|
self.lookup(result_class, result['pid'])
|
282
341
|
end
|
283
|
-
return results
|
342
|
+
return results.uniq
|
284
343
|
end
|
285
344
|
|
286
|
-
def
|
287
|
-
#
|
288
|
-
|
289
|
-
#
|
290
|
-
#
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
# puts "#{File.basename(__FILE__)}:#{__LINE__} stop this profiler"
|
295
|
-
# end
|
296
|
-
#
|
297
|
-
# def do_sync_write_work
|
345
|
+
def start_sync_write
|
346
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] #{ @filename }"
|
347
|
+
# callers = caller(0)
|
348
|
+
# puts " 0 #{ callers[0] }"
|
349
|
+
# puts " 1 #{ callers[1] }"
|
350
|
+
# puts " 2 #{ callers[2] }"
|
351
|
+
|
352
|
+
@currently_syncing = true
|
298
353
|
open_tc_db
|
299
|
-
|
354
|
+
end
|
355
|
+
|
356
|
+
def done_sync_write
|
357
|
+
begin
|
358
|
+
note_errors("TC[[#{ @filename }]]:: sync error in done_sync_write: %s\n") do
|
359
|
+
@tc_db.sync
|
360
|
+
end
|
361
|
+
# close
|
362
|
+
ensure
|
363
|
+
@currently_syncing = false
|
364
|
+
end
|
365
|
+
end
|
300
366
|
|
301
|
-
# puts "DO SYNC WRITE: #{ @changed.size } to be written (#{ @filename })"
|
302
|
-
# note_errors("TC:: open error: %s\n") do
|
303
|
-
# @tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB ) #TDB::OTSYNC slows it down by almost 50 times
|
304
|
-
# end
|
305
367
|
|
368
|
+
def do_sync_write
|
306
369
|
begin
|
370
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] **************************"
|
371
|
+
# callers = caller(0)
|
372
|
+
# puts " 0 #{ callers[0] }"
|
373
|
+
# puts " 1 #{ callers[1] }"
|
374
|
+
# puts " 2 #{ callers[2] }"
|
375
|
+
|
376
|
+
# open_tc_db
|
377
|
+
@time_stamp = Time.now.to_f.to_s
|
378
|
+
|
307
379
|
note_errors("TC[[#{ @filename }]]:: tranbegin error: %s\n") do
|
308
380
|
@tc_db.tranbegin
|
309
381
|
end
|
@@ -313,45 +385,97 @@ module Xampl
|
|
313
385
|
end
|
314
386
|
rescue => e
|
315
387
|
msg = "no TC.abort attempted"
|
316
|
-
msg = note_errors("TC[[#{ @filename }]]::
|
388
|
+
msg = note_errors("TC[[#{ @filename }]]:: tranabort error: %s\n") do
|
317
389
|
@tc_db.tranabort
|
318
390
|
end
|
391
|
+
puts "------------------------------------------------------------------------"
|
392
|
+
puts "TokyoCabinetPersister Error:: #{ msg }/#{ e }"
|
393
|
+
puts e.backtrace.join("\n")
|
394
|
+
puts "------------------------------------------------------------------------"
|
319
395
|
raise "TokyoCabinetPersister Error:: #{ msg }/#{ e }"
|
320
396
|
else
|
397
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] COMMIT"
|
321
398
|
note_errors("TC[[#{ @filename }]]:: trancommit error: %s\n") do
|
322
399
|
@tc_db.trancommit
|
323
400
|
end
|
324
401
|
ensure
|
325
|
-
# note_errors("TC[[#{ @filename }]]:: close error: %s\n") do
|
326
|
-
# @tc_db.close()
|
327
|
-
# end
|
328
|
-
end
|
329
402
|
# puts " num records: #{ @tc_db.rnum() }"
|
403
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } keys..."
|
404
|
+
# @tc_db.keys.each do | key |
|
405
|
+
# meta = @tc_db[key]
|
406
|
+
# meta['xampl'] = (meta['xampl'] || "no rep")[0..25]
|
407
|
+
# puts " key: [#{ key }] -- #{ meta.inspect }"
|
408
|
+
# end
|
409
|
+
|
410
|
+
# close
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def how_indexed(xampl)
|
415
|
+
raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
|
416
|
+
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
417
|
+
|
418
|
+
open_tc_db
|
419
|
+
|
420
|
+
result_keys = Set.new
|
421
|
+
|
422
|
+
query = TableQuery.new(@tc_db)
|
423
|
+
query.add_condition('xampl-place', :equals, place)
|
424
|
+
search_results = query.search
|
425
|
+
result_keys.merge( search_results)
|
426
|
+
|
427
|
+
primary = @tc_db[ place ]
|
428
|
+
if primary then
|
429
|
+
primary.delete('xampl')
|
430
|
+
end
|
431
|
+
|
432
|
+
results = primary ? [ primary ] : []
|
433
|
+
result_keys.each do | key |
|
434
|
+
result = @tc_db[ key ]
|
435
|
+
next unless result
|
436
|
+
|
437
|
+
result.delete('xampl')
|
438
|
+
|
439
|
+
results << result
|
440
|
+
end
|
441
|
+
|
442
|
+
results
|
330
443
|
end
|
331
444
|
|
332
445
|
def write(xampl)
|
333
446
|
raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
|
334
447
|
|
335
|
-
|
448
|
+
place_dir = xampl.class.name.split("::")
|
449
|
+
place = File.join( place_dir, xampl.get_the_index)
|
450
|
+
place_dir = File.join( @files_dir, place_dir )
|
336
451
|
mentions = Set.new
|
337
452
|
data = represent(xampl, mentions)
|
338
453
|
|
454
|
+
#get rid of any supplimentary indexes associated with this xampl object
|
455
|
+
# TODO -- This can be slow
|
339
456
|
query = TableQuery.new(@tc_db)
|
340
|
-
query.add_condition('
|
457
|
+
query.add_condition('xampl-from', :equals, place)
|
341
458
|
note_errors("TC[[#{ @filename }]]:: failed to remove from mentions, error: %s\n") do
|
342
459
|
query.searchout
|
343
460
|
end
|
344
461
|
|
462
|
+
query = TableQuery.new(@tc_db)
|
463
|
+
query.add_condition('xampl-place', :equals, place)
|
464
|
+
note_errors("TC[[#{ @filename }]]:: failed to remove from mentions, error: %s\n") do
|
465
|
+
query.searchout
|
466
|
+
end
|
467
|
+
|
468
|
+
# TODO -- This can be slow
|
345
469
|
mentions.each do | mention |
|
346
470
|
mention_place = File.join(mention.class.name.split("::"), mention.get_the_index)
|
347
471
|
#TODO -- will repeadedly changing a persisted xampl object fragment the TC db?
|
348
472
|
|
349
473
|
pk = @tc_db.genuid
|
350
474
|
mention_hash = {
|
351
|
-
'
|
352
|
-
'
|
475
|
+
'xampl-from' => place,
|
476
|
+
'mentioned_class' => xampl.class.name,
|
353
477
|
'pid' => xampl.get_the_index,
|
354
|
-
'
|
478
|
+
'xampl-to' => mention_place
|
355
479
|
}
|
356
480
|
|
357
481
|
note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
|
@@ -366,15 +490,56 @@ module Xampl
|
|
366
490
|
'xampl' => data
|
367
491
|
}
|
368
492
|
|
369
|
-
|
370
|
-
|
371
|
-
|
493
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] #{ xampl.class.name } ... describe"
|
494
|
+
primary_description, secondary_descriptions = xampl.describe_yourself
|
495
|
+
if primary_description then
|
496
|
+
xampl_hash = primary_description.merge(xampl_hash)
|
372
497
|
end
|
373
498
|
|
374
499
|
note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
|
500
|
+
if Xampl.raw_persister_options[:write_through] then
|
501
|
+
FileUtils.mkdir_p(place_dir) unless File.exist?(place_dir)
|
502
|
+
file_place = "#{ @files_dir }/#{ place }"
|
503
|
+
File.open(file_place, "w")do |out|
|
504
|
+
out.write xampl_hash['xampl']
|
505
|
+
if :sync == Xampl.raw_persister_options[:write_through] then
|
506
|
+
out.fsync
|
507
|
+
if $is_darwin then
|
508
|
+
out.fcntl(51, 0) # Attempt an F_FULLFSYNC fcntl to commit data to disk (darwin *ONLY*)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
end
|
375
514
|
@tc_db.put(place, xampl_hash)
|
376
515
|
end
|
377
516
|
|
517
|
+
#TODO -- smarter regarding when to delete (e.g. mentions)
|
518
|
+
if xampl.should_schedule_delete? and xampl.scheduled_for_deletion_at then
|
519
|
+
secondary_descriptions = [] unless secondary_descriptions
|
520
|
+
secondary_descriptions << { 'scheduled-delete-at' => xampl.scheduled_for_deletion_at }
|
521
|
+
elsif xampl.scheduled_for_deletion_at then
|
522
|
+
puts "#{ __FILE__ }:#{ __LINE__ } HOW TO DO THIS without violating xampl's change rules????? "
|
523
|
+
#xampl.scheduled_for_deletion_at = nil
|
524
|
+
end
|
525
|
+
|
526
|
+
if secondary_descriptions then
|
527
|
+
xampl_hash = {
|
528
|
+
'class' => xampl.class.name,
|
529
|
+
'pid' => xampl.get_the_index,
|
530
|
+
'xampl-place' => place
|
531
|
+
}
|
532
|
+
|
533
|
+
secondary_descriptions.each do | secondary_description |
|
534
|
+
description = secondary_description.merge(xampl_hash)
|
535
|
+
|
536
|
+
note_errors("TC[[#{ @filename }]]:: write error: %s\n") do
|
537
|
+
pk = @tc_db.genuid
|
538
|
+
@tc_db.put(pk, description)
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
378
543
|
@write_count = @write_count + 1
|
379
544
|
xampl.changes_accepted
|
380
545
|
return true
|
@@ -389,10 +554,14 @@ module Xampl
|
|
389
554
|
# puts "#{File.basename(__FILE__)}:#{__LINE__} READ #{ klass }/#{ pid }"
|
390
555
|
# caller(0).each { | trace | puts " #{trace}"}
|
391
556
|
|
392
|
-
open_tc_db
|
393
|
-
place = File.join(klass.name.split("::"), pid)
|
394
557
|
representation = nil
|
395
558
|
|
559
|
+
unless @tc_db then
|
560
|
+
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] READ REP"
|
561
|
+
open_tc_db
|
562
|
+
end
|
563
|
+
place = File.join(klass.name.split("::"), pid)
|
564
|
+
|
396
565
|
meta = @tc_db[place]
|
397
566
|
representation = meta['xampl'] if meta
|
398
567
|
|
@@ -508,6 +677,7 @@ module Xampl
|
|
508
677
|
|
509
678
|
def initialize (table)
|
510
679
|
@query = TDBQRY::new(table)
|
680
|
+
@text_form = []
|
511
681
|
@opts = {}
|
512
682
|
end
|
513
683
|
|
@@ -602,6 +772,8 @@ module Xampl
|
|
602
772
|
op = op | TDBQRY::QCNEGATE unless affirmative
|
603
773
|
op = op | TDBQRY::QCNOIDX if no_index
|
604
774
|
|
775
|
+
@text_form << "operator: #{ operator }#{ affirmative ? '' : ' NEGATED'}#{ no_index ? ' NO INDEX' : ''} -- col: '#{ colname }', val: '#{ val }'"
|
776
|
+
|
605
777
|
@query.addcond(colname, op, val)
|
606
778
|
end
|
607
779
|
|
@@ -634,6 +806,14 @@ module Xampl
|
|
634
806
|
def order_by (colname, direction=:strasc)
|
635
807
|
@query.setorder(colname, DIRECTIONS[direction])
|
636
808
|
end
|
809
|
+
|
810
|
+
def inspect
|
811
|
+
"TableQuery:\n#{ @text_form.join("\n") }"
|
812
|
+
end
|
813
|
+
|
814
|
+
def to_s
|
815
|
+
inspect
|
816
|
+
end
|
637
817
|
end
|
638
818
|
|
639
819
|
Xampl.register_persister_kind(TokyoCabinetPersister)
|