timed_lru 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 256a5775aadc75a4ba0151c3b2530d77b6fe66d8a80163bd4a51500008fc81c4
4
- data.tar.gz: 2e46aa41b37eac70b04bcabac5abf3d160af09c4da00f8fa89b5e35223b9bf6a
3
+ metadata.gz: 32262a349b2bcc96380ae8cb5684ba4276ff2dd867b2d54b1f5fc92f537d0a1c
4
+ data.tar.gz: 0536c7d764505d25c48e7b0041051499f32166ac0ae259f30770d2d2dc58dbd5
5
5
  SHA512:
6
- metadata.gz: 225fa64f43a2d8c4d730060df4af035697a628f4080c06542828fef00b58c9c7f53d0b871bb60d27cf203f5a0fd34cb47540e4eb3655fe06a192df9a8d1f12ba
7
- data.tar.gz: 9a24526b95949e25e55b919d66a393a2fe7a1f0fcdd0315c7e8edf0c662038fdd9198d0a0fe808e54b4a66ac534763e6ca798a71f07238232ceeb0ef3214ea2d
6
+ metadata.gz: e61acf070a81d2b389131302435d49b9f7c0b663dc9840948cd63686bbea01e145a6b2f0df48ab4a72b52855b888c98a502f533b665423aa17d2f00d00d9f780
7
+ data.tar.gz: fda206b6600397bc0b486cfabb5a07b56bbdb67424da829ae14938e4025553f4c000ff2cbb3b3706d62d30b34c7cec78abeb5dfaf8bc7ee5949bd717d3d045c8
@@ -0,0 +1,21 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ["2.6", "2.7", "3.0"]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby-version }}
20
+ bundler-cache: true
21
+ - run: bundle exec rake
data/.rubocop.yml CHANGED
@@ -1,8 +1,10 @@
1
- inherit_from:
2
- - https://gitlab.com/bsm/misc/raw/master/rubocop/default.yml
3
-
1
+ inherit_gem:
2
+ rubocop-bsm:
3
+ - default.yml
4
+ inherit_mode:
5
+ merge:
6
+ - Exclude
4
7
  AllCops:
5
- TargetRubyVersion: "2.4"
6
-
8
+ TargetRubyVersion: "2.6"
7
9
  Naming/MemoizedInstanceVariableName:
8
- Enabled: false
10
+ Enabled: false
data/Gemfile CHANGED
@@ -1,5 +1,2 @@
1
1
  source 'http://rubygems.org'
2
2
  gemspec
3
-
4
- gem 'coveralls', require: false, group: :test
5
- gem 'json', '>= 1.7.7', require: false, group: :test
data/Gemfile.lock CHANGED
@@ -1,70 +1,88 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- timed_lru (0.4.0)
4
+ timed_lru (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
- ast (2.4.0)
10
- coveralls (0.8.23)
11
- json (>= 1.8, < 3)
12
- simplecov (~> 0.16.1)
13
- term-ansicolor (~> 1.3)
14
- thor (>= 0.19.4, < 2.0)
15
- tins (~> 1.6)
16
- diff-lcs (1.3)
17
- docile (1.3.2)
18
- jaro_winkler (1.5.3)
19
- json (2.2.0)
20
- parallel (1.17.0)
21
- parser (2.6.3.0)
22
- ast (~> 2.4.0)
9
+ activesupport (6.1.3)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 1.6, < 2)
12
+ minitest (>= 5.1)
13
+ tzinfo (~> 2.0)
14
+ zeitwerk (~> 2.3)
15
+ ast (2.4.2)
16
+ concurrent-ruby (1.1.8)
17
+ diff-lcs (1.4.4)
18
+ i18n (1.8.9)
19
+ concurrent-ruby (~> 1.0)
20
+ minitest (5.14.4)
21
+ parallel (1.20.1)
22
+ parser (3.0.0.0)
23
+ ast (~> 2.4.1)
24
+ rack (2.2.3)
23
25
  rainbow (3.0.0)
24
- rake (12.3.3)
25
- rspec (3.8.0)
26
- rspec-core (~> 3.8.0)
27
- rspec-expectations (~> 3.8.0)
28
- rspec-mocks (~> 3.8.0)
29
- rspec-core (3.8.2)
30
- rspec-support (~> 3.8.0)
31
- rspec-expectations (3.8.4)
26
+ rake (13.0.3)
27
+ regexp_parser (2.1.1)
28
+ rexml (3.2.4)
29
+ rspec (3.10.0)
30
+ rspec-core (~> 3.10.0)
31
+ rspec-expectations (~> 3.10.0)
32
+ rspec-mocks (~> 3.10.0)
33
+ rspec-core (3.10.1)
34
+ rspec-support (~> 3.10.0)
35
+ rspec-expectations (3.10.1)
32
36
  diff-lcs (>= 1.2.0, < 2.0)
33
- rspec-support (~> 3.8.0)
34
- rspec-mocks (3.8.1)
37
+ rspec-support (~> 3.10.0)
38
+ rspec-mocks (3.10.2)
35
39
  diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.8.0)
37
- rspec-support (3.8.2)
38
- rubocop (0.71.0)
39
- jaro_winkler (~> 1.5.1)
40
+ rspec-support (~> 3.10.0)
41
+ rspec-support (3.10.2)
42
+ rubocop (1.11.0)
40
43
  parallel (~> 1.10)
41
- parser (>= 2.6)
44
+ parser (>= 3.0.0.0)
42
45
  rainbow (>= 2.2.2, < 4.0)
46
+ regexp_parser (>= 1.8, < 3.0)
47
+ rexml
48
+ rubocop-ast (>= 1.2.0, < 2.0)
43
49
  ruby-progressbar (~> 1.7)
44
- unicode-display_width (>= 1.4.0, < 1.7)
45
- ruby-progressbar (1.10.1)
46
- simplecov (0.16.1)
47
- docile (~> 1.1)
48
- json (>= 1.8, < 3)
49
- simplecov-html (~> 0.10.0)
50
- simplecov-html (0.10.2)
51
- term-ansicolor (1.7.1)
52
- tins (~> 1.0)
53
- thor (0.20.3)
54
- tins (1.21.1)
55
- unicode-display_width (1.6.0)
50
+ unicode-display_width (>= 1.4.0, < 3.0)
51
+ rubocop-ast (1.4.1)
52
+ parser (>= 2.7.1.5)
53
+ rubocop-bsm (0.5.4)
54
+ rubocop (~> 1.0)
55
+ rubocop-performance
56
+ rubocop-rails
57
+ rubocop-rake
58
+ rubocop-rspec
59
+ rubocop-performance (1.10.1)
60
+ rubocop (>= 0.90.0, < 2.0)
61
+ rubocop-ast (>= 0.4.0)
62
+ rubocop-rails (2.9.1)
63
+ activesupport (>= 4.2.0)
64
+ rack (>= 1.1)
65
+ rubocop (>= 0.90.0, < 2.0)
66
+ rubocop-rake (0.5.1)
67
+ rubocop
68
+ rubocop-rspec (2.2.0)
69
+ rubocop (~> 1.0)
70
+ rubocop-ast (>= 1.1.0)
71
+ ruby-progressbar (1.11.0)
72
+ tzinfo (2.0.4)
73
+ concurrent-ruby (~> 1.0)
74
+ unicode-display_width (2.0.0)
75
+ zeitwerk (2.4.2)
56
76
 
57
77
  PLATFORMS
58
78
  ruby
59
79
 
60
80
  DEPENDENCIES
61
81
  bundler
62
- coveralls
63
- json (>= 1.7.7)
64
82
  rake
65
83
  rspec
66
- rubocop
84
+ rubocop-bsm
67
85
  timed_lru!
68
86
 
69
87
  BUNDLED WITH
70
- 2.0.1
88
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2021 Black Square Media Ltd
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md CHANGED
@@ -1,16 +1,13 @@
1
- Timed LRU
2
- =========
1
+ # Timed LRU
3
2
 
4
3
  [![Build Status](https://travis-ci.org/bsm/timed_lru.png)](https://travis-ci.org/bsm/timed_lru)
5
4
  [![Dependency Status](https://gemnasium.com/bsm/timed_lru.png)](https://gemnasium.com/bsm/timed_lru)
6
- [![Coverage Status](https://coveralls.io/repos/bsm/timed_lru/badge.png)](https://coveralls.io/r/bsm/timed_lru)
7
5
 
8
6
  My implementation of a simple, thread-safe LRU with (optional) TTLs
9
7
  and constant time operations. There are many LRUs for Ruby available but
10
8
  I was unable to find one that matches all three requirements.
11
9
 
12
- Install
13
- -------
10
+ ## Install
14
11
 
15
12
  Install it via `gem`:
16
13
 
@@ -20,8 +17,7 @@ gem install timed_lru
20
17
 
21
18
  Or just bundle it with your project.
22
19
 
23
- Usage Example
24
- -------------
20
+ ## Usage Example
25
21
 
26
22
  ```ruby
27
23
  # Initialize with a max size (default: 100) and a TTL (default: none)
@@ -45,29 +41,3 @@ sleep(4)
45
41
  lru["c"] # => "value 3"
46
42
  lru.keys # => ["c", "d"]
47
43
  ```
48
-
49
- Licence
50
- -------
51
-
52
- ```
53
- Copyright (c) 2013 Black Square Media Ltd
54
-
55
- Permission is hereby granted, free of charge, to any person obtaining
56
- a copy of this software and associated documentation files (the
57
- "Software"), to deal in the Software without restriction, including
58
- without limitation the rights to use, copy, modify, merge, publish,
59
- distribute, sublicense, and/or sell copies of the Software, and to
60
- permit persons to whom the Software is furnished to do so, subject to
61
- the following conditions:
62
-
63
- The above copyright notice and this permission notice shall be
64
- included in all copies or substantial portions of the Software.
65
-
66
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
67
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
69
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
70
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
71
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
72
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
73
- ```
data/lib/timed_lru.rb CHANGED
@@ -23,22 +23,22 @@ class TimedLRU
23
23
  # @param [Hash] opts options
24
24
  # @option opts [Integer] max_size
25
25
  # maximum allowed number of items, defaults to 100
26
+ # @option opts [Integer,Float] ttl
27
+ # the TTL in seconds
26
28
  # @option opts [Boolean] thread_safe
27
29
  # true by default, set to false if you are not using threads a *really* need
28
30
  # that extra bit of performance
29
- # @option opts [Integer] ttl
30
- # the TTL in seconds
31
- def initialize(opts={})
31
+ def initialize(max_size: 100, ttl: nil, thread_safe: true)
32
32
  super() # MonitorMixin
33
33
 
34
34
  @hash = {}
35
- @max_size = Integer(opts[:max_size] || 100)
36
- @ttl = Integer(opts[:ttl]) if opts[:ttl]
35
+ @max_size = Integer(max_size)
36
+ @ttl = Float(ttl) if ttl
37
37
 
38
38
  raise ArgumentError, 'Option :max_size must be > 0' unless max_size.positive?
39
39
  raise ArgumentError, 'Option :ttl must be > 0' unless ttl.nil? || ttl.positive?
40
40
 
41
- extend ThreadUnsafe if opts[:thread_safe] == false
41
+ extend ThreadUnsafe if thread_safe == false
42
42
  end
43
43
 
44
44
  # Stores a `value` by `key`
@@ -84,8 +84,7 @@ class TimedLRU
84
84
 
85
85
  def compact!
86
86
  remove(@tail) while @hash.size > max_size
87
-
88
- remove(@tail) while ttl && @tail.expires_at < Time.now.to_i
87
+ remove(@tail) while ttl && @tail.expires_at < Time.now.to_f
89
88
  end
90
89
 
91
90
  def remove(node)
@@ -98,7 +97,7 @@ class TimedLRU
98
97
  end
99
98
 
100
99
  def touch(node)
101
- node.expires_at = Time.now.to_i + ttl if ttl
100
+ node.expires_at = Time.now.to_f + ttl if ttl
102
101
  return if node == @head
103
102
 
104
103
  left = node.left
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe TimedLRU do
4
-
5
4
  subject { described_class.new max_size: 4 }
6
5
 
7
6
  def full_chain
@@ -38,11 +37,13 @@ describe TimedLRU do
38
37
 
39
38
  describe '#max_size' do
40
39
  subject { super().max_size }
40
+
41
41
  it { is_expected.to be(100) }
42
42
  end
43
43
 
44
44
  describe '#ttl' do
45
45
  subject { super().ttl }
46
+
46
47
  it { is_expected.to be_nil }
47
48
  end
48
49
 
@@ -59,16 +60,19 @@ describe TimedLRU do
59
60
 
60
61
  describe '#max_size' do
61
62
  subject { super().max_size }
63
+
62
64
  it { is_expected.to be(25) }
63
65
  end
64
66
 
65
67
  describe '#ttl' do
66
68
  subject { super().ttl }
67
- it { is_expected.to be(120) }
69
+
70
+ it { is_expected.to eq(120.0) }
68
71
  end
72
+
69
73
  it { is_expected.to be_a(described_class::ThreadUnsafe) }
70
74
 
71
- it 'should assert correct option values' do
75
+ it 'asserts correct option values' do
72
76
  expect { described_class.new(max_size: 'X') }.to raise_error(ArgumentError)
73
77
  expect { described_class.new(max_size: -1) }.to raise_error(ArgumentError)
74
78
  expect { described_class.new(max_size: 0) }.to raise_error(ArgumentError)
@@ -80,46 +84,43 @@ describe TimedLRU do
80
84
  end
81
85
 
82
86
  describe 'storing' do
83
-
84
- it 'should set head + tail on first item' do
87
+ it 'sets head + tail on first item' do
85
88
  expect do
86
89
  expect(subject.store('a', 1)).to eq(1)
87
90
  end.to change { chain }.from([]).to(['a'])
88
91
  end
89
92
 
90
- it 'should shift chain when new items are added' do
93
+ it 'shifts chain when new items are added' do
91
94
  subject['a'] = 1
92
95
  expect { subject['b'] = 2 }.to change { chain }.from(%w[a]).to(%w[b a])
93
96
  expect { subject['c'] = 3 }.to change { chain }.to(%w[c b a])
94
97
  expect { subject['d'] = 4 }.to change { chain }.to(%w[d c b a])
95
98
  end
96
99
 
97
- it 'should expire LRU items when chain exceeds max size' do
100
+ it 'expires LRU items when chain exceeds max size' do
98
101
  ('a'..'d').each {|x| subject[x] = 1 }
99
102
  expect { subject['e'] = 5 }.to change { chain }.to(%w[e d c b])
100
103
  expect { subject['f'] = 6 }.to change { chain }.to(%w[f e d c])
101
104
  end
102
105
 
103
- it 'should update items' do
106
+ it 'updates items' do
104
107
  ('a'..'d').each {|x| subject[x] = 1 }
105
108
  expect { subject['d'] = 2 }.not_to change { chain }
106
109
  expect { subject['c'] = 2 }.to change { chain }.to(%w[c d b a])
107
110
  expect { subject['b'] = 2 }.to change { chain }.to(%w[b c d a])
108
111
  expect { subject['a'] = 2 }.to change { chain }.to(%w[a b c d])
109
112
  end
110
-
111
113
  end
112
114
 
113
115
  describe 'retrieving' do
114
-
115
- it 'should fetch values' do
116
+ it 'fetches values' do
116
117
  expect(subject.fetch('a')).to be_nil
117
118
  expect(subject['a']).to be_nil
118
119
  subject['a'] = 1
119
120
  expect(subject['a']).to eq(1)
120
121
  end
121
122
 
122
- it 'should renew membership on access' do
123
+ it 'renews membership on access' do
123
124
  ('a'..'d').each {|x| subject[x] = 1 }
124
125
  expect { subject['d'] }.not_to change { chain }
125
126
  expect { subject['c'] }.to change { chain }.to(%w[c d b a])
@@ -127,26 +128,23 @@ describe TimedLRU do
127
128
  expect { subject['a'] }.to change { chain }.to(%w[a b c d])
128
129
  expect { subject['x'] }.not_to change { chain }
129
130
  end
130
-
131
131
  end
132
132
 
133
133
  describe 'deleting' do
134
-
135
- it 'should delete an return values' do
134
+ it 'deletes an return values' do
136
135
  expect(subject.delete('a')).to be_nil
137
136
  subject['a'] = 1
138
137
  expect(subject.delete('a')).to eq(1)
139
138
  end
140
139
 
141
- it 'should re-arrange membership chain' do
140
+ it 're-arranges membership chain' do
142
141
  ('a'..'d').each {|x| subject[x] = 1 }
143
142
  expect { subject.delete('x') }.not_to change { chain }
144
143
  expect { subject.delete('c') }.to change { chain }.to(%w[d b a])
145
144
  expect { subject.delete('a') }.to change { chain }.to(%w[d b])
146
145
  expect { subject.delete('d') }.to change { chain }.to(%w[b])
147
- expect { subject.delete('b') }.to change { subject.size }.from(1).to(0)
146
+ expect { subject.delete('b') }.to change(subject, :size).from(1).to(0)
148
147
  end
149
-
150
148
  end
151
149
 
152
150
  describe 'TTL expiration' do
@@ -159,7 +157,7 @@ describe TimedLRU do
159
157
  allow(Time).to receive(:now).and_call_original
160
158
  end
161
159
 
162
- it 'should expire on access' do
160
+ it 'expires on access' do
163
161
  in_past(70) do
164
162
  subject['a'] = 1
165
163
  expect(chain).to eq(%w[a])
@@ -174,7 +172,7 @@ describe TimedLRU do
174
172
  expect(chain).to eq(%w[c b])
175
173
  end
176
174
 
177
- it 'should renew expiration on access' do
175
+ it 'renews expiration on access' do
178
176
  in_past(70) do
179
177
  subject['a'] = 1
180
178
  subject['b'] = 2
@@ -189,7 +187,5 @@ describe TimedLRU do
189
187
  subject['c'] = 3
190
188
  expect(chain).to eq(%w[c a])
191
189
  end
192
-
193
190
  end
194
-
195
191
  end
data/timed_lru.gemspec CHANGED
@@ -1,14 +1,15 @@
1
1
  Gem::Specification.new do |s|
2
- s.required_ruby_version = '>= 2.4.0'
2
+ s.required_ruby_version = '>= 2.6.0'
3
3
 
4
4
  s.name = File.basename(__FILE__, '.gemspec')
5
5
  s.summary = 'Timed LRU'
6
6
  s.description = 'Thread-safe LRU implementation with (optional) TTL and constant time operations'
7
- s.version = '0.4.0'
7
+ s.version = '0.5.0'
8
8
 
9
9
  s.authors = ['Black Square Media']
10
10
  s.email = 'info@blacksquaremedia.com'
11
11
  s.homepage = 'https://github.com/bsm/timed_lru'
12
+ s.license = 'Apache-2.0'
12
13
 
13
14
  s.require_path = 'lib'
14
15
  s.files = `git ls-files`.split("\n")
@@ -17,5 +18,5 @@ Gem::Specification.new do |s|
17
18
  s.add_development_dependency 'bundler'
18
19
  s.add_development_dependency 'rake'
19
20
  s.add_development_dependency 'rspec'
20
- s.add_development_dependency 'rubocop'
21
+ s.add_development_dependency 'rubocop-bsm'
21
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timed_lru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Black Square Media
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-23 00:00:00.000000000 Z
11
+ date: 2021-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: rubocop-bsm
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -73,20 +73,21 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/workflows/ruby.yml"
76
77
  - ".gitignore"
77
78
  - ".rubocop.yml"
78
- - ".travis.yml"
79
79
  - Gemfile
80
80
  - Gemfile.lock
81
+ - LICENSE
81
82
  - README.md
82
83
  - Rakefile
83
84
  - lib/timed_lru.rb
84
- - spec/coverage_helper.rb
85
85
  - spec/spec_helper.rb
86
86
  - spec/timed_lru_spec.rb
87
87
  - timed_lru.gemspec
88
88
  homepage: https://github.com/bsm/timed_lru
89
- licenses: []
89
+ licenses:
90
+ - Apache-2.0
90
91
  metadata: {}
91
92
  post_install_message:
92
93
  rdoc_options: []
@@ -96,14 +97,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
97
  requirements:
97
98
  - - ">="
98
99
  - !ruby/object:Gem::Version
99
- version: 2.4.0
100
+ version: 2.6.0
100
101
  required_rubygems_version: !ruby/object:Gem::Requirement
101
102
  requirements:
102
103
  - - ">="
103
104
  - !ruby/object:Gem::Version
104
105
  version: '0'
105
106
  requirements: []
106
- rubygems_version: 3.0.3
107
+ rubygems_version: 3.1.4
107
108
  signing_key:
108
109
  specification_version: 4
109
110
  summary: Timed LRU
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- language: ruby
2
- before_install:
3
- - gem install bundler
4
- rvm:
5
- - 2.4
6
- - 2.5
7
- - 2.6
8
- cache: bundler
@@ -1,4 +0,0 @@
1
- require 'coveralls'
2
-
3
- # Enable coverage
4
- Coveralls.wear!