sin_lru_redux 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e3321a712e82f58a5a56395d60775b0ca747408656e82accb07fe9a6a9a3b0d4
4
+ data.tar.gz: 83da0216f823ae497b57957c2f267d79d08299e59fba4735ba10e43018a72773
5
+ SHA512:
6
+ metadata.gz: 5cb2a8d0c6b9e66e20c72f88c12c578aff52f6e07a70450969e1f2ec9fc209fb95afd63627630dac1d6c459d5723ffaa7001aa1525ac384491625df4a6b81a8b
7
+ data.tar.gz: ef5f5c33c8a24d3769bbfa0bf7fa64c9ef1c01465d48d4119242b727b4b01a4b8f545f880d80be30796de819270dcc069336936b6dc2ecf2ad6dab47ec79c767
@@ -0,0 +1,18 @@
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
+ bundler-cache: true
17
+ - name: RuboCop
18
+ run: bundle exec rake rubocop
@@ -0,0 +1,21 @@
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 ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .vscode
7
+ .yardoc
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ Gemfile.lock
12
+ InstalledFiles
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rubocop.yml ADDED
@@ -0,0 +1,202 @@
1
+ require:
2
+ - rubocop-minitest
3
+ - rubocop-performance
4
+ - rubocop-rake
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.4
8
+ NewCops: enable
9
+
10
+ # https://docs.rubocop.org/rubocop/cops_gemspec.html#gemspecrequiredrubyversion
11
+ Gemspec/RequiredRubyVersion:
12
+ Enabled: false
13
+
14
+ # https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirstarrayelementindentation
15
+ Layout/FirstArrayElementIndentation:
16
+ Enabled: true
17
+ EnforcedStyle: consistent
18
+
19
+ # https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
20
+ Layout/LineLength:
21
+ Enabled: true
22
+ Max: 150
23
+ AllowURI: false
24
+
25
+ # https://docs.rubocop.org/rubocop/cops_lint.html#lintmissingsuper
26
+ Lint/MissingSuper:
27
+ Enabled: true
28
+ Exclude:
29
+ - 'app/views/components/**/component.rb'
30
+
31
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize
32
+ Metrics/AbcSize:
33
+ Enabled: true
34
+ Max: 30
35
+
36
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength
37
+ Metrics/BlockLength:
38
+ Enabled: true
39
+ Max: 30
40
+ Exclude:
41
+ - 'config/routes.rb'
42
+ - 'db/seeds.rb'
43
+ - 'spec/**/*_spec.rb'
44
+
45
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocknesting
46
+ Metrics/BlockNesting:
47
+ Enabled: true
48
+ Max: 3
49
+
50
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength
51
+ Metrics/ClassLength:
52
+ Enabled: true
53
+ CountComments: false
54
+ Max: 400
55
+
56
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity
57
+ Metrics/CyclomaticComplexity:
58
+ Enabled: true
59
+ Max: 20
60
+
61
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength
62
+ Metrics/MethodLength:
63
+ Enabled: true
64
+ CountComments: false
65
+ Max: 25
66
+
67
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength
68
+ Metrics/ModuleLength:
69
+ Enabled: true
70
+ Max: 200
71
+
72
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists
73
+ Metrics/ParameterLists:
74
+ Enabled: true
75
+ Max: 5
76
+ CountKeywordArgs: true
77
+
78
+ # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsperceivedcomplexity
79
+ Metrics/PerceivedComplexity:
80
+ Enabled: true
81
+ Max: 20
82
+
83
+ # https://docs.rubocop.org/rubocop/cops_naming.html#namingaccessormethodname
84
+ Naming/AccessorMethodName:
85
+ Enabled: false
86
+
87
+ # https://docs.rubocop.org/rubocop/cops_naming.html#namingblockforwarding
88
+ Naming/BlockForwarding:
89
+ Enabled: true
90
+ EnforcedStyle: explicit
91
+
92
+ # https://docs.rubocop.org/rubocop/cops_naming.html#namingmemoizedinstancevariablename
93
+ Naming/MemoizedInstanceVariableName:
94
+ Enabled: false
95
+
96
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleaccessmodifierdeclarations
97
+ Style/AccessModifierDeclarations:
98
+ Enabled: true
99
+ AllowModifiersOnSymbols: false
100
+
101
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylealias
102
+ Style/Alias:
103
+ Enabled: true
104
+ EnforcedStyle: prefer_alias_method
105
+
106
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleargumentsforwarding
107
+ Style/ArgumentsForwarding:
108
+ Enabled: true
109
+ UseAnonymousForwarding: false
110
+
111
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleasciicomments
112
+ Style/AsciiComments:
113
+ Enabled: false
114
+
115
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleblockcomments
116
+ Style/BlockComments:
117
+ Enabled: true
118
+ Exclude:
119
+ - 'spec/spec_helper.rb'
120
+
121
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
122
+ Style/ClassAndModuleChildren:
123
+ Enabled: false
124
+
125
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylecollectionmethods
126
+ Style/CollectionMethods:
127
+ Enabled: true
128
+ PreferredMethods:
129
+ detect: 'detect'
130
+ find: 'detect'
131
+ inject: 'inject'
132
+ reduce: 'inject'
133
+
134
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleconditionalassignment
135
+ Style/ConditionalAssignment:
136
+ Enabled: true
137
+ EnforcedStyle: assign_inside_condition
138
+
139
+ # https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation
140
+ Style/Documentation:
141
+ Enabled: false
142
+
143
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleemptymethod
144
+ Style/EmptyMethod:
145
+ Enabled: true
146
+ EnforcedStyle: expanded
147
+
148
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
149
+ Style/HashSyntax:
150
+ Enabled: true
151
+ EnforcedStyle: ruby19_no_mixed_keys
152
+ EnforcedShorthandSyntax: never
153
+
154
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylelambda
155
+ Style/Lambda:
156
+ Enabled: true
157
+ EnforcedStyle: literal
158
+
159
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylelineendconcatenation
160
+ Style/LineEndConcatenation:
161
+ Enabled: false
162
+
163
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals
164
+ Style/NumericLiterals:
165
+ Enabled: false
166
+
167
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylenumericpredicate
168
+ Style/NumericPredicate:
169
+ Enabled: true
170
+ EnforcedStyle: comparison
171
+
172
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleraiseargs
173
+ Style/RaiseArgs:
174
+ Enabled: true
175
+ EnforcedStyle: compact
176
+
177
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylesuperarguments
178
+ Style/SuperArguments:
179
+ Enabled: false
180
+
181
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray
182
+ Style/SymbolArray:
183
+ Enabled: true
184
+ EnforcedStyle: brackets
185
+
186
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleternaryparentheses
187
+ Style/TernaryParentheses:
188
+ Enabled: true
189
+ EnforcedStyle: require_parentheses_when_complex
190
+ AllowSafeAssignment: false
191
+
192
+ # https://docs.rubocop.org/rubocop/cops_style.html#styletrailingunderscorevariable
193
+ Style/TrailingUnderscoreVariable:
194
+ Enabled: false
195
+
196
+ # https://docs.rubocop.org/rubocop/cops_style.html#styleunpackfirst
197
+ Style/UnpackFirst:
198
+ Enabled: false
199
+
200
+ # https://docs.rubocop.org/rubocop/cops_style.html#stylewordarray
201
+ Style/WordArray:
202
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,19 @@
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 ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard 'minitest', focus_on_failed: true do
4
+ watch(%r{^test/.+_test\.rb$})
5
+ watch(%r{^lib/lru_redux/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
6
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2013 Sam Saffron
2
+ Copyright (c) 2024 Masahiro
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,288 @@
1
+ # SinLruRedux [![Gem Version](https://badge.fury.io/rb/sin_lru_redux.svg)](http://badge.fury.io/rb/sin_lru_redux)
2
+
3
+ An efficient, thread safe LRU cache.
4
+
5
+ Forked from [LruRedux](https://github.com/SamSaffron/lru_redux).
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [TTL Cache](#ttl-cache)
10
+ - [Cache Methods](#cache-methods)
11
+ - [Benchmarks](#benchmarks)
12
+ - [Other Caches](#other-caches)
13
+ - [Contributing](#contributing)
14
+ - [Changelog](#changelog)
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'sin_lru_redux'
21
+
22
+ And then execute:
23
+
24
+ $ bundle install
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install sin_lru_redux
29
+
30
+ ## Usage
31
+
32
+ ```ruby
33
+ require 'lru_redux'
34
+
35
+ # non thread safe
36
+ cache = LruRedux::Cache.new(100)
37
+ cache[:a] = '1'
38
+ cache[:b] = '2'
39
+
40
+ cache.to_a
41
+ # [[:b, '2'], [:a, '1']]
42
+ # note the order matters here, last accessed is first
43
+
44
+ cache[:a] # a pushed to front
45
+ # '1'
46
+
47
+ cache.to_a
48
+ # [[:a, '1'], [:b, '2']]
49
+ cache.delete(:a)
50
+ cache.each { |k, v| puts "#{k} #{v}"}
51
+ # b 2
52
+
53
+ cache.max_size = 200 # cache now stores 200 items
54
+ cache.clear # cache has no items
55
+
56
+ cache.getset(:a) { 1 }
57
+ cache.to_a
58
+ #[[:a, 1]]
59
+
60
+ # already set so don't call block
61
+ cache.getset(:a) { 99 }
62
+ cache.to_a
63
+ #[[:a, 1]]
64
+
65
+ # for thread safe access, all methods on cache
66
+ # are protected with a mutex
67
+ cache = LruRedux::ThreadSafeCache.new(100)
68
+ ```
69
+
70
+ #### TTL Cache
71
+
72
+ The TTL cache extends the functionality of the LRU cache with a Time To Live eviction strategy. TTL eviction occurs on every access and takes precedence over LRU eviction, meaning a 'live' value will never be evicted over an expired one.
73
+
74
+ ```ruby
75
+ # Timecop is gem that allows us to change Time.now
76
+ # and is used for demonstration purposes.
77
+ require 'lru_redux'
78
+ require 'timecop'
79
+
80
+ # Create a TTL cache with a size of 100 and TTL of 5 minutes.
81
+ # The first argument is the size and
82
+ # the second optional argument is the TTL in seconds.
83
+ cache = LruRedux::TTL::Cache.new(100, 5 * 60)
84
+
85
+ Timecop.freeze(Time.now)
86
+
87
+ cache[:a] = '1'
88
+ cache[:b] = '2'
89
+
90
+ cache.to_a
91
+ # => [[:b, '2'], [:a, '1']]
92
+
93
+ # Now we advance time 5 min 30 sec into the future.
94
+ Timecop.freeze(Time.now + 330)
95
+
96
+ # And we see that the expired values have been evicted.
97
+ cache.to_a
98
+ # => []
99
+
100
+ # The TTL can be updated on a live cache using #ttl=.
101
+ # Currently cached items will be evicted under the new TTL.
102
+ cache[:a] = '1'
103
+ cache[:b] = '2'
104
+
105
+ Timecop.freeze(Time.now + 330)
106
+
107
+ cache.ttl = 10 * 60
108
+
109
+ # Since ttl eviction is triggered by access,
110
+ # the items are still cached when the ttl is changed and
111
+ # are now under the 10 minute TTL.
112
+ cache.to_a
113
+ # => [[:b, '2'], [:a, '1']]
114
+
115
+ # TTL eviction can be triggered manually with the #expire method.
116
+ Timecop.freeze(Time.now + 330)
117
+
118
+ cache.expire
119
+ cache.to_a
120
+ # => []
121
+
122
+ Timecop.return
123
+
124
+ # The behavior of a TTL cache with the TTL set to `:none`
125
+ # is identical to the LRU cache.
126
+
127
+ cache = LruRedux::TTL::Cache.new(100, :none)
128
+
129
+ # The TTL argument is optional and defaults to `:none`.
130
+ cache = LruRedux::TTL::Cache.new(100)
131
+
132
+ # A thread safe version is available.
133
+ cache = LruRedux::TTL::ThreadSafeCache.new(100, 5 * 60)
134
+ ```
135
+
136
+ ## Cache Methods
137
+
138
+ - `#getset` Takes a key and block. Will return a value if cached, otherwise will execute the block and cache the resulting value.
139
+ - `#fetch` Takes a key and optional block. Will return a value if cached, otherwise will execute the block and return the resulting value or return nil if no block is provided.
140
+ - `#[]` Takes a key. Will return a value if cached, otherwise nil.
141
+ - `#[]=` Takes a key and value. Will cache the value under the key.
142
+ - `#delete` Takes a key. Will return the deleted value, otherwise nil.
143
+ - `#evict` Alias for `#delete`.
144
+ - `#clear` Clears the cache. Returns nil.
145
+ - `#each` Takes a block. Executes the block on each key-value pair in LRU order (most recent first).
146
+ - `#to_a` Return an array of key-value pairs (arrays) in LRU order (most recent first).
147
+ - `#key?` Takes a key. Returns true if the key is cached, otherwise false.
148
+ - `#has_key?` Alias for `#key?`.
149
+ - `#count` Return the current number of items stored in the cache.
150
+ - `#max_size` Returns the current maximum size of the cache.
151
+ - `#max_size=` Takes a positive number. Changes the current max_size and triggers a resize. Also triggers TTL eviction on the TTL cache.
152
+ - `#ignore_nil` Returns the current ignore nil setting.
153
+ - `#ignore_nil=` Takes true or false. Changes the current ignore nil setting.
154
+
155
+ #### TTL Cache Specific
156
+
157
+ - `#ttl` Returns the current TTL of the cache.
158
+ - `#ttl=` Takes `:none` or a positive number. Changes the current ttl and triggers a TTL eviction.
159
+ - `#expire` Triggers a TTL eviction.
160
+
161
+ ## Benchmarks
162
+
163
+ see: benchmark directory (a million random lookup / store)
164
+
165
+ #### LRU
166
+
167
+ ##### Ruby 2.2.1
168
+
169
+ ```shell
170
+ $ ruby ./bench/bench.rb
171
+
172
+ Rehearsal -------------------------------------------------------------
173
+ ThreadSafeLru 4.500000 0.030000 4.530000 ( 4.524213)
174
+ LRU 2.250000 0.000000 2.250000 ( 2.249670)
175
+ LRUCache 1.720000 0.010000 1.730000 ( 1.728243)
176
+ LruRedux::Cache 0.960000 0.000000 0.960000 ( 0.961292)
177
+ LruRedux::ThreadSafeCache 2.180000 0.000000 2.180000 ( 2.187714)
178
+ --------------------------------------------------- total: 11.650000sec
179
+
180
+ user system total real
181
+ ThreadSafeLru 4.390000 0.020000 4.410000 ( 4.415703)
182
+ LRU 2.140000 0.010000 2.150000 ( 2.149626)
183
+ LRUCache 1.680000 0.010000 1.690000 ( 1.688564)
184
+ LruRedux::Cache 0.910000 0.000000 0.910000 ( 0.913108)
185
+ LruRedux::ThreadSafeCache 2.200000 0.010000 2.210000 ( 2.212108)
186
+ ```
187
+
188
+ #### TTL
189
+
190
+ ##### Ruby 2.2.1
191
+
192
+ ```shell
193
+ $ ruby ./bench/bench_ttl.rb
194
+ Rehearsal -----------------------------------------------------------------------
195
+ FastCache 6.240000 0.070000 6.310000 ( 6.302569)
196
+ LruRedux::TTL::Cache 4.700000 0.010000 4.710000 ( 4.712858)
197
+ LruRedux::TTL::ThreadSafeCache 6.300000 0.010000 6.310000 ( 6.319032)
198
+ LruRedux::TTL::Cache (TTL disabled) 2.460000 0.010000 2.470000 ( 2.470629)
199
+ ------------------------------------------------------------- total: 19.800000sec
200
+
201
+ user system total real
202
+ FastCache 6.470000 0.070000 6.540000 ( 6.536193)
203
+ LruRedux::TTL::Cache 4.640000 0.010000 4.650000 ( 4.661793)
204
+ LruRedux::TTL::ThreadSafeCache 6.310000 0.020000 6.330000 ( 6.328840)
205
+ LruRedux::TTL::Cache (TTL disabled) 2.440000 0.000000 2.440000 ( 2.446269)
206
+ ```
207
+
208
+ ## Other Caches
209
+
210
+ This is a list of the caches that are used in the benchmarks.
211
+
212
+ #### LRU
213
+
214
+ - RubyGems: https://rubygems.org/gems/lru
215
+ - Homepage: http://lru.rubyforge.org/
216
+
217
+ #### LRUCache
218
+
219
+ - RubyGems: https://rubygems.org/gems/lru_cache
220
+ - Homepage: https://github.com/brendan/lru_cache
221
+
222
+ #### ThreadSafeLru
223
+
224
+ - RubyGems: https://rubygems.org/gems/threadsafe-lru
225
+ - Homepage: https://github.com/draganm/threadsafe-lru
226
+
227
+ #### FastCache
228
+
229
+ - RubyGems: https://rubygems.org/gems/fast_cache
230
+ - Homepage: https://github.com/swoop-inc/fast_cache
231
+
232
+ ## Contributing
233
+
234
+ 1. Fork it
235
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
236
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
237
+ 4. Push to the branch (`git push origin my-new-feature`)
238
+ 5. Create new Pull Request
239
+
240
+ ## Changelog
241
+
242
+ ### version 2.0.0 - 28-Dec-2024
243
+
244
+ - New: Add ignore_nil argument to cache initialize arguments. If true, blocks called by getset yielding nil values will be returned but not stored in the cache.
245
+ - Fix: Fix LruRedux::TTL::ThreadSafeCache#delete to return deleted value.
246
+ - Ruby Support: Drop runtime support for Ruby 2.3 and below and JRuby.
247
+
248
+ ### version 1.1.0 - 30-Mar-2015
249
+
250
+ - New: TTL cache added. This cache is LRU like with the addition of time-based eviction. Check the Usage -> TTL Cache section in README.md for details.
251
+
252
+ ### version 1.0.0 - 26-Mar-2015
253
+
254
+ - Ruby Support: Ruby 1.9+ is now required by LruRedux. If you need to use LruRedux in Ruby 1.8, please specify gem version 0.8.4 in your Gemfile. v0.8.4 is the last 1.8 compatible release and included a number of fixes and performance improvements for the Ruby 1.8 implementation. @Seberius
255
+ - Perf: improve performance in Ruby 2.1+ on the MRI @Seberius
256
+
257
+ ### version 0.8.4 - 20-Feb-2015
258
+
259
+ - Fix: regression of ThreadSafeCache under JRuby 1.7 @Seberius
260
+
261
+ ### version 0.8.3 - 20-Feb-2015
262
+
263
+ - Perf: improve ThreadSafeCache performance @Seberius
264
+
265
+ ### version 0.8.2 - 16-Feb-2015
266
+
267
+ - Perf: use #size instead of #count when checking length @Seberius
268
+ - Fix: Cache could grow beyond its size in Ruby 1.8 @Seberius
269
+ - Fix: #each could deadlock in Ruby 1.8 @Seberius
270
+
271
+ ### version 0.8.1 - 7-Sep-2013
272
+
273
+ - Fix #each implementation
274
+ - Fix deadlocks with ThreadSafeCache
275
+ - Version jump is because its been used in production for quite a while now
276
+
277
+ ### version 0.0.6 - 24-April-2013
278
+
279
+ - Fix bug in getset, overflow was not returning the yeilded val
280
+
281
+ ### version 0.0.5 - 23-April-2013
282
+
283
+ - Added getset and fetch
284
+ - Optimised implementation so it 20-30% faster on Ruby 1.9+
285
+
286
+ ### version 0.0.4 - 23-April-2013
287
+
288
+ - Initial version
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+ require 'rubocop/rake_task'
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.pattern = 'test/**/*_test.rb'
9
+ end
10
+
11
+ RuboCop::RakeTask.new
data/bench/bench.rb ADDED
@@ -0,0 +1,46 @@
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