Module: Archipelago::Hashish::CachedHashish
- Includes:
- Current::Synchronized
- Included in:
- BerkeleyHashish, DumpHashish
- Defined in:
- lib/archipelago/hashish.rb
Overview
In essence a persistence backed Hash (with certain BTree behaviours).
Will cache everything including timestamps for last modification in normal Hashes, but keep everything stored in a persistency backer defined by the subclass.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Simply get the value for the
key
. -
#[]=(key, value) ⇒ Object
Insert
value
underkey
. -
#changed?(key, value) ⇒ Boolean
Returns true if what
key
points to is no longervalue
. -
#close! ⇒ Object
Close the persistent backers behind this CachedHashish.
-
#db_include? ⇒ Boolean
Returns whether the persistent backer contains
key
. -
#delete(key) ⇒ Object
Delete
key
and its value and timestamp. -
#do_delete_from_persistence(serialized_key) ⇒ Object
Actually deletes
serialized_key
from the persistent backer. -
#do_get_from_db(serialized_key) ⇒ Object
Will perform an actual fetching of
serialized_key
from the persistent backer. -
#do_get_timestamp_from_db(serialized_key) ⇒ Object
Get the serialized timestamp for
serialized_key
from the persistent backer. -
#do_write_to_db(key, serialized_key, serialized_value, timestamp) ⇒ Object
Actually writes
key
serialized asserialized_key
anserialized_value
to the db, andtimestamp
to the timestamp db. -
#each(callable) ⇒ Object
Will do
callable
.call(key, value) for each key-and-value pair in this Hashish. -
#first ⇒ Object
Get the first key/value pair from our cache tree.
-
#forget(key) ⇒ Object
Forget the given
key
in the cache tree. -
#get_deep_clone(key) ⇒ Object
Returns a deep ( Marshal.load(Marshal.dump(o)) ) clone of the object represented by
key
. -
#get_from_db(key) ⇒ Object
Read
key
from db and if it is found put it in the cache Hash. -
#include?(key) ⇒ Boolean
Returns true if this BerkeleyHashish include
key
. -
#initialize_cached_hashish ⇒ Object
Initializes the cache hashes for this CachedHashish.
-
#last ⇒ Object
Get the last key/value pair from our cache tree.
-
#store_if_changed(key) ⇒ Object
Stores whatever is under
key
if it is not the same as whats in the persistent db - if thekey
actually has a representation in the db. -
#timestamp(key) ⇒ Object
Returns the last time the value under
key
was changed. - #without_lock(&block) ⇒ Object
-
#write_to_db(key, serialized_key, serialized_value, value) ⇒ Object
Write
key
, serialized asserialized_key
andserialized_value
to the db.
Methods included from Current::Synchronized
#lock_on, #mon_check_owner, #synchronize_on, #unlock_on
Instance Method Details
#[](key) ⇒ Object
Simply get the value for the key
.
Will call value.load_hook and send it a block that does the actuall insertion of the value into the live hash if value.respond_to?(:load_hook) if the value didnt exist in the live hash yet.
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/archipelago/hashish.rb', line 121 def [](key) synchronize_on(key) do value = @content[key] return value if value return get_from_db(key) end end |
#[]=(key, value) ⇒ Object
Insert value
under key
.
Will call value.save_hook(old_value) and send it a block that does the actual saving if value.respond_to?(:save_hook).
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/archipelago/hashish.rb', line 146 def []=(key, value) synchronize_on(key, @unlocked_thread != Thread.current) do @content[key] = value write_to_db(key, Marshal.dump(key), Marshal.dump(value), value) return value end end |
#changed?(key, value) ⇒ Boolean
Returns true if what key
points to is no longer value
.
41 42 43 |
# File 'lib/archipelago/hashish.rb', line 41 def changed?(key, value) raise "You have to implement me!" end |
#close! ⇒ Object
Close the persistent backers behind this CachedHashish.
63 64 65 |
# File 'lib/archipelago/hashish.rb', line 63 def close! raise "You have to implement me!" end |
#db_include? ⇒ Boolean
Returns whether the persistent backer contains key
.
69 70 71 |
# File 'lib/archipelago/hashish.rb', line 69 def db_include? raise "You have to implement me!" end |
#delete(key) ⇒ Object
Delete key
and its value and timestamp.
209 210 211 212 213 214 215 216 217 218 |
# File 'lib/archipelago/hashish.rb', line 209 def delete(key) synchronize_on(key, @unlocked_thread != Thread.current) do serialized_key = Marshal.dump(key) @content.delete(key) @timestamps.delete(key) do_delete_from_persistence(serialized_key) end end |
#do_delete_from_persistence(serialized_key) ⇒ Object
Actually deletes serialized_key
from the persistent backer.
81 82 83 |
# File 'lib/archipelago/hashish.rb', line 81 def do_delete_from_persistence(serialized_key) raise "You have to implement me!" end |
#do_get_from_db(serialized_key) ⇒ Object
Will perform an actual fetching of serialized_key
from the persistent backer.
75 76 77 |
# File 'lib/archipelago/hashish.rb', line 75 def do_get_from_db(serialized_key) raise "You have to implement me!" end |
#do_get_timestamp_from_db(serialized_key) ⇒ Object
Get the serialized timestamp for serialized_key
from the persistent backer.
47 48 49 |
# File 'lib/archipelago/hashish.rb', line 47 def (serialized_key) raise "You have to implement me!" end |
#do_write_to_db(key, serialized_key, serialized_value, timestamp) ⇒ Object
Actually writes key
serialized as serialized_key
an serialized_value
to the db, and timestamp
to the timestamp db.
Used by write_to_db.
57 58 59 |
# File 'lib/archipelago/hashish.rb', line 57 def do_write_to_db(key, serialized_key, serialized_value, ) raise "You have to implement me!" end |
#each(callable) ⇒ Object
Will do callable
.call(key, value) for each key-and-value pair in this Hashish.
NB: This is totaly thread-unsafe, only do this for management or rescue!
91 92 93 |
# File 'lib/archipelago/hashish.rb', line 91 def each(callable) raise "You have to implement me!" end |
#first ⇒ Object
Get the first key/value pair from our cache tree.
97 98 99 |
# File 'lib/archipelago/hashish.rb', line 97 def first @content.first end |
#forget(key) ⇒ Object
Forget the given key
in the cache tree.
109 110 111 112 |
# File 'lib/archipelago/hashish.rb', line 109 def forget(key) @content.delete(key) @timestamps.delete(key) end |
#get_deep_clone(key) ⇒ Object
Returns a deep ( Marshal.load(Marshal.dump(o)) ) clone of the object represented by key
.
195 196 197 |
# File 'lib/archipelago/hashish.rb', line 195 def get_deep_clone(key) return Marshal.load(Marshal.dump(@content[key])) end |
#get_from_db(key) ⇒ Object
Read key
from db and if it is found put it in the cache Hash.
Will call value.load_hook and send it a block that does the actuall insertion of the value into the live hash if value.respond_to?(:load_hook).
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/archipelago/hashish.rb', line 227 def get_from_db(key) serialized_key = Marshal.dump(key) serialized_value = do_get_from_db(serialized_key) return nil unless serialized_value value = Marshal.load(serialized_value) if value.respond_to?(:load_hook) value.load_hook do @content[key] = value end else @content[key] = value end return value end |
#include?(key) ⇒ Boolean
Returns true if this BerkeleyHashish include key
.
245 246 247 |
# File 'lib/archipelago/hashish.rb', line 245 def include?(key) @content.include?(key) || db_include?(key) end |
#initialize_cached_hashish ⇒ Object
Initializes the cache hashes for this CachedHashish.
201 202 203 204 205 |
# File 'lib/archipelago/hashish.rb', line 201 def initialize_cached_hashish @content = RBTree.new @timestamps = {} @unlocked_thread = nil end |
#last ⇒ Object
Get the last key/value pair from our cache tree.
103 104 105 |
# File 'lib/archipelago/hashish.rb', line 103 def last @content.last end |
#store_if_changed(key) ⇒ Object
Stores whatever is under key
if it is not the same as whats in the persistent db - if the key
actually has a representation in the db.
Will call value.save_hook(old_value) and send it a block that does the actual saving if value.respond_to?(:save_hook) and a save is actually performed.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/archipelago/hashish.rb', line 167 def store_if_changed(key) synchronize_on(key) do value = @content[key] if value.respond_to?(:dirty?) if value.dirty? serialized_value = Marshal.dump(value) serialized_key = Marshal.dump(key) write_to_db(key, serialized_key, serialized_value, value) value.is_clean! if value.respond_to?(:is_clean!) end else serialized_value = Marshal.dump(value) serialized_key = Marshal.dump(key) write_to_db(key, serialized_key, serialized_value, value) if changed?(serialized_key, serialized_value) end end end |
#timestamp(key) ⇒ Object
Returns the last time the value under key
was changed.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/archipelago/hashish.rb', line 251 def (key) synchronize_on(key) do = @timestamps[key] return if serialized_key = Marshal.dump(key) = (serialized_key) return nil unless = Marshal.load() @timestamps[key] = return end end |
#without_lock(&block) ⇒ Object
131 132 133 134 135 136 137 138 |
# File 'lib/archipelago/hashish.rb', line 131 def without_lock(&block) @unlocked_thread = Thread.current begin yield ensure @unlocked_thread = nil end end |
#write_to_db(key, serialized_key, serialized_value, value) ⇒ Object
Write key
, serialized as serialized_key
and serialized_value
to the db.
Will call value.save_hook(old_value) and send it a block that does the actual saving if value.respond_to?(:save_hook).
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/archipelago/hashish.rb', line 275 def write_to_db(key, serialized_key, serialized_value, value) if value.respond_to?(:save_hook) old_serialized_value = do_get_from_db(serialized_key) old_value = old_serialized_value ? Marshal.load(old_serialized_value) : nil value.save_hook(old_value) do now = Time.now do_write_to_db(key, serialized_key, serialized_value, now) @timestamps[key] = now end else now = Time.now do_write_to_db(key, serialized_key, serialized_value, now) @timestamps[key] = now end end |