hutch-xamplr 1.0.5 → 1.1.0

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.
Files changed (76) hide show
  1. data/Rakefile +1 -0
  2. data/VERSION.yml +2 -2
  3. data/examples/random-people-shared-addresses/Makefile +2 -2
  4. data/examples/random-people-shared-addresses/batch-load-users.rb +2 -5
  5. data/examples/random-people-shared-addresses/find-mentions.rb +1 -4
  6. data/examples/random-people-shared-addresses/find-people-by-address.rb +1 -4
  7. data/examples/random-people-shared-addresses/optimise.rb +1 -4
  8. data/examples/random-people-shared-addresses/people.rb +0 -15
  9. data/examples/random-people-shared-addresses/query.rb +1 -4
  10. data/examples/random-people-shared-addresses/query2.rb +1 -4
  11. data/examples/random-people-shared-addresses/results.write.BASELINE +298 -0
  12. data/examples/random-people-shared-addresses/results.write.NEW_ATTR_ENCODING +294 -0
  13. data/examples/random-people-shared-addresses/settings.rb +3 -0
  14. data/examples/random-people/batch-load-users.rb +1 -4
  15. data/examples/random-people/optimise.rb +1 -4
  16. data/examples/random-people/people.rb +0 -3
  17. data/examples/random-people/query.rb +1 -5
  18. data/examples/random-people/query2.rb +1 -4
  19. data/examples/random-people/settings.rb +3 -0
  20. data/examples/random-people/what-to-query-on.rb +1 -3
  21. data/examples/read-testing/Makefile +10 -0
  22. data/examples/read-testing/load.rb +65 -0
  23. data/examples/read-testing/read.rb +51 -0
  24. data/examples/read-testing/results.read.BASELINE +6 -0
  25. data/examples/read-testing/results.read.FAST +5 -0
  26. data/examples/read-testing/rrr.rb +87 -0
  27. data/examples/read-testing/settings.rb +2 -0
  28. data/examples/read-testing/xampl-gen.rb +36 -0
  29. data/examples/read-testing/xml/text.xml +8 -0
  30. data/lib/xamplr.rb +10 -1
  31. data/lib/xamplr/exceptions.rb +97 -0
  32. data/lib/xamplr/from-xml-orig.rb +350 -0
  33. data/lib/xamplr/from-xml.rb +272 -183
  34. data/lib/xamplr/handwritten/example.rb +0 -58
  35. data/lib/xamplr/handwritten/hand-example.rb +0 -27
  36. data/lib/xamplr/handwritten/test-handwritten.rb +0 -37
  37. data/lib/xamplr/mixins.rb +10 -48
  38. data/lib/xamplr/persist-to-xml.rb +249 -0
  39. data/lib/xamplr/persistence.rb +44 -412
  40. data/lib/xamplr/persistence.rb.more_thread_safe +0 -13
  41. data/lib/xamplr/persistence.rb.partially_thread_safe +0 -13
  42. data/lib/xamplr/persister.rb +298 -0
  43. data/lib/xamplr/{persister → persisters}/caches.rb +0 -0
  44. data/lib/xamplr/{persister → persisters}/caching.rb +1 -1
  45. data/lib/xamplr/{persister → persisters}/filesystem.rb +4 -5
  46. data/lib/xamplr/{persister → persisters}/in-memory.rb +1 -1
  47. data/lib/xamplr/{persister → persisters}/simple.rb +0 -0
  48. data/lib/xamplr/{persister → persisters}/tokyo-cabinet.rb +53 -15
  49. data/lib/xamplr/simpleTemplate/{input-c.r4 → obsolete/input-c.r4} +0 -0
  50. data/lib/xamplr/simpleTemplate/{play.r6.txt → obsolete/play.r6.txt} +0 -0
  51. data/lib/xamplr/simpleTemplate/{play_more.r6.txt → obsolete/play_more.r6.txt} +0 -0
  52. data/lib/xamplr/simpleTemplate/{test001.r5 → obsolete/test001.r5} +0 -0
  53. data/lib/xamplr/simpleTemplate/{test002.r5 → obsolete/test002.r5} +0 -0
  54. data/lib/xamplr/simpleTemplate/{test003.r5 → obsolete/test003.r5} +0 -0
  55. data/lib/xamplr/templates/child_indexed.template +1 -1
  56. data/lib/xamplr/templates/element_classes.template +1 -1
  57. data/lib/xamplr/templates/element_data.template +0 -39
  58. data/lib/xamplr/templates/element_empty.template +0 -40
  59. data/lib/xamplr/templates/element_mixed.template +0 -41
  60. data/lib/xamplr/templates/element_simple.template +0 -40
  61. data/lib/xamplr/test-support/bench.rb +6 -26
  62. data/lib/xamplr/test-support/test.rb +1 -89
  63. data/lib/xamplr/visitor.rb +0 -778
  64. data/lib/xamplr/visitors.rb +573 -0
  65. data/lib/xamplr/xampl-generator.rb +1 -1
  66. data/lib/xamplr/xampl-hand-generated.rb +0 -85
  67. data/lib/xamplr/xampl-module.rb +36 -0
  68. data/lib/xamplr/xampl-object-internals.rb +6 -0
  69. data/lib/xamplr/xampl-object.rb +10 -341
  70. data/lib/xamplr/xampl-persisted-object.rb +122 -0
  71. data/lib/xamplr/xml-text.rb +117 -0
  72. metadata +53 -18
  73. data/lib/xamplr/persister/subversion.rb +0 -61
  74. data/lib/xamplr/rac.sh +0 -6
  75. data/lib/xamplr/rac_gen.sh +0 -1
  76. data/lib/xamplr/templates/child_indexed.template.000 +0 -87
@@ -0,0 +1,573 @@
1
+
2
+ module Xampl
3
+
4
+ class CountingVisitor < Visitor
5
+ attr_accessor :count
6
+
7
+ def initialize
8
+ super
9
+ @count = 0
10
+ end
11
+
12
+ def before_visit(xampl)
13
+ @count += 1
14
+ end
15
+ end
16
+
17
+ class ResetIsChanged < Visitor
18
+ def initialize
19
+ super
20
+ end
21
+
22
+ def start(xampl, verbose=false)
23
+ @verbose = verbose
24
+ if verbose
25
+ puts "RESET IS CHANGED.... #{xampl}"
26
+ puts "SKIPPING!!!" unless xampl.persist_required and xampl.load_needed
27
+ end
28
+
29
+ return if xampl.persist_required and xampl.load_needed
30
+ super(xampl)
31
+ end
32
+
33
+ def before_visit(xampl)
34
+ if xampl.is_changed then
35
+ puts "RESET CHANGED: #{xampl} and continue" if verbose
36
+ xampl.is_changed = false;
37
+ else
38
+ puts "RESET CHANGED: #{xampl} block" if verbose
39
+ @no_children = true
40
+ end
41
+ end
42
+ end
43
+
44
+ class MarkChangedDeep < Visitor
45
+ def initialize
46
+ super
47
+ end
48
+
49
+ def before_visit(xampl)
50
+ xampl.changed if xampl.persist_required
51
+ end
52
+ end
53
+
54
+ class PrettyXML < Visitor
55
+ attr_accessor :ns_to_prefix, :start_body, :body, :out
56
+ attr_accessor :indent, :indent_step
57
+
58
+ @@compact = true
59
+
60
+ def PrettyXML.compact
61
+ @@compact
62
+ end
63
+
64
+ def PrettyXML.compact=(v)
65
+ @@compact = v
66
+ end
67
+
68
+ def initialize(out="", skip=[])
69
+ super()
70
+
71
+ @out = out
72
+ @indent = ""
73
+ @indent_step = " "
74
+ @start_attr_indent = ""
75
+ @was_attr = false
76
+
77
+ @depth = 0
78
+
79
+ @skip = {}
80
+ skip.each{ | ns |
81
+ @skip[ns] = ns
82
+ }
83
+
84
+ @ns_to_prefix = {}
85
+ @start_body = nil
86
+ @body = ""
87
+ @attr_list = nil
88
+
89
+ @insert_comment = nil
90
+ end
91
+
92
+ def short_circuit
93
+ body << @insert_comment if @insert_comment
94
+ @insert_comment = nil
95
+ end
96
+
97
+ def cycle(xampl)
98
+ @short_circuit = true
99
+ @insert_comment = "<!-- CYCLE -->"
100
+ return true
101
+ end
102
+
103
+ def revisit(xampl)
104
+ @insert_comment = "<!-- You've seen this before -->"
105
+ #body << "<!-- You've seen this before -->"
106
+ return true
107
+ end
108
+
109
+ def register_ns(ns)
110
+ if (0 == ns.length) then
111
+ return ""
112
+ end
113
+
114
+ prefix = ns_to_prefix[ns]
115
+ if (nil == prefix) then
116
+ preferred = XamplObject.lookup_preferred_ns_prefix(ns)
117
+ prefix = "" << preferred << ":" if preferred
118
+ prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
119
+ ns_to_prefix[ns] = prefix
120
+ end
121
+ return prefix
122
+ end
123
+
124
+ def attr_esc(s)
125
+ if (s.kind_of? XamplObject)
126
+ return attr_esc(s.to_xml)
127
+ end
128
+
129
+ result = s.to_s.dup
130
+
131
+ result.gsub!("&", "&amp;")
132
+ result.gsub!("<", "&lt;")
133
+ result.gsub!(">", "&gt;")
134
+ result.gsub!("'", "&apos;")
135
+ result.gsub!("\"", "&quot;")
136
+
137
+ return result
138
+ end
139
+
140
+ def content_esc(s)
141
+ result = s.to_s.dup
142
+
143
+ return result if (s.kind_of? XamplObject)
144
+
145
+ result.gsub!("&", "&amp;")
146
+ result.gsub!("<", "&lt;")
147
+
148
+ return result
149
+ end
150
+
151
+ def attribute(xampl)
152
+ @attr_list = []
153
+ pid = nil
154
+ if (nil != xampl.attributes) then
155
+ xampl.attributes.each do |attr_spec|
156
+ unless @skip[attr_spec[2]] then
157
+ value = xampl.instance_variable_get(attr_spec[0])
158
+ if value then
159
+ prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
160
+ @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'")
161
+ end
162
+ end
163
+ end
164
+ @attr_list.sort!
165
+ end
166
+ #@attr_list << " xampl:marker='OKAY: #{ xampl }'"
167
+ end
168
+
169
+ def persist_attribute(xampl)
170
+ @attr_list = []
171
+ if xampl.persist_required then
172
+ index = xampl.indexed_by.to_s
173
+ if index then
174
+ value = xampl.get_the_index
175
+ @attr_list << (" " << index << "='" << attr_esc(value) << "'") if value
176
+ end
177
+ else
178
+ attribute(xampl)
179
+ #@attr_list << " xampl:wtf='WTF??'"
180
+ end
181
+ end
182
+
183
+ def show_attributes(attr_indent)
184
+ if (nil == @attr_list) then
185
+ return ""
186
+ else
187
+ result = @attr_list.join(attr_indent)
188
+ if (0 == result.length) then
189
+ return ""
190
+ else
191
+ return result
192
+ end
193
+ end
194
+ end
195
+
196
+ def do_indent
197
+ return "\n" << @indent << (@indent_step * @depth)
198
+ end
199
+
200
+ def start_element(xampl)
201
+ xampl.accessed
202
+
203
+ if @revisiting or @cycling then
204
+ @short_circuit = true
205
+ persist_attribute(xampl)
206
+ else
207
+ attribute(xampl)
208
+ end
209
+
210
+ tag = xampl.tag
211
+ ns = xampl.ns
212
+ indent = do_indent
213
+ tag_info = "" << "<" << register_ns(ns) << tag
214
+ attr_indent = "" << indent << (" " * tag_info.size)
215
+ unless @start_body then
216
+ @start_attr_indent = attr_indent
217
+ attr_defn = show_attributes(attr_indent)
218
+ @start_body = "" << indent << tag_info << attr_defn
219
+ @was_attr = true if 0 < attr_defn.size
220
+ else
221
+ @body << indent << tag_info << show_attributes(attr_indent)
222
+ end
223
+ end
224
+
225
+ def end_element(xampl)
226
+ tag = xampl.tag
227
+ ns = xampl.ns
228
+ if @@compact then
229
+ @body << "</" << register_ns(ns) << tag << ">"
230
+ else
231
+ @body << do_indent << "</" << register_ns(ns) << tag << ">"
232
+ end
233
+ end
234
+
235
+ def define_ns
236
+ result = ""
237
+ indent = @was_attr
238
+ ns_to_prefix.each do |ns, prefix|
239
+ result = sprintf("%s%s xmlns:%s='%s'", result, indent ? @start_attr_indent : "", prefix[0..-2], ns)
240
+ indent = true
241
+ end
242
+ return result
243
+ end
244
+
245
+ def done
246
+ out << @start_body << define_ns << @body
247
+ end
248
+
249
+ def before_visit_without_content(xampl)
250
+ start_element(xampl)
251
+ @body << "/>"
252
+ end
253
+
254
+ def before_visit_simple_content(xampl)
255
+ start_element(xampl)
256
+ @body << ">"
257
+ @body << content_esc(xampl._content) if xampl._content
258
+ end_element(xampl)
259
+ end
260
+
261
+ def before_visit_data_content(xampl)
262
+ start_element(xampl)
263
+ @body << ">"
264
+ @body << content_esc(xampl._content) if xampl._content
265
+ @depth += 1
266
+ end
267
+
268
+ def after_visit_data_content(xampl)
269
+ @depth += -1
270
+ end_element(xampl)
271
+ end
272
+
273
+ def before_visit_mixed_content(xampl)
274
+ start_element(xampl)
275
+ @body << ">"
276
+ @depth += 1
277
+ end
278
+
279
+ def after_visit_mixed_content(xampl)
280
+ @depth -= 1
281
+ end_element(xampl)
282
+ end
283
+
284
+ def before_visit(xampl)
285
+ unless xampl.kind_of?(XamplObject) and @skip[xampl.ns] then
286
+ if xampl.respond_to? "before_visit_by_element_kind" then
287
+ xampl.before_visit_by_element_kind(self)
288
+ else
289
+ @body << xampl.to_s
290
+ end
291
+ else
292
+ @no_children = true
293
+ end
294
+ end
295
+
296
+ def after_visit(xampl)
297
+ xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
298
+ end
299
+
300
+ def visit_string(string)
301
+ @body << string
302
+ end
303
+ end
304
+
305
+ class CopyXML < Visitor
306
+ attr_accessor :ns_to_prefix, :start_body, :body
307
+
308
+ def CopyXML.copy(root, translate_pids={})
309
+ CopyXML.new.make_copy(root, translate_pids)
310
+ end
311
+
312
+ def make_copy(root, translate_pids)
313
+ @was_attr = false
314
+
315
+ @ns_to_prefix = {}
316
+ @start_body = nil
317
+ @body = ""
318
+ @attr_list = nil
319
+
320
+ @pid_translations_old_to_new = translate_pids
321
+ @pid_translations_new_to_old = translate_pids.invert
322
+
323
+ @persisted_xampl_found = { @current_root.get_the_index => root }
324
+ @copies_by_old_pid = {}
325
+
326
+ while true do
327
+ copy_these = []
328
+
329
+ @persisted_xampl_found.each do | pid, xampl |
330
+ copy_these << xampl unless @copies_by_old_pid[pid]
331
+ end
332
+
333
+ break if 0 == copy_these.length
334
+
335
+ @persisted_xampl_found = {}
336
+ copy_these.each do | xampl |
337
+ @current_root = xampl
338
+ @out = ""
339
+ @copies_by_old_pid[@current_root.get_the_index] = @out
340
+
341
+ copy_xampl(@current_root)
342
+ end
343
+ end
344
+
345
+ return @copies_by_old_pid
346
+ end
347
+
348
+ def copy_xampl(root)
349
+ start(root).done
350
+ end
351
+
352
+ @@base_pid = Time.now.to_i.to_s + "_"
353
+ @@gen_pid = 0
354
+
355
+ def get_the_new_pid(xampl)
356
+ current_pid = xampl.get_the_index
357
+ @persisted_xampl_found[current_pid] = xampl
358
+
359
+ new_pid = @pid_translations_old_to_new[current_pid]
360
+
361
+ unless new_pid then
362
+ @@gen_pid += 1
363
+ new_pid = @@base_pid + @@gen_pid.to_s
364
+
365
+ @pid_translations_old_to_new[current_pid] = new_pid
366
+ @pid_translations_new_to_old[new_pid] = current_pid
367
+ end
368
+
369
+ return new_pid
370
+ end
371
+
372
+ def cycle(xampl)
373
+ raise XamplException.new(:cycle_detected_in_xampl_cluster) unless xampl.kind_of?(XamplPersistedObject)
374
+ return true
375
+ end
376
+
377
+ def revisit(xampl)
378
+ return true
379
+ end
380
+
381
+ def register_ns(ns)
382
+ if (0 == ns.length) then
383
+ return ""
384
+ end
385
+
386
+ prefix = ns_to_prefix[ns]
387
+ if (nil == prefix) then
388
+ preferred = XamplObject.lookup_preferred_ns_prefix(ns)
389
+ prefix = "" << preferred << ":" if preferred
390
+ prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
391
+ ns_to_prefix[ns] = prefix
392
+ end
393
+ return prefix
394
+ end
395
+
396
+ def attr_esc(s)
397
+ if (s.kind_of? XamplObject)
398
+ return attr_esc(s.to_xml)
399
+ end
400
+
401
+ result = s.to_s.dup
402
+
403
+ result.gsub!("&", "&amp;")
404
+ result.gsub!("<", "&lt;")
405
+ result.gsub!(">", "&gt;")
406
+ result.gsub!("'", "&apos;")
407
+ result.gsub!("\"", "&quot;")
408
+
409
+ return result
410
+ end
411
+
412
+ def content_esc(s)
413
+ result = s.to_s.dup
414
+
415
+ return result if (s.kind_of? XamplObject)
416
+
417
+ result.gsub!("&", "&amp;")
418
+ result.gsub!("<", "&lt;")
419
+
420
+ return result
421
+ end
422
+
423
+ def attribute(xampl)
424
+ @attr_list = []
425
+ if (nil != xampl.attributes) then
426
+ xampl.attributes.each{ | attr_spec |
427
+ prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
428
+ value = get_the_new_pid(xampl.instance_variable_get(attr_spec[0]))
429
+ @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
430
+ unless nil == value
431
+ }
432
+ end
433
+ end
434
+
435
+ def persist_attribute(xampl)
436
+ @attr_list = []
437
+ pattr = xampl.indexed_by.to_s
438
+ if (nil != xampl.attributes) then
439
+ xampl.attributes.each{ | attr_spec |
440
+ if pattr == attr_spec[1] then
441
+ prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
442
+ value = xampl.instance_variable_get(attr_spec[0])
443
+ @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
444
+ unless nil == value
445
+ break
446
+ end
447
+ }
448
+ end
449
+ end
450
+
451
+ def show_attributes
452
+ result = @attr_list.join(" ")
453
+ if (0 == result.length) then
454
+ return ""
455
+ else
456
+ return result
457
+ end
458
+ end
459
+
460
+ def start_element(xampl)
461
+ tag = xampl.tag
462
+ ns = xampl.ns
463
+ tag_info = "" << "<" << register_ns(ns) << tag
464
+ unless @start_body then
465
+ attribute(xampl)
466
+ attr_defn = show_attributes
467
+ @start_body = "" << tag_info << attr_defn
468
+ @was_attr = true if 0 < attr_defn.size
469
+ else
470
+ if xampl.persist_required then
471
+ @no_children = true
472
+ persist_attribute(xampl)
473
+ else
474
+ attribute(xampl)
475
+ end
476
+ @body << tag_info << show_attributes
477
+ end
478
+ end
479
+
480
+ def end_element(xampl)
481
+ tag = xampl.tag
482
+ ns = xampl.ns
483
+ @body << "</" << register_ns(ns) << tag << ">"
484
+ end
485
+
486
+ def define_ns
487
+ result = ""
488
+ ns_to_prefix.each{ | ns, prefix |
489
+ result = sprintf("%s xmlns:%s='%s'", result, prefix[0..-2], ns)
490
+ }
491
+ return result
492
+ end
493
+
494
+ def done
495
+ out << @start_body << define_ns << @body
496
+ end
497
+
498
+ def before_visit_without_content(xampl)
499
+ start_element(xampl)
500
+ @body << "/>"
501
+ end
502
+
503
+ def before_visit_simple_content(xampl)
504
+ start_element(xampl)
505
+ if @no_children then
506
+ @body << "/>"
507
+ else
508
+ @body << ">"
509
+ @body << content_esc(xampl._content) if xampl._content
510
+ end_element(xampl)
511
+ end
512
+ end
513
+
514
+ def before_visit_data_content(xampl)
515
+ start_element(xampl)
516
+ if @no_children then
517
+ @body << "/>"
518
+ else
519
+ @body << ">"
520
+ @body << content_esc(xampl._content) if xampl._content
521
+ end
522
+ end
523
+
524
+ def after_visit_data_content(xampl)
525
+ end_element(xampl) unless @no_children
526
+ end
527
+
528
+ def before_visit_mixed_content(xampl)
529
+ if @no_children then
530
+ @body << "/>"
531
+ else
532
+ start_element(xampl)
533
+ @body << ">"
534
+ end
535
+ end
536
+
537
+ def after_visit_mixed_content(xampl)
538
+ end_element(xampl) unless @no_children
539
+ end
540
+
541
+ def before_visit(xampl)
542
+ if xampl.respond_to? "before_visit_by_element_kind" then
543
+ xampl.before_visit_by_element_kind(self)
544
+ else
545
+ @body << xampl.to_s
546
+ end
547
+ end
548
+
549
+ def after_visit(xampl)
550
+ xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
551
+ end
552
+
553
+ def visit_string(string)
554
+ @body << string
555
+ end
556
+ end
557
+
558
+ module XamplObject
559
+ def pp_xml(out="", skip=[])
560
+ PrettyXML.new(out, skip).start(self).done
561
+ end
562
+
563
+ def copy_xampl(root, translate_pids={})
564
+ CopyXML.copy(root, translate_pids)
565
+ end
566
+
567
+ def mark_changed_deep
568
+ MarkChangedDeep.new.start(self)
569
+ end
570
+ end
571
+
572
+ end
573
+