lib/zache.rb in zache-0.4.0 vs lib/zache.rb in zache-0.5.0
- old
+ new
@@ -41,23 +41,33 @@
class Zache
# Makes a new object of the cache.
# "sync" is whether the hash is thread-safe (`true`)
# or not (`false`); it is recommended to leave this parameter untouched,
# unless you really know what you are doing.
- def initialize(sync: true)
+ #
+ # If the <tt>dirty</tt> argument is set to <tt>true</tt>, a previously
+ # calculated result will be returned if it exists.
+ def initialize(sync: true, dirty: false)
@hash = {}
@sync = sync
+ @dirty = dirty
@monitor = Monitor.new
end
# Gets the value from the cache by the provided key. If the value is not
# found in the cache, it will be calculated via the provided block. If
# the block is not given, an exception will be raised. The lifetime
# must be in seconds. The default lifetime is huge, which means that the
# key will never be expired.
- def get(key, lifetime: 2**32)
+ #
+ # If the <tt>dirty</tt> argument is set to <tt>true</tt>, a previously
+ # calculated result will be returned if it exists.
+ def get(key, lifetime: 2**32, dirty: false)
if block_given?
+ if (dirty || @dirty) && locked? && !key_expired?(key) && @hash.key?(key)
+ return @hash[key]
+ end
synchronized { calc(key, lifetime) { yield } }
else
rec = @hash[key]
if key_expired?(key)
@hash.delete(key)
@@ -78,10 +88,15 @@
rec = nil
end
!rec.nil?
end
+ # Is cache currently locked doing something?
+ def locked?
+ !@monitor.mon_try_enter { true }
+ end
+
# Put a value into the cache.
def put(key, value, lifetime: 2**32)
synchronized do
@hash[key] = {
value: value,
@@ -122,10 +137,10 @@
@hash[key][:value]
end
def synchronized
if @sync
- @monitor.synchronize { yield }
+ @monitor.mon_synchronize { yield }
else
yield
end
end