sin_lru_redux 2.0.1 → 2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +68 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +17 -18
- data/README.md +21 -142
- data/Rakefile +1 -1
- data/lib/lru_redux/cache.rb +76 -46
- data/lib/lru_redux/ttl/cache.rb +126 -101
- data/lib/lru_redux/util/safe_sync.rb +2 -0
- data/lib/lru_redux/version.rb +1 -1
- metadata +10 -20
- data/.github/workflows/lint.yml +0 -19
- data/.github/workflows/test.yml +0 -21
- data/.gitignore +0 -19
- data/Gemfile +0 -19
- data/Guardfile +0 -6
- data/bench/bench.rb +0 -46
- data/bench/bench_ttl.rb +0 -35
- data/sin_lru_redux.gemspec +0 -35
- data/test/cache_test.rb +0 -146
- data/test/thread_safe_cache_test.rb +0 -19
- data/test/ttl/cache_test.rb +0 -93
- data/test/ttl/thread_safe_cache_test.rb +0 -20
data/lib/lru_redux/ttl/cache.rb
CHANGED
@@ -8,12 +8,13 @@ module LruRedux
|
|
8
8
|
def initialize(*args)
|
9
9
|
max_size, ttl, ignore_nil = args
|
10
10
|
|
11
|
+
max_size ||= 1000
|
11
12
|
ttl ||= :none
|
12
13
|
ignore_nil ||= false
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
validate_max_size!(max_size)
|
16
|
+
validate_ttl!(ttl)
|
17
|
+
validate_ignore_nil!(ignore_nil)
|
17
18
|
|
18
19
|
@max_size = max_size
|
19
20
|
@ttl = ttl
|
@@ -22,64 +23,59 @@ module LruRedux
|
|
22
23
|
@data_ttl = {}
|
23
24
|
end
|
24
25
|
|
25
|
-
def max_size=(
|
26
|
-
|
26
|
+
def max_size=(new_max_size)
|
27
|
+
new_max_size ||= @max_size
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
@max_size = max_size
|
29
|
+
validate_max_size!(new_max_size)
|
31
30
|
|
31
|
+
@max_size = new_max_size
|
32
32
|
resize
|
33
33
|
end
|
34
34
|
|
35
|
-
def ttl=(
|
36
|
-
|
37
|
-
raise ArgumentError.new(:ttl) unless valid_ttl?(ttl)
|
35
|
+
def ttl=(new_ttl)
|
36
|
+
new_ttl ||= @ttl
|
38
37
|
|
39
|
-
|
38
|
+
validate_ttl!(new_ttl)
|
40
39
|
|
41
|
-
|
40
|
+
@ttl = new_ttl
|
41
|
+
evict_expired
|
42
42
|
end
|
43
43
|
|
44
|
-
def ignore_nil=(
|
45
|
-
|
46
|
-
raise ArgumentError.new(:ignore_nil) unless valid_ignore_nil?(ignore_nil)
|
44
|
+
def ignore_nil=(new_ignore_nil)
|
45
|
+
new_ignore_nil ||= @ignore_nil
|
47
46
|
|
48
|
-
|
47
|
+
validate_ignore_nil!(new_ignore_nil)
|
48
|
+
|
49
|
+
@ignore_nil = new_ignore_nil
|
50
|
+
evict_nil
|
49
51
|
end
|
50
52
|
|
51
53
|
def getset(key)
|
52
|
-
|
54
|
+
evict_expired
|
55
|
+
|
56
|
+
key_found = true
|
57
|
+
value = @data_lru.delete(key) { key_found = false }
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
if key_found
|
60
|
+
@data_ttl.delete(key)
|
61
|
+
@data_ttl[key] = Time.now.to_f
|
57
62
|
@data_lru[key] = value
|
58
63
|
else
|
59
64
|
result = yield
|
60
|
-
|
61
|
-
if !result.nil? || !@ignore_nil
|
62
|
-
@data_lru[key] = result
|
63
|
-
@data_ttl[key] = Time.now.to_f
|
64
|
-
|
65
|
-
if @data_lru.size > @max_size
|
66
|
-
key, _ = @data_lru.first
|
67
|
-
|
68
|
-
@data_ttl.delete(key)
|
69
|
-
@data_lru.delete(key)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
65
|
+
store_item(key, result)
|
73
66
|
result
|
74
67
|
end
|
75
68
|
end
|
76
69
|
|
77
70
|
def fetch(key)
|
78
|
-
|
71
|
+
evict_expired
|
79
72
|
|
80
|
-
|
81
|
-
value = @data_lru.delete(key) {
|
82
|
-
|
73
|
+
key_found = true
|
74
|
+
value = @data_lru.delete(key) { key_found = false }
|
75
|
+
|
76
|
+
if key_found
|
77
|
+
@data_ttl.delete(key)
|
78
|
+
@data_ttl[key] = Time.now.to_f
|
83
79
|
@data_lru[key] = value
|
84
80
|
else
|
85
81
|
yield if block_given? # rubocop:disable Style/IfInsideElse
|
@@ -87,71 +83,55 @@ module LruRedux
|
|
87
83
|
end
|
88
84
|
|
89
85
|
def [](key)
|
90
|
-
|
86
|
+
evict_expired
|
91
87
|
|
92
|
-
|
93
|
-
value = @data_lru.delete(key) {
|
94
|
-
|
95
|
-
end
|
88
|
+
key_found = true
|
89
|
+
value = @data_lru.delete(key) { key_found = false }
|
90
|
+
return unless key_found
|
96
91
|
|
97
|
-
def []=(key, val)
|
98
|
-
ttl_evict
|
99
|
-
|
100
|
-
@data_lru.delete(key)
|
101
92
|
@data_ttl.delete(key)
|
102
|
-
|
103
|
-
@data_lru[key] = val
|
104
93
|
@data_ttl[key] = Time.now.to_f
|
94
|
+
@data_lru[key] = value
|
95
|
+
end
|
105
96
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
@data_ttl.delete(key)
|
110
|
-
@data_lru.delete(key)
|
111
|
-
end
|
97
|
+
def []=(key, val)
|
98
|
+
evict_expired
|
112
99
|
|
113
|
-
val
|
100
|
+
store_item(key, val)
|
114
101
|
end
|
115
102
|
|
116
103
|
def each(&block)
|
117
|
-
|
104
|
+
evict_expired
|
118
105
|
|
119
|
-
|
120
|
-
array.reverse!.each(&block)
|
106
|
+
@data_lru.to_a.reverse_each(&block)
|
121
107
|
end
|
122
|
-
|
123
|
-
# used further up the chain, non thread safe each
|
124
108
|
alias_method :each_unsafe, :each
|
125
109
|
|
126
110
|
def to_a
|
127
|
-
|
111
|
+
evict_expired
|
128
112
|
|
129
|
-
|
130
|
-
array.reverse!
|
113
|
+
@data_lru.to_a.reverse
|
131
114
|
end
|
132
115
|
|
133
116
|
def values
|
134
|
-
|
117
|
+
evict_expired
|
135
118
|
|
136
|
-
|
137
|
-
vals.reverse!
|
119
|
+
@data_lru.values.reverse
|
138
120
|
end
|
139
121
|
|
140
122
|
def delete(key)
|
141
|
-
|
123
|
+
evict_expired
|
142
124
|
|
143
125
|
@data_ttl.delete(key)
|
144
126
|
@data_lru.delete(key)
|
145
127
|
end
|
146
|
-
|
147
128
|
alias_method :evict, :delete
|
148
129
|
|
149
130
|
def key?(key)
|
150
|
-
|
131
|
+
evict_expired
|
151
132
|
|
152
133
|
@data_lru.key?(key)
|
153
134
|
end
|
154
|
-
|
155
135
|
alias_method :has_key?, :key?
|
156
136
|
|
157
137
|
def clear
|
@@ -159,65 +139,110 @@ module LruRedux
|
|
159
139
|
@data_lru.clear
|
160
140
|
end
|
161
141
|
|
162
|
-
def expire
|
163
|
-
ttl_evict
|
164
|
-
end
|
165
|
-
|
166
142
|
def count
|
167
143
|
@data_lru.size
|
168
144
|
end
|
169
145
|
|
170
|
-
|
146
|
+
def expire
|
147
|
+
evict_expired
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
171
151
|
|
172
|
-
#
|
152
|
+
# For cache validation only, ensure all is valid
|
173
153
|
def valid?
|
174
154
|
@data_lru.size == @data_ttl.size
|
175
155
|
end
|
176
156
|
|
177
|
-
def
|
178
|
-
|
157
|
+
def validate_max_size!(max_size)
|
158
|
+
unless max_size.is_a?(Numeric)
|
159
|
+
raise ArgumentError.new(<<~ERROR)
|
160
|
+
Invalid max_size: #{max_size.inspect}
|
161
|
+
max_size must be a number.
|
162
|
+
ERROR
|
163
|
+
end
|
164
|
+
return if max_size >= 1
|
179
165
|
|
180
|
-
|
181
|
-
|
166
|
+
raise ArgumentError.new(<<~ERROR)
|
167
|
+
Invalid max_size: #{max_size.inspect}
|
168
|
+
max_size must be greater than or equal to 1.
|
169
|
+
ERROR
|
170
|
+
end
|
182
171
|
|
183
|
-
|
184
|
-
|
185
|
-
@data_lru.delete(key)
|
172
|
+
def validate_ttl!(ttl)
|
173
|
+
return if ttl == :none
|
186
174
|
|
187
|
-
|
175
|
+
unless ttl.is_a?(Numeric)
|
176
|
+
raise ArgumentError.new(<<~ERROR)
|
177
|
+
Invalid ttl: #{ttl.inspect}
|
178
|
+
ttl must be a number.
|
179
|
+
ERROR
|
188
180
|
end
|
181
|
+
return if ttl >= 0
|
182
|
+
|
183
|
+
raise ArgumentError.new(<<~ERROR)
|
184
|
+
Invalid ttl: #{ttl.inspect}
|
185
|
+
ttl must be greater than or equal to 0.
|
186
|
+
ERROR
|
187
|
+
end
|
188
|
+
|
189
|
+
def validate_ignore_nil!(ignore_nil)
|
190
|
+
return if [true, false].include?(ignore_nil)
|
191
|
+
|
192
|
+
raise ArgumentError.new("Invalid ignore_nil: #{ignore_nil.inspect}")
|
189
193
|
end
|
190
194
|
|
191
195
|
def resize
|
192
|
-
|
196
|
+
evict_expired
|
197
|
+
evict_if_exceeded
|
198
|
+
end
|
193
199
|
|
194
|
-
|
195
|
-
|
200
|
+
def evict_expired
|
201
|
+
return if @ttl == :none
|
196
202
|
|
197
|
-
|
203
|
+
expiration_threshold = Time.now.to_f - @ttl
|
204
|
+
key, time = @data_ttl.first
|
205
|
+
until time.nil? || time > expiration_threshold
|
198
206
|
@data_lru.delete(key)
|
207
|
+
@data_ttl.delete(key)
|
208
|
+
key, time = @data_ttl.first
|
199
209
|
end
|
200
210
|
end
|
201
211
|
|
202
|
-
|
212
|
+
def evict_if_exceeded
|
213
|
+
evict_least_recently_used while @data_lru.size > @max_size
|
214
|
+
end
|
203
215
|
|
204
|
-
def
|
205
|
-
return
|
216
|
+
def evict_least_recently_used
|
217
|
+
return if @data_lru.empty?
|
206
218
|
|
207
|
-
|
219
|
+
oldest_key, _value = @data_lru.first
|
220
|
+
@data_lru.delete(oldest_key)
|
221
|
+
@data_ttl.delete(oldest_key)
|
208
222
|
end
|
209
223
|
|
210
|
-
def
|
211
|
-
return
|
212
|
-
return true if ttl.is_a?(Numeric) && ttl >= 0
|
224
|
+
def evict_nil
|
225
|
+
return unless @ignore_nil
|
213
226
|
|
214
|
-
|
227
|
+
@data_lru.reject! do |key, value|
|
228
|
+
if value.nil?
|
229
|
+
@data_ttl.delete(key)
|
230
|
+
true
|
231
|
+
else
|
232
|
+
false
|
233
|
+
end
|
234
|
+
end
|
215
235
|
end
|
216
236
|
|
217
|
-
def
|
218
|
-
|
219
|
-
|
220
|
-
|
237
|
+
def store_item(key, value)
|
238
|
+
@data_lru.delete(key)
|
239
|
+
@data_ttl.delete(key)
|
240
|
+
if !value.nil? || !@ignore_nil
|
241
|
+
@data_lru[key] = value
|
242
|
+
@data_ttl[key] = Time.now.to_f
|
243
|
+
end
|
244
|
+
evict_if_exceeded
|
245
|
+
value
|
221
246
|
end
|
222
247
|
end
|
223
248
|
end
|
data/lib/lru_redux/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sin_lru_redux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masahiro
|
8
|
-
bindir:
|
8
|
+
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2024-12-
|
10
|
+
date: 2024-12-30 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: |
|
13
13
|
Efficient and thread-safe LRU cache.
|
@@ -18,17 +18,12 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
-
- ".github/workflows/lint.yml"
|
22
|
-
- ".github/workflows/test.yml"
|
23
|
-
- ".gitignore"
|
24
21
|
- ".rubocop.yml"
|
25
|
-
-
|
26
|
-
-
|
22
|
+
- CHANGELOG.md
|
23
|
+
- CODE_OF_CONDUCT.md
|
27
24
|
- LICENSE.txt
|
28
25
|
- README.md
|
29
26
|
- Rakefile
|
30
|
-
- bench/bench.rb
|
31
|
-
- bench/bench_ttl.rb
|
32
27
|
- lib/lru_redux.rb
|
33
28
|
- lib/lru_redux/cache.rb
|
34
29
|
- lib/lru_redux/thread_safe_cache.rb
|
@@ -38,20 +33,15 @@ files:
|
|
38
33
|
- lib/lru_redux/util.rb
|
39
34
|
- lib/lru_redux/util/safe_sync.rb
|
40
35
|
- lib/lru_redux/version.rb
|
41
|
-
-
|
42
|
-
- test/cache_test.rb
|
43
|
-
- test/thread_safe_cache_test.rb
|
44
|
-
- test/ttl/cache_test.rb
|
45
|
-
- test/ttl/thread_safe_cache_test.rb
|
46
|
-
homepage: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.0.1
|
36
|
+
homepage: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.1.0
|
47
37
|
licenses:
|
48
38
|
- MIT
|
49
39
|
metadata:
|
50
|
-
homepage_uri: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.0
|
51
|
-
source_code_uri: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.0
|
52
|
-
changelog_uri: https://github.com/cadenza-tech/sin_lru_redux/blob/
|
40
|
+
homepage_uri: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.1.0
|
41
|
+
source_code_uri: https://github.com/cadenza-tech/sin_lru_redux/tree/v2.1.0
|
42
|
+
changelog_uri: https://github.com/cadenza-tech/sin_lru_redux/blob/v2.1.0/CHANGELOG.md
|
53
43
|
bug_tracker_uri: https://github.com/cadenza-tech/sin_lru_redux/issues
|
54
|
-
documentation_uri: https://rubydoc.info/gems/sin_lru_redux/2.0
|
44
|
+
documentation_uri: https://rubydoc.info/gems/sin_lru_redux/2.1.0
|
55
45
|
rubygems_mfa_required: 'true'
|
56
46
|
rdoc_options: []
|
57
47
|
require_paths:
|
data/.github/workflows/lint.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
name: Lint
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
paths:
|
5
|
-
- '**/*.rb'
|
6
|
-
permissions:
|
7
|
-
contents: read
|
8
|
-
jobs:
|
9
|
-
lint:
|
10
|
-
runs-on: ubuntu-latest
|
11
|
-
steps:
|
12
|
-
- uses: actions/checkout@v4
|
13
|
-
- name: Set up Ruby
|
14
|
-
uses: ruby/setup-ruby@v1
|
15
|
-
with:
|
16
|
-
ruby-version: 3.4
|
17
|
-
bundler-cache: true
|
18
|
-
- name: RuboCop
|
19
|
-
run: bundle exec rake rubocop
|
data/.github/workflows/test.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
name: Test
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
permissions:
|
5
|
-
contents: read
|
6
|
-
jobs:
|
7
|
-
test:
|
8
|
-
runs-on: ubuntu-latest
|
9
|
-
strategy:
|
10
|
-
fail-fast: false
|
11
|
-
matrix:
|
12
|
-
ruby-version: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4]
|
13
|
-
steps:
|
14
|
-
- uses: actions/checkout@v4
|
15
|
-
- name: Set up Ruby
|
16
|
-
uses: ruby/setup-ruby@v1
|
17
|
-
with:
|
18
|
-
ruby-version: ${{ matrix.ruby-version }}
|
19
|
-
bundler-cache: true
|
20
|
-
- name: Run tests
|
21
|
-
run: bundle exec rake test
|
data/.gitignore
DELETED
data/Gemfile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
source 'https://rubygems.org'
|
4
|
-
|
5
|
-
gemspec
|
6
|
-
|
7
|
-
group :development, :test do
|
8
|
-
gem 'bundler'
|
9
|
-
gem 'guard'
|
10
|
-
gem 'guard-minitest'
|
11
|
-
gem 'minitest'
|
12
|
-
gem 'rake'
|
13
|
-
gem 'rb-inotify'
|
14
|
-
gem 'rubocop'
|
15
|
-
gem 'rubocop-minitest'
|
16
|
-
gem 'rubocop-performance'
|
17
|
-
gem 'rubocop-rake'
|
18
|
-
gem 'timecop'
|
19
|
-
end
|
data/Guardfile
DELETED
data/bench/bench.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
require 'benchmark'
|
5
|
-
require 'lru'
|
6
|
-
require 'lru_cache'
|
7
|
-
require 'threadsafe-lru'
|
8
|
-
|
9
|
-
Bundler.require
|
10
|
-
|
11
|
-
# Lru
|
12
|
-
lru = Cache::LRU.new(max_elements: 1_000)
|
13
|
-
|
14
|
-
# LruCache
|
15
|
-
lru_cache = LRUCache.new(1_000)
|
16
|
-
|
17
|
-
# ThreadSafeLru
|
18
|
-
thread_safe_lru = ThreadSafeLru::LruCache.new(1_000)
|
19
|
-
|
20
|
-
# LruRedux
|
21
|
-
redux = LruRedux::Cache.new(1_000)
|
22
|
-
redux_thread_safe = LruRedux::ThreadSafeCache.new(1_000)
|
23
|
-
|
24
|
-
puts '** LRU Benchmarks **'
|
25
|
-
|
26
|
-
Benchmark.bmbm do |bm|
|
27
|
-
bm.report 'ThreadSafeLru' do
|
28
|
-
1_000_000.times { thread_safe_lru.get(rand(2_000)) { :value } }
|
29
|
-
end
|
30
|
-
|
31
|
-
bm.report 'LRU' do
|
32
|
-
1_000_000.times { lru[rand(2_000)] ||= :value }
|
33
|
-
end
|
34
|
-
|
35
|
-
bm.report 'LRUCache' do
|
36
|
-
1_000_000.times { lru_cache[rand(2_000)] ||= :value }
|
37
|
-
end
|
38
|
-
|
39
|
-
bm.report 'LruRedux::Cache' do
|
40
|
-
1_000_000.times { redux.getset(rand(2_000)) { :value } }
|
41
|
-
end
|
42
|
-
|
43
|
-
bm.report 'LruRedux::ThreadSafeCache' do
|
44
|
-
1_000_000.times { redux_thread_safe.getset(rand(2_000)) { :value } }
|
45
|
-
end
|
46
|
-
end
|
data/bench/bench_ttl.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
require 'benchmark'
|
5
|
-
require 'fast_cache'
|
6
|
-
|
7
|
-
Bundler.require
|
8
|
-
|
9
|
-
# FastCache
|
10
|
-
fast_cache = FastCache::Cache.new(1_000, 5 * 60)
|
11
|
-
|
12
|
-
# LruRedux
|
13
|
-
redux_ttl = LruRedux::TTL::Cache.new(1_000, 5 * 60)
|
14
|
-
redux_ttl_thread_safe = LruRedux::TTL::ThreadSafeCache.new(1_000, 5 * 60)
|
15
|
-
redux_ttl_disabled = LruRedux::TTL::Cache.new(1_000, :none)
|
16
|
-
|
17
|
-
puts '** TTL Benchmarks **'
|
18
|
-
|
19
|
-
Benchmark.bmbm do |bm|
|
20
|
-
bm.report 'FastCache' do
|
21
|
-
1_000_000.times { fast_cache.fetch(rand(2_000)) { :value } } # rubocop:disable Style/RedundantFetchBlock
|
22
|
-
end
|
23
|
-
|
24
|
-
bm.report 'LruRedux::TTL::Cache' do
|
25
|
-
1_000_000.times { redux_ttl.getset(rand(2_000)) { :value } }
|
26
|
-
end
|
27
|
-
|
28
|
-
bm.report 'LruRedux::TTL::ThreadSafeCache' do
|
29
|
-
1_000_000.times { redux_ttl_thread_safe.getset(rand(2_000)) { :value } }
|
30
|
-
end
|
31
|
-
|
32
|
-
bm.report 'LruRedux::TTL::Cache (TTL disabled)' do
|
33
|
-
1_000_000.times { redux_ttl_disabled.getset(rand(2_000)) { :value } }
|
34
|
-
end
|
35
|
-
end
|
data/sin_lru_redux.gemspec
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
lib = File.expand_path('lib', __dir__)
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require 'lru_redux/version'
|
6
|
-
|
7
|
-
Gem::Specification.new do |spec|
|
8
|
-
spec.name = 'sin_lru_redux'
|
9
|
-
spec.version = LruRedux::VERSION
|
10
|
-
spec.description = <<~DESCRIPTION
|
11
|
-
Efficient and thread-safe LRU cache.
|
12
|
-
Forked from LruRedux.
|
13
|
-
DESCRIPTION
|
14
|
-
spec.summary = 'Efficient and thread-safe LRU cache.'
|
15
|
-
spec.authors = ['Masahiro']
|
16
|
-
spec.email = ['watanabe@cadenza-tech.com']
|
17
|
-
spec.license = 'MIT'
|
18
|
-
|
19
|
-
github_root_uri = 'https://github.com/cadenza-tech/sin_lru_redux'
|
20
|
-
spec.homepage = "#{github_root_uri}/tree/v#{spec.version}"
|
21
|
-
spec.metadata = {
|
22
|
-
'homepage_uri' => spec.homepage,
|
23
|
-
'source_code_uri' => spec.homepage,
|
24
|
-
'changelog_uri' => "#{github_root_uri}/blob/#{spec.version}#changelog",
|
25
|
-
'bug_tracker_uri' => "#{github_root_uri}/issues",
|
26
|
-
'documentation_uri' => "https://rubydoc.info/gems/#{spec.name}/#{spec.version}",
|
27
|
-
'rubygems_mfa_required' => 'true'
|
28
|
-
}
|
29
|
-
|
30
|
-
spec.required_ruby_version = '>= 2.3.0'
|
31
|
-
|
32
|
-
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
33
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
34
|
-
spec.require_paths = ['lib']
|
35
|
-
end
|