xamplr 1.2.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.
- data/CHANGES.txt +13 -0
- data/LICENSE +3 -0
- data/README.rdoc +26 -0
- data/README.rdoc.orig +118 -0
- data/Rakefile +85 -0
- data/VERSION.yml +4 -0
- data/examples/random-people-shared-addresses/Makefile +16 -0
- data/examples/random-people-shared-addresses/batch-load-users.rb +83 -0
- data/examples/random-people-shared-addresses/find-mentions.rb +47 -0
- data/examples/random-people-shared-addresses/find-people-by-address.rb +104 -0
- data/examples/random-people-shared-addresses/optimise.rb +16 -0
- data/examples/random-people-shared-addresses/people.rb +35 -0
- data/examples/random-people-shared-addresses/query.rb +75 -0
- data/examples/random-people-shared-addresses/query2.rb +73 -0
- data/examples/random-people-shared-addresses/random-names.csv +10000 -0
- data/examples/random-people-shared-addresses/settings.rb +3 -0
- data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
- data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
- data/examples/random-people-shared-addresses/xml/people.xml +14 -0
- data/examples/random-people/Makefile +16 -0
- data/examples/random-people/batch-load-users.rb +61 -0
- data/examples/random-people/optimise.rb +16 -0
- data/examples/random-people/people.rb +22 -0
- data/examples/random-people/query.rb +73 -0
- data/examples/random-people/query2.rb +73 -0
- data/examples/random-people/random-names.csv +10000 -0
- data/examples/random-people/rawtc.rb +91 -0
- data/examples/random-people/settings.rb +3 -0
- data/examples/random-people/what-to-query-on.rb +80 -0
- data/examples/random-people/xampl-gen.rb +36 -0
- data/examples/random-people/xml/people.xml +11 -0
- data/examples/read-testing/Makefile +10 -0
- data/examples/read-testing/load.rb +65 -0
- data/examples/read-testing/read.rb +51 -0
- data/examples/read-testing/rrr.rb +87 -0
- data/examples/read-testing/settings.rb +2 -0
- data/examples/read-testing/xampl-gen.rb +36 -0
- data/examples/read-testing/xml/text.xml +8 -0
- data/examples/tokyo-cabinet-experimental/expt-query.rb +42 -0
- data/examples/tokyo-cabinet-experimental/expt-query2.rb +42 -0
- data/examples/tokyo-cabinet-experimental/expt-query3.rb +41 -0
- data/examples/tokyo-cabinet-experimental/expt-reader.rb +32 -0
- data/examples/tokyo-cabinet-experimental/expt.rb +61 -0
- data/examples/tokyo-cabinet-experimental/xampl-gen.rb +36 -0
- data/examples/tokyo-cabinet-experimental/xml/tcx.xml +6 -0
- data/lib/xampl-generator.rb +3 -0
- data/lib/xampl.rb +3 -0
- data/lib/xamplr-generator.rb +10 -0
- data/lib/xamplr.rb +37 -0
- data/lib/xamplr/README-POSSIBLE-PROBLEMS +5 -0
- data/lib/xamplr/TODO +1 -0
- data/lib/xamplr/exceptions.rb +97 -0
- data/lib/xamplr/from-xml-orig.rb +350 -0
- data/lib/xamplr/from-xml.rb +439 -0
- data/lib/xamplr/gen-elements.xml +6230 -0
- data/lib/xamplr/gen.elements.xml +108 -0
- data/lib/xamplr/generate-elements.rb +15 -0
- data/lib/xamplr/generator.rb +5 -0
- data/lib/xamplr/graphml-out.rb +470 -0
- data/lib/xamplr/handwritten/example.rb +698 -0
- data/lib/xamplr/handwritten/hand-example.rb +533 -0
- data/lib/xamplr/handwritten/test-handwritten.rb +873 -0
- data/lib/xamplr/indexed-array.rb +115 -0
- data/lib/xamplr/mixins.rb +397 -0
- data/lib/xamplr/my.gen.elements.xml +461 -0
- data/lib/xamplr/notifications.rb +57 -0
- data/lib/xamplr/obsolete/fsdb.rb +62 -0
- data/lib/xamplr/persist-to-xml.rb +249 -0
- data/lib/xamplr/persistence.rb +522 -0
- data/lib/xamplr/persistence.rb.more_thread_safe +771 -0
- data/lib/xamplr/persistence.rb.partially_thread_safe +763 -0
- data/lib/xamplr/persister.rb +310 -0
- data/lib/xamplr/persisters/caches.rb +186 -0
- data/lib/xamplr/persisters/caching.rb +172 -0
- data/lib/xamplr/persisters/filesystem.rb +60 -0
- data/lib/xamplr/persisters/in-memory.rb +180 -0
- data/lib/xamplr/persisters/simple.rb +59 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb +641 -0
- data/lib/xamplr/simpleTemplate/danger.rx +4 -0
- data/lib/xamplr/simpleTemplate/obsolete/input-c.r4 +35 -0
- data/lib/xamplr/simpleTemplate/obsolete/play.r6.txt +12 -0
- data/lib/xamplr/simpleTemplate/obsolete/play_more.r6.txt +20 -0
- data/lib/xamplr/simpleTemplate/obsolete/test001.r5 +8 -0
- data/lib/xamplr/simpleTemplate/obsolete/test002.r5 +13 -0
- data/lib/xamplr/simpleTemplate/obsolete/test003.r5 +37 -0
- data/lib/xamplr/simpleTemplate/old/r6.000.rb +122 -0
- data/lib/xamplr/simpleTemplate/old/r6.001.rb +145 -0
- data/lib/xamplr/simpleTemplate/play.r6 +12 -0
- data/lib/xamplr/simpleTemplate/play_more.r6 +20 -0
- data/lib/xamplr/simpleTemplate/play_noblanks.r6 +21 -0
- data/lib/xamplr/simpleTemplate/playq.r6 +16 -0
- data/lib/xamplr/simpleTemplate/r6.rb +87 -0
- data/lib/xamplr/simpleTemplate/simple-template.rb +75 -0
- data/lib/xamplr/templates/child.template +47 -0
- data/lib/xamplr/templates/child_indexed.template +89 -0
- data/lib/xamplr/templates/child_modules.template +5 -0
- data/lib/xamplr/templates/element_classes.template +11 -0
- data/lib/xamplr/templates/element_data.template +282 -0
- data/lib/xamplr/templates/element_empty.template +285 -0
- data/lib/xamplr/templates/element_mixed.template +277 -0
- data/lib/xamplr/templates/element_simple.template +276 -0
- data/lib/xamplr/templates/package.template +26 -0
- data/lib/xamplr/test-support/Makefile +47 -0
- data/lib/xamplr/test-support/bench-cache.rb +80 -0
- data/lib/xamplr/test-support/bench-script.rb +21 -0
- data/lib/xamplr/test-support/bench.rb +116 -0
- data/lib/xamplr/test-support/bench2.rb +132 -0
- data/lib/xamplr/test-support/test-cache.rb +147 -0
- data/lib/xamplr/test-support/test-data/binding.xml +7 -0
- data/lib/xamplr/test-support/test-data/example.xml +14 -0
- data/lib/xamplr/test-support/test-data/internationalization-utf8.txt +1 -0
- data/lib/xamplr/test-support/test-data/labels.xml +37 -0
- data/lib/xamplr/test-support/test-data/labels001.xml +38 -0
- data/lib/xamplr/test-support/test-deep-change.rb +135 -0
- data/lib/xamplr/test-support/test-elements.rb +109 -0
- data/lib/xamplr/test-support/test-indexed-array.rb +169 -0
- data/lib/xamplr/test-support/test-misc.rb +73 -0
- data/lib/xamplr/test-support/test-names.rb +67 -0
- data/lib/xamplr/test-support/test-rollback.rb +106 -0
- data/lib/xamplr/test-support/test.rb +1504 -0
- data/lib/xamplr/to-ruby.rb +220 -0
- data/lib/xamplr/to-xml.rb +158 -0
- data/lib/xamplr/version.rb +67 -0
- data/lib/xamplr/visitor.rb +140 -0
- data/lib/xamplr/visitors.rb +573 -0
- data/lib/xamplr/xampl-generator.rb +533 -0
- data/lib/xamplr/xampl-hand-generated.rb +1535 -0
- data/lib/xamplr/xampl-module.rb +36 -0
- data/lib/xamplr/xampl-object-internals.rb +6 -0
- data/lib/xamplr/xampl-object.rb +202 -0
- data/lib/xamplr/xampl-persisted-object.rb +122 -0
- data/lib/xamplr/xml-text.rb +117 -0
- data/lib/xamplr/xml/document.xml +7 -0
- data/lib/xamplr/xml/elements.xml +101 -0
- data/lib/xamplr/xml/elements000.xml +73 -0
- data/lib/xamplr/xml/example.xml +23 -0
- data/lib/xamplr/xml/options.xml +12 -0
- data/lib/xamplr/xml/uche.xml +38 -0
- data/lib/xamplr/yEd-sample.graphml +300 -0
- data/test/test_helper.rb +10 -0
- data/test/xamplr_test.rb +7 -0
- metadata +245 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
|
|
2
|
+
require "xamplr/persistence"
|
|
3
|
+
|
|
4
|
+
module Xampl
|
|
5
|
+
class Persister
|
|
6
|
+
attr_accessor :name,
|
|
7
|
+
:automatic,
|
|
8
|
+
:block_changes,
|
|
9
|
+
:read_count, :total_read_count,
|
|
10
|
+
:write_count, :total_write_count,
|
|
11
|
+
:total_sync_count, :total_rollback_count,
|
|
12
|
+
:cache_hits, :total_cache_hits,
|
|
13
|
+
:last_write_count,
|
|
14
|
+
:rolled_back
|
|
15
|
+
attr_reader :syncing, :format
|
|
16
|
+
|
|
17
|
+
def initialize(name=nil, format=nil)
|
|
18
|
+
@name = name
|
|
19
|
+
@format = format
|
|
20
|
+
@automatic = false
|
|
21
|
+
@changed = {}
|
|
22
|
+
@cache_hits = 0
|
|
23
|
+
@total_cache_hits = 0
|
|
24
|
+
@read_count = 0
|
|
25
|
+
@total_read_count = 0
|
|
26
|
+
@write_count = 0
|
|
27
|
+
@total_write_count = 0
|
|
28
|
+
@last_write_count = 0
|
|
29
|
+
@total_sync_count = 0
|
|
30
|
+
@total_rollback_count = 0
|
|
31
|
+
@rolled_back = false
|
|
32
|
+
@syncing = false
|
|
33
|
+
|
|
34
|
+
@busy_count = 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def optimise(opts)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def close
|
|
41
|
+
self.sync
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def busy(yes)
|
|
45
|
+
if yes then
|
|
46
|
+
@busy_count += 1
|
|
47
|
+
elsif 0 < @busy_count then
|
|
48
|
+
@busy_count -= 1
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def is_busy
|
|
53
|
+
return 0 < @busy_count
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def introduce(xampl)
|
|
57
|
+
if xampl.introduce_persister(self) then
|
|
58
|
+
cache(xampl)
|
|
59
|
+
end
|
|
60
|
+
has_changed(xampl) if xampl.is_changed
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def has_changed(xampl)
|
|
64
|
+
#raise XamplException.new(:live_across_rollback) if @rolled_back
|
|
65
|
+
# puts "!!!! has_changed #{xampl} #{xampl.get_the_index} -- persist required: #{xampl.persist_required}"
|
|
66
|
+
if xampl.persist_required && xampl.is_changed then
|
|
67
|
+
unless self == xampl.persister
|
|
68
|
+
raise MixedPersisters.new(xampl.persister, self)
|
|
69
|
+
end
|
|
70
|
+
@changed[xampl] = xampl
|
|
71
|
+
# puts "!!!! change recorded ==> #{@changed.size}/#{count_changed} #{@changed.object_id} !!!!"
|
|
72
|
+
# @changed.each{ | thing, ignore |
|
|
73
|
+
# puts " changed: #{thing}, index: #{thing.get_the_index}, changed: #{thing.is_changed}"
|
|
74
|
+
# }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def has_not_changed(xampl)
|
|
79
|
+
# puts "!!!! has_not_changed #{xampl} #{xampl.get_the_index} -- in @changed: #{nil != @changed[xampl]}"
|
|
80
|
+
@changed.delete(xampl) if xampl
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def count_changed
|
|
84
|
+
# @changed.each{ | thing, ignore |
|
|
85
|
+
# puts "changed: #{thing}, index: #{thing.get_the_index}"
|
|
86
|
+
# }
|
|
87
|
+
return @changed.size
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def cache(xampl)
|
|
91
|
+
raise XamplException.new(:unimplemented)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def uncache(xampl)
|
|
95
|
+
raise XamplException.new(:unimplemented)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def clear_cache
|
|
99
|
+
raise XamplException.new(:unimplemented)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def Persister.replace(old_xampl, new_xampl)
|
|
103
|
+
pid = old_xampl.get_the_index
|
|
104
|
+
if old_xampl.persister != @@persister then
|
|
105
|
+
raise MixedPersisters.new(@@persister, old_xampl.persister)
|
|
106
|
+
end
|
|
107
|
+
if new_xampl.persister != @@persister then
|
|
108
|
+
raise MixedPersisters.new(@@persister, new_xampl.persister)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
new_xampl.note_replacing(old_xampl)
|
|
112
|
+
|
|
113
|
+
unless old_xampl.load_needed then
|
|
114
|
+
Xampl.log.warn("Replacing live xampl: #{old_xampl} pid: #{pid}")
|
|
115
|
+
@@persister.uncache(old_xampl)
|
|
116
|
+
old_xampl.invalidate
|
|
117
|
+
end
|
|
118
|
+
new_xampl.pid = nil
|
|
119
|
+
new_xampl.pid = pid
|
|
120
|
+
@@persister.introduce(new_xampl)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def represent(xampl, mentions=[])
|
|
124
|
+
#puts "REPRESENT #{xampl} load needed: #{xampl.load_needed}"
|
|
125
|
+
# return nil if xampl.load_needed
|
|
126
|
+
case xampl.default_persister_format || @format
|
|
127
|
+
when nil, :xml_format then
|
|
128
|
+
return xampl.persist("", mentions)
|
|
129
|
+
when :ruby_format then
|
|
130
|
+
return xampl.to_ruby(mentions)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def realise(representation, target=nil)
|
|
135
|
+
# Normally we'd expect to see the representation in the @format format, but
|
|
136
|
+
# that isn't necessarily the case. Try to work out what the format might be...
|
|
137
|
+
|
|
138
|
+
if representation =~ /^</ then
|
|
139
|
+
return XamplObject.realise_from_xml_string(representation, target)
|
|
140
|
+
else
|
|
141
|
+
XamplObject.from_ruby(representation, target)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def version(stream)
|
|
146
|
+
raise XamplException.new(:unimplemented)
|
|
147
|
+
# catch(:refuse_to_version) do
|
|
148
|
+
# end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def write(xampl)
|
|
152
|
+
raise XamplException.new(:unimplemented)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def read(klass, pid, target=nil)
|
|
156
|
+
raise XamplException.new(:unimplemented)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def query_implemented
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def find_xampl(hint=false)
|
|
164
|
+
if hint then
|
|
165
|
+
return [], "no query made"
|
|
166
|
+
else
|
|
167
|
+
return []
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def lookup(klass, pid)
|
|
172
|
+
#raise XamplException.new(:live_across_rollback) if @rolled_back
|
|
173
|
+
#puts "#{File.basename(__FILE__)} #{__LINE__} LOOKUP:: klass: #{klass} pid: #{pid}"
|
|
174
|
+
|
|
175
|
+
begin
|
|
176
|
+
busy(true)
|
|
177
|
+
xampl = read(klass, pid)
|
|
178
|
+
ensure
|
|
179
|
+
busy(false)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
#puts "#{File.basename(__FILE__)} #{__LINE__} ---> #{ xampl }"
|
|
183
|
+
|
|
184
|
+
return xampl
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def find_known(klass, pid)
|
|
188
|
+
#raise XamplException.new(:live_across_rollback) if @rolled_back
|
|
189
|
+
|
|
190
|
+
xampl = read_from_cache(klass, pid, nil)
|
|
191
|
+
|
|
192
|
+
return xampl
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def lazy_load(target, klass, pid)
|
|
196
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} LAZY_LOAD:: klass: #{klass} pid: #{pid} target: #{target}"
|
|
197
|
+
|
|
198
|
+
xampl = read(klass, pid, target)
|
|
199
|
+
|
|
200
|
+
# puts " LAZY_LOAD --> #{xampl}"
|
|
201
|
+
|
|
202
|
+
return xampl
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def put_changed(msg="")
|
|
206
|
+
puts "Changed::#{msg}:"
|
|
207
|
+
@changed.each { | xampl, ignore | puts " #{xampl.tag} #{xampl.get_the_index}" }
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def do_sync_write
|
|
211
|
+
unchanged_in_changed_list = 0
|
|
212
|
+
@changed.each do |xampl, ignore|
|
|
213
|
+
unchanged_in_changed_list += 1 unless xampl.is_changed
|
|
214
|
+
unless xampl.kind_of?(InvalidXampl) then
|
|
215
|
+
write(xampl)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def sync
|
|
221
|
+
#raise XamplException.new(:live_across_rollback) if @rolled_back
|
|
222
|
+
begin
|
|
223
|
+
#puts "SYNC"
|
|
224
|
+
#puts "SYNC"
|
|
225
|
+
#puts "SYNC changed: #{@changed.size}" if 0 < @changed.size
|
|
226
|
+
#@changed.each do | key, value |
|
|
227
|
+
##puts " #{key.class.name}"
|
|
228
|
+
##puts "key: #{key.class.name}, value: #{value.class.name}"
|
|
229
|
+
#puts key.to_xml
|
|
230
|
+
#end
|
|
231
|
+
#puts "SYNC"
|
|
232
|
+
#puts "SYNC"
|
|
233
|
+
|
|
234
|
+
#if 0 < @changed.size then
|
|
235
|
+
#puts "SYNC changed: #{@changed.size}"
|
|
236
|
+
##caller(0).each do | trace |
|
|
237
|
+
## next if /xamplr/ =~ trace
|
|
238
|
+
## puts " #{trace}"
|
|
239
|
+
## break if /actionpack/ =~ trace
|
|
240
|
+
##end
|
|
241
|
+
#end
|
|
242
|
+
busy(true)
|
|
243
|
+
@syncing = true
|
|
244
|
+
|
|
245
|
+
do_sync_write
|
|
246
|
+
|
|
247
|
+
@changed = {}
|
|
248
|
+
|
|
249
|
+
@total_read_count = @total_read_count + @read_count
|
|
250
|
+
@total_write_count = @total_write_count + @write_count
|
|
251
|
+
@total_cache_hits = @total_cache_hits + @cache_hits
|
|
252
|
+
@total_sync_count = @total_sync_count + 1
|
|
253
|
+
|
|
254
|
+
@read_count = 0
|
|
255
|
+
@last_write_count = @write_count
|
|
256
|
+
@write_count = 0
|
|
257
|
+
|
|
258
|
+
self.sync_done()
|
|
259
|
+
|
|
260
|
+
return @last_write_count
|
|
261
|
+
ensure
|
|
262
|
+
busy(false)
|
|
263
|
+
@syncing = false
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def sync_done
|
|
268
|
+
raise XamplException.new(:unimplemented)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def rollback
|
|
272
|
+
begin
|
|
273
|
+
busy(true)
|
|
274
|
+
|
|
275
|
+
return Xampl.rollback(self)
|
|
276
|
+
ensure
|
|
277
|
+
busy(false)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def rollback_cleanup
|
|
282
|
+
@changed = {}
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def print_stats
|
|
286
|
+
printf("SYNC:: TOTAL cache_hits: %d, reads: %d, writes: %d\n",
|
|
287
|
+
@total_cache_hits, @total_read_count, @total_write_count)
|
|
288
|
+
printf(" cache_hits: %d, reads: %d, last writes: %d\n",
|
|
289
|
+
@cache_hits, @read_count, @last_write_count)
|
|
290
|
+
printf(" syncs: %d\n", @total_sync_count)
|
|
291
|
+
printf(" changed count: %d (%d)\n", count_changed, @changed.size)
|
|
292
|
+
@changed.each do |thing, ignore|
|
|
293
|
+
if thing.is_changed then
|
|
294
|
+
puts " changed: #{thing}, index: #{thing.get_the_index}"
|
|
295
|
+
else
|
|
296
|
+
puts " UNCHANGED: #{thing}, index: #{thing.get_the_index} <<<<<<<<<<<<<<<<<<< BAD!"
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
require "xamplr/persisters/simple"
|
|
303
|
+
require "xamplr/persisters/in-memory"
|
|
304
|
+
require "xamplr/persisters/filesystem"
|
|
305
|
+
|
|
306
|
+
if require 'tokyocabinet' then
|
|
307
|
+
require "xamplr/persisters/tokyo-cabinet"
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module Xampl
|
|
2
|
+
|
|
3
|
+
#TODO -- this is **way** too big!
|
|
4
|
+
#TODO -- FIX THIS PROBLEM
|
|
5
|
+
# increase the default cache size to 2000 (which is way too big, but there is
|
|
6
|
+
# a bug... removing from the cache does not remove from memory, so if a
|
|
7
|
+
# storybook exists that points (even indirectly) at something flushed, the
|
|
8
|
+
# thing flushed is still held in memory. What is needed is for the thing to
|
|
9
|
+
# be invalidated somehow withought DUPLICATES being created when the thing
|
|
10
|
+
# is read again next time)
|
|
11
|
+
|
|
12
|
+
DEFAULT_CAPACITY = 2000
|
|
13
|
+
|
|
14
|
+
class XamplCache
|
|
15
|
+
require 'xamplr/indexed-array'
|
|
16
|
+
|
|
17
|
+
attr_reader :cache, :capacity
|
|
18
|
+
|
|
19
|
+
def initialize(capacity=DEFAULT_CAPACITY)
|
|
20
|
+
@capacity = capacity
|
|
21
|
+
@now = 0
|
|
22
|
+
@size = 0
|
|
23
|
+
@cache = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def size
|
|
27
|
+
#@cache.size
|
|
28
|
+
return @size
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def delete(key)
|
|
32
|
+
@cache.delete(key)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def limit
|
|
36
|
+
victim = nil
|
|
37
|
+
actual_victim = nil
|
|
38
|
+
min = 1 + @now
|
|
39
|
+
@size = 0
|
|
40
|
+
@cache.each do |key, pair|
|
|
41
|
+
possibility = pair[0]
|
|
42
|
+
if (not possibility.load_needed) and pair[1] < min then
|
|
43
|
+
@size += 1
|
|
44
|
+
victim = key
|
|
45
|
+
actual_victim = possibility
|
|
46
|
+
min = pair[1]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
#puts
|
|
50
|
+
#puts
|
|
51
|
+
#puts "REMOVE FROM CACHE(XamplCache): victim: #{victim}, actual: #{actual_victim}"
|
|
52
|
+
#puts " size: #{@size}, physical size: #{@cache.size}"
|
|
53
|
+
#puts
|
|
54
|
+
#puts
|
|
55
|
+
#@cache.delete(victim)
|
|
56
|
+
actual_victim.force_load if actual_victim
|
|
57
|
+
#puts ">>>>>>> #{actual_victim.load_needed} #{actual_victim.class.name}" if actual_victim
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def fetch(key, default_value=nil)
|
|
61
|
+
pair = @cache[key]
|
|
62
|
+
if pair then
|
|
63
|
+
pair[1] = (@now += 1)
|
|
64
|
+
return pair[0]
|
|
65
|
+
else
|
|
66
|
+
return default_value
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def store(key, value)
|
|
71
|
+
if (@capacity <= @size) then
|
|
72
|
+
self.limit
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
pair = @cache[key]
|
|
76
|
+
if pair then
|
|
77
|
+
pair[0] = value
|
|
78
|
+
pair[1] = (@now += 1)
|
|
79
|
+
else
|
|
80
|
+
@cache[key] = [value, (@now += 1)]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
return value
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def print(out = "")
|
|
87
|
+
out << "Cache (standard) with capacity: #{@capacity}, current size: #{@size}\n"
|
|
88
|
+
@cache.each do |key, pair|
|
|
89
|
+
out << sprintf(" key: '%s', value: '%s', accessed: %s\n",
|
|
90
|
+
key, pair[0], pair[1])
|
|
91
|
+
end
|
|
92
|
+
out
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
alias [] fetch
|
|
96
|
+
alias []= store
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class XamplCacheLFU
|
|
100
|
+
require 'xamplr/indexed-array'
|
|
101
|
+
|
|
102
|
+
attr_reader :cache, :capacity
|
|
103
|
+
|
|
104
|
+
def initialize(capacity=DEFAULT_CAPACITY)
|
|
105
|
+
@capacity = capacity
|
|
106
|
+
@accesses = 0
|
|
107
|
+
@size = 0
|
|
108
|
+
@cache = {}
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def size
|
|
112
|
+
#@cache.size
|
|
113
|
+
@size
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def delete(key)
|
|
117
|
+
@cache.delete(key)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def limit
|
|
121
|
+
victim = nil
|
|
122
|
+
actual_victim = nil
|
|
123
|
+
min = 1 + @accesses
|
|
124
|
+
live = 0
|
|
125
|
+
@cache.each do |key, pair|
|
|
126
|
+
pair[1] -= 1
|
|
127
|
+
possibility = pair[0]
|
|
128
|
+
if (not possibility.load_needed) and pair[1] < min then
|
|
129
|
+
live += 1
|
|
130
|
+
victim = key
|
|
131
|
+
actual_victim = possibility
|
|
132
|
+
min = pair[1]
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
#puts
|
|
136
|
+
#puts
|
|
137
|
+
#puts "REMOVE FROM CACHE(XamplCacheLFU): victim: #{victim}, actual: #{actual_victim} -- live: #{live}, size: #{@size}"
|
|
138
|
+
#puts
|
|
139
|
+
#puts
|
|
140
|
+
#@cache.delete(victim)
|
|
141
|
+
actual_victim.force_load if actual_victim
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def fetch(key, default_value=nil)
|
|
145
|
+
@accesses += 1
|
|
146
|
+
|
|
147
|
+
pair = @cache[key]
|
|
148
|
+
if pair then
|
|
149
|
+
pair[1] += 1
|
|
150
|
+
return pair[0]
|
|
151
|
+
else
|
|
152
|
+
return default_value
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def store(key, value)
|
|
157
|
+
@accesses += 1
|
|
158
|
+
|
|
159
|
+
if (@capacity <= @size) then
|
|
160
|
+
self.limit
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
pair = @cache[key]
|
|
164
|
+
if pair then
|
|
165
|
+
pair[0] = value
|
|
166
|
+
pair[1] += 1
|
|
167
|
+
else
|
|
168
|
+
@cache[key] = [value, 1]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
return value
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def print(out = "")
|
|
175
|
+
out << "Cache (LFU) with capacity: #{@capacity}, current size: #{@size}\n"
|
|
176
|
+
@cache.each do |key, pair|
|
|
177
|
+
out << sprintf(" key: '%s', value: '%s', count: %s\n",
|
|
178
|
+
key, pair[0], pair[1])
|
|
179
|
+
end
|
|
180
|
+
out
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
alias [] fetch
|
|
184
|
+
alias []= store
|
|
185
|
+
end
|
|
186
|
+
end
|