zache 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/lib/zache.rb +18 -3
- data/test/test_zache.rb +29 -0
- data/zache.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1b2d35db53d59daaf2d281eb08c0381bc0d7302cbab9d817c39b22e8aec93b0
|
4
|
+
data.tar.gz: db7d2212ceea4cc6f7e2f8feb5954b720c16ed0fd12fab56ea50c2d2fed5621c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63ffba8c6c32c96aabbf443b6faa94bcbe4b8e5a6fb2f2a39ac36bdc6a68906c7d0f46a8266d10d485ed4ec463104d38f65bfed4cb3bf246a8d4cfdbe2da545e
|
7
|
+
data.tar.gz: 9b46a730a46d6a177092b1499f3cd020796eb4c63782a17cb0e8c54ad55e1fabbaf9b9d96ff703ab41e502e41dcf8d338a184e9fad4aae29eaddd95a19555938
|
data/.rubocop.yml
CHANGED
data/lib/zache.rb
CHANGED
@@ -43,9 +43,13 @@ class Zache
|
|
43
43
|
# "sync" is whether the hash is thread-safe (`true`)
|
44
44
|
# or not (`false`); it is recommended to leave this parameter untouched,
|
45
45
|
# unless you really know what you are doing.
|
46
|
-
|
46
|
+
#
|
47
|
+
# If the <tt>dirty</tt> argument is set to <tt>true</tt>, a previously
|
48
|
+
# calculated result will be returned if it exists.
|
49
|
+
def initialize(sync: true, dirty: false)
|
47
50
|
@hash = {}
|
48
51
|
@sync = sync
|
52
|
+
@dirty = dirty
|
49
53
|
@monitor = Monitor.new
|
50
54
|
end
|
51
55
|
|
@@ -54,8 +58,14 @@ class Zache
|
|
54
58
|
# the block is not given, an exception will be raised. The lifetime
|
55
59
|
# must be in seconds. The default lifetime is huge, which means that the
|
56
60
|
# key will never be expired.
|
57
|
-
|
61
|
+
#
|
62
|
+
# If the <tt>dirty</tt> argument is set to <tt>true</tt>, a previously
|
63
|
+
# calculated result will be returned if it exists.
|
64
|
+
def get(key, lifetime: 2**32, dirty: false)
|
58
65
|
if block_given?
|
66
|
+
if (dirty || @dirty) && locked? && !key_expired?(key) && @hash.key?(key)
|
67
|
+
return @hash[key]
|
68
|
+
end
|
59
69
|
synchronized { calc(key, lifetime) { yield } }
|
60
70
|
else
|
61
71
|
rec = @hash[key]
|
@@ -80,6 +90,11 @@ class Zache
|
|
80
90
|
!rec.nil?
|
81
91
|
end
|
82
92
|
|
93
|
+
# Is cache currently locked doing something?
|
94
|
+
def locked?
|
95
|
+
!@monitor.mon_try_enter { true }
|
96
|
+
end
|
97
|
+
|
83
98
|
# Put a value into the cache.
|
84
99
|
def put(key, value, lifetime: 2**32)
|
85
100
|
synchronized do
|
@@ -124,7 +139,7 @@ class Zache
|
|
124
139
|
|
125
140
|
def synchronized
|
126
141
|
if @sync
|
127
|
-
@monitor.
|
142
|
+
@monitor.mon_synchronize { yield }
|
128
143
|
else
|
129
144
|
yield
|
130
145
|
end
|
data/test/test_zache.rb
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
require 'minitest/autorun'
|
26
26
|
require 'threads'
|
27
|
+
require 'timeout'
|
27
28
|
require_relative '../lib/zache'
|
28
29
|
|
29
30
|
# Cache test.
|
@@ -168,4 +169,32 @@ class ZacheTest < Minitest::Test
|
|
168
169
|
cache = Zache.new
|
169
170
|
cache.get(:first) { cache.get(:second) { cache.get(:third) { 1 } } }
|
170
171
|
end
|
172
|
+
|
173
|
+
def test_calculates_only_once
|
174
|
+
cache = Zache.new
|
175
|
+
long = Thread.start do
|
176
|
+
cache.get(:x) do
|
177
|
+
sleep 0.5
|
178
|
+
'first'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
sleep 0.1
|
182
|
+
assert(cache.locked?)
|
183
|
+
cache.get(:x) { 'second' }
|
184
|
+
assert(!cache.locked?)
|
185
|
+
long.kill
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_returns_dirty_result
|
189
|
+
cache = Zache.new
|
190
|
+
cache.get(:first, lifetime: 10) { 1 }
|
191
|
+
long = Thread.start do
|
192
|
+
cache.get(:first) { sleep 1000 }
|
193
|
+
end
|
194
|
+
sleep 0.1
|
195
|
+
Timeout.timeout(1) do
|
196
|
+
assert_equal(1, cache.get(:first, dirty: true) { 2 })
|
197
|
+
end
|
198
|
+
long.kill
|
199
|
+
end
|
171
200
|
end
|
data/zache.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.rubygems_version = '2.3.3'
|
32
32
|
s.required_ruby_version = '>=2.3'
|
33
33
|
s.name = 'zache'
|
34
|
-
s.version = '0.
|
34
|
+
s.version = '0.5.0'
|
35
35
|
s.license = 'MIT'
|
36
36
|
s.summary = 'In-memory Cache'
|
37
37
|
s.description = 'Zero-footprint in-memory thread-safe cache'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|