concurrent-ruby 1.2.0 → 1.2.1
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/CHANGELOG.md +3 -0
- data/Rakefile +7 -6
- data/lib/concurrent-ruby/concurrent/atomic/locals.rb +1 -0
- data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +2 -2
- data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +8 -8
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent-ruby/concurrent/map.rb +34 -31
- data/lib/concurrent-ruby/concurrent/version.rb +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: 366b0c4f0d3184143a58a6b30538fe9997e7dfad19c8ea38a468168d680f3bdf
|
4
|
+
data.tar.gz: 010f0ee92f5132a2ed41da7d789a72955691dbcf880c579fd121cb366ba000bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 876b3302b218236cb89bd838e3030e2c5937d9682edd8e88a47d538ec5f0da21a7d49b55452e278e6c01b7210cb51c4bad3afc6b5767294f16890f5bd630e69b
|
7
|
+
data.tar.gz: 938906cad82d61617a0267dc28dc99e18420c7872593344c1c6adb4fa54c751839226703e1ce6ea81e79dcd35b2650e5868c6c11bcaf83c02d2fb105aa8b35a2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
## Current
|
2
2
|
|
3
|
+
* (#990) Add missing `require 'fiber'` for `FiberLocalVar`.
|
4
|
+
* (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`.
|
5
|
+
|
3
6
|
## Release v1.2.0 (23 Jan 2023)
|
4
7
|
|
5
8
|
* (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses.
|
data/Rakefile
CHANGED
@@ -271,6 +271,7 @@ namespace :release do
|
|
271
271
|
task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
|
272
272
|
|
273
273
|
namespace :publish do
|
274
|
+
publish_base = true
|
274
275
|
publish_edge = false
|
275
276
|
|
276
277
|
task :ask do
|
@@ -289,8 +290,8 @@ namespace :release do
|
|
289
290
|
desc '** tag HEAD with current version and push to github'
|
290
291
|
task :tag => :ask do
|
291
292
|
Dir.chdir(__dir__) do
|
292
|
-
sh "git tag v#{Concurrent::VERSION}"
|
293
|
-
sh "git push origin v#{Concurrent::VERSION}"
|
293
|
+
sh "git tag v#{Concurrent::VERSION}" if publish_base
|
294
|
+
sh "git push origin v#{Concurrent::VERSION}" if publish_base
|
294
295
|
sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
295
296
|
sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
296
297
|
end
|
@@ -299,11 +300,11 @@ namespace :release do
|
|
299
300
|
desc '** push all *.gem files to rubygems'
|
300
301
|
task :rubygems => :ask do
|
301
302
|
Dir.chdir(__dir__) do
|
302
|
-
sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
|
303
|
+
sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem" if publish_base
|
303
304
|
sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
|
304
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem"
|
305
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem"
|
306
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem"
|
305
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if publish_base
|
306
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem" if publish_base
|
307
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem" if publish_base
|
307
308
|
end
|
308
309
|
end
|
309
310
|
|
@@ -9,8 +9,8 @@ module Concurrent
|
|
9
9
|
# @!visibility private
|
10
10
|
class MriMapBackend < NonConcurrentMapBackend
|
11
11
|
|
12
|
-
def initialize(options = nil)
|
13
|
-
super(options)
|
12
|
+
def initialize(options = nil, &default_proc)
|
13
|
+
super(options, &default_proc)
|
14
14
|
@write_lock = Mutex.new
|
15
15
|
end
|
16
16
|
|
@@ -12,8 +12,10 @@ module Concurrent
|
|
12
12
|
# directly without calling each other. This is important because of the
|
13
13
|
# SynchronizedMapBackend which uses a non-reentrant mutex for performance
|
14
14
|
# reasons.
|
15
|
-
def initialize(options = nil)
|
16
|
-
|
15
|
+
def initialize(options = nil, &default_proc)
|
16
|
+
validate_options_hash!(options) if options.kind_of?(::Hash)
|
17
|
+
@backend = Hash.new(&default_proc)
|
18
|
+
@default_proc = default_proc
|
17
19
|
end
|
18
20
|
|
19
21
|
def [](key)
|
@@ -55,7 +57,7 @@ module Concurrent
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def compute(key)
|
58
|
-
store_computed_value(key, yield(
|
60
|
+
store_computed_value(key, yield(get_or_default(key, nil)))
|
59
61
|
end
|
60
62
|
|
61
63
|
def merge_pair(key, value)
|
@@ -67,7 +69,7 @@ module Concurrent
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def get_and_set(key, value)
|
70
|
-
stored_value =
|
72
|
+
stored_value = get_or_default(key, nil)
|
71
73
|
@backend[key] = value
|
72
74
|
stored_value
|
73
75
|
end
|
@@ -109,13 +111,11 @@ module Concurrent
|
|
109
111
|
@backend.fetch(key, default_value)
|
110
112
|
end
|
111
113
|
|
112
|
-
alias_method :_get, :[]
|
113
|
-
alias_method :_set, :[]=
|
114
|
-
private :_get, :_set
|
115
114
|
private
|
115
|
+
|
116
116
|
def initialize_copy(other)
|
117
117
|
super
|
118
|
-
@backend =
|
118
|
+
@backend = Hash.new(&@default_proc)
|
119
119
|
self
|
120
120
|
end
|
121
121
|
|
Binary file
|
@@ -46,6 +46,12 @@ module Concurrent
|
|
46
46
|
# @note Atomic methods taking a block do not allow the `self` instance
|
47
47
|
# to be used within the block. Doing so will cause a deadlock.
|
48
48
|
|
49
|
+
# @!method []=(key, value)
|
50
|
+
# Set a value with key
|
51
|
+
# @param [Object] key
|
52
|
+
# @param [Object] value
|
53
|
+
# @return [Object] the new value
|
54
|
+
|
49
55
|
# @!method compute_if_absent(key)
|
50
56
|
# Compute and store new value for key if the key is absent.
|
51
57
|
# @param [Object] key
|
@@ -119,41 +125,38 @@ module Concurrent
|
|
119
125
|
# @return [true, false] true if deleted
|
120
126
|
# @!macro map.atomic_method
|
121
127
|
|
122
|
-
#
|
123
|
-
|
124
|
-
if options.kind_of?(::Hash)
|
125
|
-
validate_options_hash!(options)
|
126
|
-
else
|
127
|
-
options = nil
|
128
|
-
end
|
128
|
+
# NonConcurrentMapBackend handles default_proc natively
|
129
|
+
unless defined?(Collection::NonConcurrentMapBackend) and self < Collection::NonConcurrentMapBackend
|
129
130
|
|
130
|
-
|
131
|
-
@default_proc
|
132
|
-
|
131
|
+
# @param [Hash, nil] options options to set the :initial_capacity or :load_factor. Ignored on some Rubies.
|
132
|
+
# @param [Proc] default_proc Optional block to compute the default value if the key is not set, like `Hash#default_proc`
|
133
|
+
def initialize(options = nil, &default_proc)
|
134
|
+
if options.kind_of?(::Hash)
|
135
|
+
validate_options_hash!(options)
|
136
|
+
else
|
137
|
+
options = nil
|
138
|
+
end
|
133
139
|
|
134
|
-
|
135
|
-
|
136
|
-
# @return [Object] the value
|
137
|
-
def [](key)
|
138
|
-
if value = super # non-falsy value is an existing mapping, return it right away
|
139
|
-
value
|
140
|
-
# re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
|
141
|
-
# a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
|
142
|
-
# would be returned)
|
143
|
-
# note: nil == value check is not technically necessary
|
144
|
-
elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
|
145
|
-
@default_proc.call(self, key)
|
146
|
-
else
|
147
|
-
value
|
140
|
+
super(options)
|
141
|
+
@default_proc = default_proc
|
148
142
|
end
|
149
|
-
end
|
150
143
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
144
|
+
# Get a value with key
|
145
|
+
# @param [Object] key
|
146
|
+
# @return [Object] the value
|
147
|
+
def [](key)
|
148
|
+
if value = super # non-falsy value is an existing mapping, return it right away
|
149
|
+
value
|
150
|
+
# re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
|
151
|
+
# a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
|
152
|
+
# would be returned)
|
153
|
+
# note: nil == value check is not technically necessary
|
154
|
+
elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
|
155
|
+
@default_proc.call(self, key)
|
156
|
+
else
|
157
|
+
value
|
158
|
+
end
|
159
|
+
end
|
157
160
|
end
|
158
161
|
|
159
162
|
alias_method :get, :[]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-02-24 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: |
|
16
16
|
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
|