concurrent-ruby 1.0.5 → 1.1.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 +5 -5
 - data/CHANGELOG.md +65 -0
 - data/Gemfile +39 -0
 - data/{LICENSE.txt → LICENSE.md} +2 -0
 - data/README.md +207 -105
 - data/Rakefile +314 -0
 - data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +159 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +306 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
 - data/lib/concurrent/agent.rb +7 -7
 - data/lib/concurrent/array.rb +59 -32
 - data/lib/concurrent/async.rb +4 -4
 - data/lib/concurrent/atom.rb +9 -9
 - data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
 - data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
 - data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
 - data/lib/concurrent/atomic/atomic_reference.rb +185 -32
 - data/lib/concurrent/atomic/count_down_latch.rb +6 -6
 - data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
 - data/lib/concurrent/atomic/event.rb +1 -1
 - data/lib/concurrent/atomic/java_count_down_latch.rb +9 -6
 - data/lib/concurrent/atomic/mutex_atomic_boolean.rb +2 -0
 - data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
 - data/lib/concurrent/atomic/read_write_lock.rb +2 -1
 - data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
 - data/lib/concurrent/atomic/semaphore.rb +8 -8
 - data/lib/concurrent/atomic/thread_local_var.rb +7 -7
 - data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
 - data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
 - data/lib/concurrent/atomics.rb +0 -43
 - data/lib/concurrent/collection/lock_free_stack.rb +158 -0
 - data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
 - data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
 - data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
 - data/lib/concurrent/concern/dereferenceable.rb +1 -1
 - data/lib/concurrent/concern/logging.rb +6 -1
 - data/lib/concurrent/concern/observable.rb +7 -7
 - data/lib/concurrent/concurrent_ruby.jar +0 -0
 - data/lib/concurrent/configuration.rb +1 -6
 - data/lib/concurrent/constants.rb +1 -1
 - data/lib/concurrent/dataflow.rb +2 -1
 - data/lib/concurrent/delay.rb +9 -7
 - data/lib/concurrent/exchanger.rb +21 -25
 - data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
 - data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
 - data/lib/concurrent/executor/executor_service.rb +15 -15
 - data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
 - data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
 - data/lib/concurrent/executor/single_thread_executor.rb +2 -2
 - data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
 - data/lib/concurrent/executor/timer_set.rb +1 -1
 - data/lib/concurrent/future.rb +4 -1
 - data/lib/concurrent/hash.rb +53 -30
 - data/lib/concurrent/ivar.rb +5 -6
 - data/lib/concurrent/map.rb +178 -81
 - data/lib/concurrent/maybe.rb +1 -1
 - data/lib/concurrent/mutable_struct.rb +15 -14
 - data/lib/concurrent/mvar.rb +2 -2
 - data/lib/concurrent/promise.rb +53 -21
 - data/lib/concurrent/promises.rb +1936 -0
 - data/lib/concurrent/re_include.rb +58 -0
 - data/lib/concurrent/set.rb +66 -0
 - data/lib/concurrent/settable_struct.rb +1 -0
 - data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
 - data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
 - data/lib/concurrent/synchronization/lockable_object.rb +6 -6
 - data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
 - data/lib/concurrent/synchronization/object.rb +8 -4
 - data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
 - data/lib/concurrent/synchronization/volatile.rb +11 -9
 - data/lib/concurrent/synchronization.rb +4 -5
 - data/lib/concurrent/thread_safe/util/data_structures.rb +63 -0
 - data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
 - data/lib/concurrent/timer_task.rb +5 -2
 - data/lib/concurrent/tuple.rb +1 -1
 - data/lib/concurrent/tvar.rb +2 -2
 - data/lib/concurrent/utility/193.rb +17 -0
 - data/lib/concurrent/utility/at_exit.rb +1 -1
 - data/lib/concurrent/utility/engine.rb +4 -4
 - data/lib/concurrent/utility/monotonic_time.rb +3 -3
 - data/lib/concurrent/utility/native_extension_loader.rb +31 -33
 - data/lib/concurrent/utility/processor_counter.rb +0 -2
 - data/lib/concurrent/version.rb +2 -2
 - data/lib/concurrent-ruby.rb +1 -0
 - data/lib/concurrent.rb +26 -20
 - metadata +33 -18
 - data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
 - data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
 - data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
 - data/lib/concurrent/atomic_reference/jruby.rb +0 -16
 - data/lib/concurrent/atomic_reference/rbx.rb +0 -22
 - data/lib/concurrent/atomic_reference/ruby.rb +0 -32
 - data/lib/concurrent/edge.rb +0 -26
 - data/lib/concurrent/lazy_register.rb +0 -81
 - data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
 - data/lib/concurrent/synchronization/truffle_object.rb +0 -31
 - data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
 
    
        data/lib/concurrent/map.rb
    CHANGED
    
    | 
         @@ -1,33 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'thread'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'concurrent/constants'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'concurrent/synchronization'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'concurrent/utility/engine'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Concurrent
         
     | 
| 
       6 
7 
     | 
    
         
             
              # @!visibility private
         
     | 
| 
       7 
8 
     | 
    
         
             
              module Collection
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
                # @!visibility private
         
     | 
| 
       10 
     | 
    
         
            -
                MapImplementation =  
     | 
| 
      
 11 
     | 
    
         
            +
                MapImplementation = case
         
     | 
| 
      
 12 
     | 
    
         
            +
                                    when Concurrent.on_jruby?
         
     | 
| 
       11 
13 
     | 
    
         
             
                                      # noinspection RubyResolve
         
     | 
| 
       12 
14 
     | 
    
         
             
                                      JRubyMapBackend
         
     | 
| 
       13 
     | 
    
         
            -
                                     
     | 
| 
       14 
     | 
    
         
            -
                                       
     | 
| 
       15 
     | 
    
         
            -
                                      when 'ruby'
         
     | 
| 
       16 
     | 
    
         
            -
                                        require 'concurrent/collection/map/mri_map_backend'
         
     | 
| 
       17 
     | 
    
         
            -
                                        MriMapBackend
         
     | 
| 
       18 
     | 
    
         
            -
                                      when 'rbx'
         
     | 
| 
       19 
     | 
    
         
            -
                                        require 'concurrent/collection/map/atomic_reference_map_backend'
         
     | 
| 
       20 
     | 
    
         
            -
                                        AtomicReferenceMapBackend
         
     | 
| 
       21 
     | 
    
         
            -
                                      when 'jruby+truffle'
         
     | 
| 
       22 
     | 
    
         
            -
                                        require 'concurrent/collection/map/atomic_reference_map_backend'
         
     | 
| 
       23 
     | 
    
         
            -
                                        AtomicReferenceMapBackend
         
     | 
| 
       24 
     | 
    
         
            -
                                      else
         
     | 
| 
       25 
     | 
    
         
            -
                                        warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' if $VERBOSE
         
     | 
| 
       26 
     | 
    
         
            -
                                        require 'concurrent/collection/map/synchronized_map_backend'
         
     | 
| 
       27 
     | 
    
         
            -
                                        SynchronizedMapBackend
         
     | 
| 
       28 
     | 
    
         
            -
                                      end
         
     | 
| 
       29 
     | 
    
         
            -
                                    else
         
     | 
| 
      
 15 
     | 
    
         
            +
                                    when Concurrent.on_cruby?
         
     | 
| 
      
 16 
     | 
    
         
            +
                                      require 'concurrent/collection/map/mri_map_backend'
         
     | 
| 
       30 
17 
     | 
    
         
             
                                      MriMapBackend
         
     | 
| 
      
 18 
     | 
    
         
            +
                                    when Concurrent.on_rbx? || Concurrent.on_truffleruby?
         
     | 
| 
      
 19 
     | 
    
         
            +
                                      require 'concurrent/collection/map/atomic_reference_map_backend'
         
     | 
| 
      
 20 
     | 
    
         
            +
                                      AtomicReferenceMapBackend
         
     | 
| 
      
 21 
     | 
    
         
            +
                                    else
         
     | 
| 
      
 22 
     | 
    
         
            +
                                      warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation'
         
     | 
| 
      
 23 
     | 
    
         
            +
                                      require 'concurrent/collection/map/synchronized_map_backend'
         
     | 
| 
      
 24 
     | 
    
         
            +
                                      SynchronizedMapBackend
         
     | 
| 
       31 
25 
     | 
    
         
             
                                    end
         
     | 
| 
       32 
26 
     | 
    
         
             
              end
         
     | 
| 
       33 
27 
     | 
    
         | 
| 
         @@ -37,46 +31,89 @@ module Concurrent 
     | 
|
| 
       37 
31 
     | 
    
         
             
              # -- for instance, it does not necessarily retain ordering by insertion time as `Hash`
         
     | 
| 
       38 
32 
     | 
    
         
             
              # does. For most uses it should do fine though, and we recommend you consider
         
     | 
| 
       39 
33 
     | 
    
         
             
              # `Concurrent::Map` instead of `Concurrent::Hash` for your concurrency-safe hash needs.
         
     | 
| 
       40 
     | 
    
         
            -
              #
         
     | 
| 
       41 
     | 
    
         
            -
              # > require 'concurrent'
         
     | 
| 
       42 
     | 
    
         
            -
              # >
         
     | 
| 
       43 
     | 
    
         
            -
              # > map = Concurrent::Map.new
         
     | 
| 
       44 
34 
     | 
    
         
             
              class Map < Collection::MapImplementation
         
     | 
| 
       45 
35 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                # @!macro  
     | 
| 
       47 
     | 
    
         
            -
                #   This method is atomic. 
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                # 
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                #  
     | 
| 
       52 
     | 
    
         
            -
                # 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                # @!method compute_if_absent
         
     | 
| 
       55 
     | 
    
         
            -
                #    
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                #  
     | 
| 
       58 
     | 
    
         
            -
                #    
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                # 
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                #  
     | 
| 
       64 
     | 
    
         
            -
                #    
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                #  
     | 
| 
       67 
     | 
    
         
            -
                #    
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                # 
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                #  
     | 
| 
       73 
     | 
    
         
            -
                #    
     | 
| 
      
 36 
     | 
    
         
            +
                # @!macro map.atomic_method
         
     | 
| 
      
 37 
     | 
    
         
            +
                #   This method is atomic.
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                # @!macro map.atomic_method_with_block
         
     | 
| 
      
 40 
     | 
    
         
            +
                #   This method is atomic.
         
     | 
| 
      
 41 
     | 
    
         
            +
                #   @note Atomic methods taking a block do not allow the `self` instance
         
     | 
| 
      
 42 
     | 
    
         
            +
                #     to be used within the block. Doing so will cause a deadlock.
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # @!method compute_if_absent(key)
         
     | 
| 
      
 45 
     | 
    
         
            +
                #   Compute and store new value for key if the key is absent.
         
     | 
| 
      
 46 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 47 
     | 
    
         
            +
                #   @yield new value
         
     | 
| 
      
 48 
     | 
    
         
            +
                #   @yieldreturn [Object] new value
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   @return [Object] new value or current value
         
     | 
| 
      
 50 
     | 
    
         
            +
                #   @!macro map.atomic_method_with_block
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                # @!method compute_if_present(key)
         
     | 
| 
      
 53 
     | 
    
         
            +
                #   Compute and store new value for key if the key is present.
         
     | 
| 
      
 54 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 55 
     | 
    
         
            +
                #   @yield new value
         
     | 
| 
      
 56 
     | 
    
         
            +
                #   @yieldparam old_value [Object]
         
     | 
| 
      
 57 
     | 
    
         
            +
                #   @yieldreturn [Object, nil] new value, when nil the key is removed
         
     | 
| 
      
 58 
     | 
    
         
            +
                #   @return [Object, nil] new value or nil
         
     | 
| 
      
 59 
     | 
    
         
            +
                #   @!macro map.atomic_method_with_block
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                # @!method compute(key)
         
     | 
| 
      
 62 
     | 
    
         
            +
                #   Compute and store new value for key.
         
     | 
| 
      
 63 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 64 
     | 
    
         
            +
                #   @yield compute new value from old one
         
     | 
| 
      
 65 
     | 
    
         
            +
                #   @yieldparam old_value [Object, nil] old_value, or nil when key is absent
         
     | 
| 
      
 66 
     | 
    
         
            +
                #   @yieldreturn [Object, nil] new value, when nil the key is removed
         
     | 
| 
      
 67 
     | 
    
         
            +
                #   @return [Object, nil] new value or nil
         
     | 
| 
      
 68 
     | 
    
         
            +
                #   @!macro map.atomic_method_with_block
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                # @!method merge_pair(key, value)
         
     | 
| 
      
 71 
     | 
    
         
            +
                #   If the key is absent, the value is stored, otherwise new value is
         
     | 
| 
      
 72 
     | 
    
         
            +
                #   computed with a block.
         
     | 
| 
      
 73 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 74 
     | 
    
         
            +
                #   @param [Object] value
         
     | 
| 
      
 75 
     | 
    
         
            +
                #   @yield compute new value from old one
         
     | 
| 
      
 76 
     | 
    
         
            +
                #   @yieldparam old_value [Object] old value
         
     | 
| 
      
 77 
     | 
    
         
            +
                #   @yieldreturn [Object, nil] new value, when nil the key is removed
         
     | 
| 
      
 78 
     | 
    
         
            +
                #   @return [Object, nil] new value or nil
         
     | 
| 
      
 79 
     | 
    
         
            +
                #   @!macro map.atomic_method_with_block
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                # @!method replace_pair(key, old_value, new_value)
         
     | 
| 
      
 82 
     | 
    
         
            +
                #   Replaces old_value with new_value if key exists and current value
         
     | 
| 
      
 83 
     | 
    
         
            +
                #   matches old_value
         
     | 
| 
      
 84 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 85 
     | 
    
         
            +
                #   @param [Object] old_value
         
     | 
| 
      
 86 
     | 
    
         
            +
                #   @param [Object] new_value
         
     | 
| 
      
 87 
     | 
    
         
            +
                #   @return [true, false] true if replaced
         
     | 
| 
      
 88 
     | 
    
         
            +
                #   @!macro map.atomic_method
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                # @!method replace_if_exists(key, new_value)
         
     | 
| 
      
 91 
     | 
    
         
            +
                #   Replaces current value with new_value if key exists
         
     | 
| 
      
 92 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 93 
     | 
    
         
            +
                #   @param [Object] new_value
         
     | 
| 
      
 94 
     | 
    
         
            +
                #   @return [Object, nil] old value or nil
         
     | 
| 
      
 95 
     | 
    
         
            +
                #   @!macro map.atomic_method
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                # @!method get_and_set(key, value)
         
     | 
| 
      
 98 
     | 
    
         
            +
                #   Get the current value under key and set new value.
         
     | 
| 
      
 99 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 100 
     | 
    
         
            +
                #   @param [Object] value
         
     | 
| 
      
 101 
     | 
    
         
            +
                #   @return [Object, nil] old value or nil when the key was absent
         
     | 
| 
      
 102 
     | 
    
         
            +
                #   @!macro map.atomic_method
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                # @!method delete(key)
         
     | 
| 
      
 105 
     | 
    
         
            +
                #   Delete key and its value.
         
     | 
| 
      
 106 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 107 
     | 
    
         
            +
                #   @return [Object, nil] old value or nil when the key was absent
         
     | 
| 
      
 108 
     | 
    
         
            +
                #   @!macro map.atomic_method
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                # @!method delete_pair(key, value)
         
     | 
| 
      
 111 
     | 
    
         
            +
                #   Delete pair and its value if current value equals the provided value.
         
     | 
| 
      
 112 
     | 
    
         
            +
                #   @param [Object] key
         
     | 
| 
      
 113 
     | 
    
         
            +
                #   @param [Object] value
         
     | 
| 
      
 114 
     | 
    
         
            +
                #   @return [true, false] true if deleted
         
     | 
| 
      
 115 
     | 
    
         
            +
                #   @!macro map.atomic_method
         
     | 
| 
       74 
116 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
                # @!method delete
         
     | 
| 
       76 
     | 
    
         
            -
                #   @!macro map_method_is_atomic
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                # @!method delete_pair
         
     | 
| 
       79 
     | 
    
         
            -
                #   @!macro map_method_is_atomic
         
     | 
| 
       80 
117 
     | 
    
         | 
| 
       81 
118 
     | 
    
         
             
                def initialize(options = nil, &block)
         
     | 
| 
       82 
119 
     | 
    
         
             
                  if options.kind_of?(::Hash)
         
     | 
| 
         @@ -89,6 +126,9 @@ module Concurrent 
     | 
|
| 
       89 
126 
     | 
    
         
             
                  @default_proc = block
         
     | 
| 
       90 
127 
     | 
    
         
             
                end
         
     | 
| 
       91 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
                # Get a value with key
         
     | 
| 
      
 130 
     | 
    
         
            +
                # @param [Object] key
         
     | 
| 
      
 131 
     | 
    
         
            +
                # @return [Object] the value
         
     | 
| 
       92 
132 
     | 
    
         
             
                def [](key)
         
     | 
| 
       93 
133 
     | 
    
         
             
                  if value = super # non-falsy value is an existing mapping, return it right away
         
     | 
| 
       94 
134 
     | 
    
         
             
                    value
         
     | 
| 
         @@ -104,17 +144,27 @@ module Concurrent 
     | 
|
| 
       104 
144 
     | 
    
         
             
                end
         
     | 
| 
       105 
145 
     | 
    
         | 
| 
       106 
146 
     | 
    
         
             
                alias_method :get, :[]
         
     | 
| 
      
 147 
     | 
    
         
            +
                # TODO (pitr-ch 30-Oct-2018): doc
         
     | 
| 
       107 
148 
     | 
    
         
             
                alias_method :put, :[]=
         
     | 
| 
       108 
149 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                #  
     | 
| 
       110 
     | 
    
         
            -
                # 
     | 
| 
       111 
     | 
    
         
            -
                # 
     | 
| 
       112 
     | 
    
         
            -
                # 
     | 
| 
       113 
     | 
    
         
            -
                # 
     | 
| 
       114 
     | 
    
         
            -
                # 
     | 
| 
       115 
     | 
    
         
            -
                # 
     | 
| 
       116 
     | 
    
         
            -
                # 
     | 
| 
       117 
     | 
    
         
            -
                # 
     | 
| 
      
 150 
     | 
    
         
            +
                # Get a value with key, or default_value when key is absent,
         
     | 
| 
      
 151 
     | 
    
         
            +
                # or fail when no default_value is given.
         
     | 
| 
      
 152 
     | 
    
         
            +
                # @param [Object] key
         
     | 
| 
      
 153 
     | 
    
         
            +
                # @param [Object] default_value
         
     | 
| 
      
 154 
     | 
    
         
            +
                # @yield default value for a key
         
     | 
| 
      
 155 
     | 
    
         
            +
                # @yieldparam key [Object]
         
     | 
| 
      
 156 
     | 
    
         
            +
                # @yieldreturn [Object] default value
         
     | 
| 
      
 157 
     | 
    
         
            +
                # @return [Object] the value or default value
         
     | 
| 
      
 158 
     | 
    
         
            +
                # @raise [KeyError] when key is missing and no default_value is provided
         
     | 
| 
      
 159 
     | 
    
         
            +
                # @!macro map_method_not_atomic
         
     | 
| 
      
 160 
     | 
    
         
            +
                #   @note The "fetch-then-act" methods of `Map` are not atomic. `Map` is intended
         
     | 
| 
      
 161 
     | 
    
         
            +
                #     to be use as a concurrency primitive with strong happens-before
         
     | 
| 
      
 162 
     | 
    
         
            +
                #     guarantees. It is not intended to be used as a high-level abstraction
         
     | 
| 
      
 163 
     | 
    
         
            +
                #     supporting complex operations. All read and write operations are
         
     | 
| 
      
 164 
     | 
    
         
            +
                #     thread safe, but no guarantees are made regarding race conditions
         
     | 
| 
      
 165 
     | 
    
         
            +
                #     between the fetch operation and yielding to the block. Additionally,
         
     | 
| 
      
 166 
     | 
    
         
            +
                #     this method does not support recursion. This is due to internal
         
     | 
| 
      
 167 
     | 
    
         
            +
                #     constraints that are very unlikely to change in the near future.
         
     | 
| 
       118 
168 
     | 
    
         
             
                def fetch(key, default_value = NULL)
         
     | 
| 
       119 
169 
     | 
    
         
             
                  if NULL != (value = get_or_default(key, NULL))
         
     | 
| 
       120 
170 
     | 
    
         
             
                    value
         
     | 
| 
         @@ -127,23 +177,39 @@ module Concurrent 
     | 
|
| 
       127 
177 
     | 
    
         
             
                  end
         
     | 
| 
       128 
178 
     | 
    
         
             
                end
         
     | 
| 
       129 
179 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                #  
     | 
| 
      
 180 
     | 
    
         
            +
                # Fetch value with key, or store default value when key is absent,
         
     | 
| 
      
 181 
     | 
    
         
            +
                # or fail when no default_value is given. This is a two step operation,
         
     | 
| 
      
 182 
     | 
    
         
            +
                # therefore not atomic. The store can overwrite other concurrently
         
     | 
| 
      
 183 
     | 
    
         
            +
                # stored value.
         
     | 
| 
      
 184 
     | 
    
         
            +
                # @param [Object] key
         
     | 
| 
      
 185 
     | 
    
         
            +
                # @param [Object] default_value
         
     | 
| 
      
 186 
     | 
    
         
            +
                # @yield default value for a key
         
     | 
| 
      
 187 
     | 
    
         
            +
                # @yieldparam key [Object]
         
     | 
| 
      
 188 
     | 
    
         
            +
                # @yieldreturn [Object] default value
         
     | 
| 
      
 189 
     | 
    
         
            +
                # @return [Object] the value or default value
         
     | 
| 
      
 190 
     | 
    
         
            +
                # @!macro map.atomic_method_with_block
         
     | 
| 
       131 
191 
     | 
    
         
             
                def fetch_or_store(key, default_value = NULL)
         
     | 
| 
       132 
192 
     | 
    
         
             
                  fetch(key) do
         
     | 
| 
       133 
193 
     | 
    
         
             
                    put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value))
         
     | 
| 
       134 
194 
     | 
    
         
             
                  end
         
     | 
| 
       135 
195 
     | 
    
         
             
                end
         
     | 
| 
       136 
196 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
                #  
     | 
| 
      
 197 
     | 
    
         
            +
                # Insert value into map with key if key is absent in one atomic step.
         
     | 
| 
      
 198 
     | 
    
         
            +
                # @param [Object] key
         
     | 
| 
      
 199 
     | 
    
         
            +
                # @param [Object] value
         
     | 
| 
      
 200 
     | 
    
         
            +
                # @return [Object, nil] the value or nil when key was present
         
     | 
| 
       138 
201 
     | 
    
         
             
                def put_if_absent(key, value)
         
     | 
| 
       139 
202 
     | 
    
         
             
                  computed = false
         
     | 
| 
       140 
     | 
    
         
            -
                  result 
     | 
| 
      
 203 
     | 
    
         
            +
                  result   = compute_if_absent(key) do
         
     | 
| 
       141 
204 
     | 
    
         
             
                    computed = true
         
     | 
| 
       142 
205 
     | 
    
         
             
                    value
         
     | 
| 
       143 
206 
     | 
    
         
             
                  end
         
     | 
| 
       144 
207 
     | 
    
         
             
                  computed ? nil : result
         
     | 
| 
       145 
208 
     | 
    
         
             
                end unless method_defined?(:put_if_absent)
         
     | 
| 
       146 
209 
     | 
    
         | 
| 
      
 210 
     | 
    
         
            +
                # Is the value stored in the map. Iterates over all values.
         
     | 
| 
      
 211 
     | 
    
         
            +
                # @param [Object] value
         
     | 
| 
      
 212 
     | 
    
         
            +
                # @return [true, false]
         
     | 
| 
       147 
213 
     | 
    
         
             
                def value?(value)
         
     | 
| 
       148 
214 
     | 
    
         
             
                  each_value do |v|
         
     | 
| 
       149 
215 
     | 
    
         
             
                    return true if value.equal?(v)
         
     | 
| 
         @@ -151,52 +217,86 @@ module Concurrent 
     | 
|
| 
       151 
217 
     | 
    
         
             
                  false
         
     | 
| 
       152 
218 
     | 
    
         
             
                end
         
     | 
| 
       153 
219 
     | 
    
         | 
| 
      
 220 
     | 
    
         
            +
                # All keys
         
     | 
| 
      
 221 
     | 
    
         
            +
                # @return [::Array<Object>] keys
         
     | 
| 
       154 
222 
     | 
    
         
             
                def keys
         
     | 
| 
       155 
223 
     | 
    
         
             
                  arr = []
         
     | 
| 
       156 
     | 
    
         
            -
                  each_pair {|k, v| arr << k}
         
     | 
| 
      
 224 
     | 
    
         
            +
                  each_pair { |k, v| arr << k }
         
     | 
| 
       157 
225 
     | 
    
         
             
                  arr
         
     | 
| 
       158 
226 
     | 
    
         
             
                end unless method_defined?(:keys)
         
     | 
| 
       159 
227 
     | 
    
         | 
| 
      
 228 
     | 
    
         
            +
                # All values
         
     | 
| 
      
 229 
     | 
    
         
            +
                # @return [::Array<Object>] values
         
     | 
| 
       160 
230 
     | 
    
         
             
                def values
         
     | 
| 
       161 
231 
     | 
    
         
             
                  arr = []
         
     | 
| 
       162 
     | 
    
         
            -
                  each_pair {|k, v| arr << v}
         
     | 
| 
      
 232 
     | 
    
         
            +
                  each_pair { |k, v| arr << v }
         
     | 
| 
       163 
233 
     | 
    
         
             
                  arr
         
     | 
| 
       164 
234 
     | 
    
         
             
                end unless method_defined?(:values)
         
     | 
| 
       165 
235 
     | 
    
         | 
| 
      
 236 
     | 
    
         
            +
                # Iterates over each key.
         
     | 
| 
      
 237 
     | 
    
         
            +
                # @yield for each key in the map
         
     | 
| 
      
 238 
     | 
    
         
            +
                # @yieldparam key [Object]
         
     | 
| 
      
 239 
     | 
    
         
            +
                # @return [self]
         
     | 
| 
      
 240 
     | 
    
         
            +
                # @!macro map.atomic_method_with_block
         
     | 
| 
       166 
241 
     | 
    
         
             
                def each_key
         
     | 
| 
       167 
     | 
    
         
            -
                  each_pair {|k, v| yield k}
         
     | 
| 
      
 242 
     | 
    
         
            +
                  each_pair { |k, v| yield k }
         
     | 
| 
       168 
243 
     | 
    
         
             
                end unless method_defined?(:each_key)
         
     | 
| 
       169 
244 
     | 
    
         | 
| 
      
 245 
     | 
    
         
            +
                # Iterates over each value.
         
     | 
| 
      
 246 
     | 
    
         
            +
                # @yield for each value in the map
         
     | 
| 
      
 247 
     | 
    
         
            +
                # @yieldparam value [Object]
         
     | 
| 
      
 248 
     | 
    
         
            +
                # @return [self]
         
     | 
| 
      
 249 
     | 
    
         
            +
                # @!macro map.atomic_method_with_block
         
     | 
| 
       170 
250 
     | 
    
         
             
                def each_value
         
     | 
| 
       171 
     | 
    
         
            -
                  each_pair {|k, v| yield v}
         
     | 
| 
      
 251 
     | 
    
         
            +
                  each_pair { |k, v| yield v }
         
     | 
| 
       172 
252 
     | 
    
         
             
                end unless method_defined?(:each_value)
         
     | 
| 
       173 
253 
     | 
    
         | 
| 
      
 254 
     | 
    
         
            +
                # Iterates over each key value pair.
         
     | 
| 
      
 255 
     | 
    
         
            +
                # @yield for each key value pair in the map
         
     | 
| 
      
 256 
     | 
    
         
            +
                # @yieldparam key [Object]
         
     | 
| 
      
 257 
     | 
    
         
            +
                # @yieldparam value [Object]
         
     | 
| 
      
 258 
     | 
    
         
            +
                # @return [self]
         
     | 
| 
      
 259 
     | 
    
         
            +
                # @!macro map.atomic_method_with_block
         
     | 
| 
      
 260 
     | 
    
         
            +
                def each_pair
         
     | 
| 
      
 261 
     | 
    
         
            +
                  return enum_for :each_pair unless block_given?
         
     | 
| 
      
 262 
     | 
    
         
            +
                  super
         
     | 
| 
      
 263 
     | 
    
         
            +
                end
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
       174 
265 
     | 
    
         
             
                alias_method :each, :each_pair unless method_defined?(:each)
         
     | 
| 
       175 
266 
     | 
    
         | 
| 
      
 267 
     | 
    
         
            +
                # Find key of a value.
         
     | 
| 
      
 268 
     | 
    
         
            +
                # @param [Object] value
         
     | 
| 
      
 269 
     | 
    
         
            +
                # @return [Object, nil] key or nil when not found
         
     | 
| 
       176 
270 
     | 
    
         
             
                def key(value)
         
     | 
| 
       177 
     | 
    
         
            -
                  each_pair {|k, v| return k if v == value}
         
     | 
| 
      
 271 
     | 
    
         
            +
                  each_pair { |k, v| return k if v == value }
         
     | 
| 
       178 
272 
     | 
    
         
             
                  nil
         
     | 
| 
       179 
273 
     | 
    
         
             
                end unless method_defined?(:key)
         
     | 
| 
       180 
274 
     | 
    
         
             
                alias_method :index, :key if RUBY_VERSION < '1.9'
         
     | 
| 
       181 
275 
     | 
    
         | 
| 
      
 276 
     | 
    
         
            +
                # Is map empty?
         
     | 
| 
      
 277 
     | 
    
         
            +
                # @return [true, false]
         
     | 
| 
       182 
278 
     | 
    
         
             
                def empty?
         
     | 
| 
       183 
     | 
    
         
            -
                  each_pair {|k, v| return false}
         
     | 
| 
      
 279 
     | 
    
         
            +
                  each_pair { |k, v| return false }
         
     | 
| 
       184 
280 
     | 
    
         
             
                  true
         
     | 
| 
       185 
281 
     | 
    
         
             
                end unless method_defined?(:empty?)
         
     | 
| 
       186 
282 
     | 
    
         | 
| 
      
 283 
     | 
    
         
            +
                # The size of map.
         
     | 
| 
      
 284 
     | 
    
         
            +
                # @return [Integer] size
         
     | 
| 
       187 
285 
     | 
    
         
             
                def size
         
     | 
| 
       188 
286 
     | 
    
         
             
                  count = 0
         
     | 
| 
       189 
     | 
    
         
            -
                  each_pair {|k, v| count += 1}
         
     | 
| 
      
 287 
     | 
    
         
            +
                  each_pair { |k, v| count += 1 }
         
     | 
| 
       190 
288 
     | 
    
         
             
                  count
         
     | 
| 
       191 
289 
     | 
    
         
             
                end unless method_defined?(:size)
         
     | 
| 
       192 
290 
     | 
    
         | 
| 
      
 291 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
       193 
292 
     | 
    
         
             
                def marshal_dump
         
     | 
| 
       194 
293 
     | 
    
         
             
                  raise TypeError, "can't dump hash with default proc" if @default_proc
         
     | 
| 
       195 
294 
     | 
    
         
             
                  h = {}
         
     | 
| 
       196 
     | 
    
         
            -
                  each_pair {|k, v| h[k] = v}
         
     | 
| 
      
 295 
     | 
    
         
            +
                  each_pair { |k, v| h[k] = v }
         
     | 
| 
       197 
296 
     | 
    
         
             
                  h
         
     | 
| 
       198 
297 
     | 
    
         
             
                end
         
     | 
| 
       199 
298 
     | 
    
         | 
| 
      
 299 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
       200 
300 
     | 
    
         
             
                def marshal_load(hash)
         
     | 
| 
       201 
301 
     | 
    
         
             
                  initialize
         
     | 
| 
       202 
302 
     | 
    
         
             
                  populate_from(hash)
         
     | 
| 
         @@ -205,15 +305,12 @@ module Concurrent 
     | 
|
| 
       205 
305 
     | 
    
         
             
                undef :freeze
         
     | 
| 
       206 
306 
     | 
    
         | 
| 
       207 
307 
     | 
    
         
             
                # @!visibility private
         
     | 
| 
       208 
     | 
    
         
            -
                DEFAULT_OBJ_ID_STR_WIDTH = 0.size == 4 ? 7 : 14 # we want to look "native", 7 for 32-bit, 14 for 64-bit
         
     | 
| 
       209 
     | 
    
         
            -
                # override default #inspect() method: firstly, we don't want to be spilling our guts (i-vars), secondly, MRI backend's
         
     | 
| 
       210 
     | 
    
         
            -
                # #inspect() call on its @backend i-var will bump @backend's iter level while possibly yielding GVL
         
     | 
| 
       211 
308 
     | 
    
         
             
                def inspect
         
     | 
| 
       212 
     | 
    
         
            -
                   
     | 
| 
       213 
     | 
    
         
            -
                  "#<#{self.class.name}:0x#{id_str} entries=#{size} default_proc=#{@default_proc.inspect}>"
         
     | 
| 
      
 309 
     | 
    
         
            +
                  format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect
         
     | 
| 
       214 
310 
     | 
    
         
             
                end
         
     | 
| 
       215 
311 
     | 
    
         | 
| 
       216 
312 
     | 
    
         
             
                private
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
       217 
314 
     | 
    
         
             
                def raise_fetch_no_key
         
     | 
| 
       218 
315 
     | 
    
         
             
                  raise KeyError, 'key not found'
         
     | 
| 
       219 
316 
     | 
    
         
             
                end
         
     | 
| 
         @@ -224,7 +321,7 @@ module Concurrent 
     | 
|
| 
       224 
321 
     | 
    
         
             
                end
         
     | 
| 
       225 
322 
     | 
    
         | 
| 
       226 
323 
     | 
    
         
             
                def populate_from(hash)
         
     | 
| 
       227 
     | 
    
         
            -
                  hash.each_pair {|k, v| self[k] = v}
         
     | 
| 
      
 324 
     | 
    
         
            +
                  hash.each_pair { |k, v| self[k] = v }
         
     | 
| 
       228 
325 
     | 
    
         
             
                  self
         
     | 
| 
       229 
326 
     | 
    
         
             
                end
         
     | 
| 
       230 
327 
     | 
    
         | 
    
        data/lib/concurrent/maybe.rb
    CHANGED
    
    | 
         @@ -108,7 +108,7 @@ module Concurrent 
     | 
|
| 
       108 
108 
     | 
    
         
             
                # Indicates that the given attribute has not been set.
         
     | 
| 
       109 
109 
     | 
    
         
             
                # When `Just` the {#nothing} getter will return `NONE`.
         
     | 
| 
       110 
110 
     | 
    
         
             
                # When `Nothing` the {#just} getter will return `NONE`.
         
     | 
| 
       111 
     | 
    
         
            -
                NONE = Object.new.freeze
         
     | 
| 
      
 111 
     | 
    
         
            +
                NONE = ::Object.new.freeze
         
     | 
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
                # The value of a `Maybe` when `Just`. Will be `NONE` when `Nothing`.
         
     | 
| 
       114 
114 
     | 
    
         
             
                attr_reader :just
         
     | 
| 
         @@ -10,7 +10,7 @@ module Concurrent 
     | 
|
| 
       10 
10 
     | 
    
         
             
              module MutableStruct
         
     | 
| 
       11 
11 
     | 
    
         
             
                include Synchronization::AbstractStruct
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 13 
     | 
    
         
            +
                # @!macro struct_new
         
     | 
| 
       14 
14 
     | 
    
         
             
                #
         
     | 
| 
       15 
15 
     | 
    
         
             
                #   Factory for creating new struct classes.
         
     | 
| 
       16 
16 
     | 
    
         
             
                #
         
     | 
| 
         @@ -42,7 +42,7 @@ module Concurrent 
     | 
|
| 
       42 
42 
     | 
    
         
             
                #
         
     | 
| 
       43 
43 
     | 
    
         
             
                #   @see http://ruby-doc.org/core-2.2.0/Struct.html#method-c-new Ruby standard library `Struct#new`
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 45 
     | 
    
         
            +
                # @!macro struct_values
         
     | 
| 
       46 
46 
     | 
    
         
             
                #
         
     | 
| 
       47 
47 
     | 
    
         
             
                #   Returns the values for this struct as an Array.
         
     | 
| 
       48 
48 
     | 
    
         
             
                #
         
     | 
| 
         @@ -53,7 +53,7 @@ module Concurrent 
     | 
|
| 
       53 
53 
     | 
    
         
             
                end
         
     | 
| 
       54 
54 
     | 
    
         
             
                alias_method :to_a, :values
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 56 
     | 
    
         
            +
                # @!macro struct_values_at
         
     | 
| 
       57 
57 
     | 
    
         
             
                #
         
     | 
| 
       58 
58 
     | 
    
         
             
                #   Returns the struct member values for each selector as an Array.
         
     | 
| 
       59 
59 
     | 
    
         
             
                #
         
     | 
| 
         @@ -64,7 +64,7 @@ module Concurrent 
     | 
|
| 
       64 
64 
     | 
    
         
             
                  synchronize { ns_values_at(indexes) }
         
     | 
| 
       65 
65 
     | 
    
         
             
                end
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 67 
     | 
    
         
            +
                # @!macro struct_inspect
         
     | 
| 
       68 
68 
     | 
    
         
             
                #
         
     | 
| 
       69 
69 
     | 
    
         
             
                #   Describe the contents of this struct in a string.
         
     | 
| 
       70 
70 
     | 
    
         
             
                #
         
     | 
| 
         @@ -74,7 +74,7 @@ module Concurrent 
     | 
|
| 
       74 
74 
     | 
    
         
             
                end
         
     | 
| 
       75 
75 
     | 
    
         
             
                alias_method :to_s, :inspect
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 77 
     | 
    
         
            +
                # @!macro struct_merge
         
     | 
| 
       78 
78 
     | 
    
         
             
                #
         
     | 
| 
       79 
79 
     | 
    
         
             
                #   Returns a new struct containing the contents of `other` and the contents
         
     | 
| 
       80 
80 
     | 
    
         
             
                #   of `self`. If no block is specified, the value for entries with duplicate
         
     | 
| 
         @@ -95,7 +95,7 @@ module Concurrent 
     | 
|
| 
       95 
95 
     | 
    
         
             
                  synchronize { ns_merge(other, &block) }
         
     | 
| 
       96 
96 
     | 
    
         
             
                end
         
     | 
| 
       97 
97 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 98 
     | 
    
         
            +
                # @!macro struct_to_h
         
     | 
| 
       99 
99 
     | 
    
         
             
                #
         
     | 
| 
       100 
100 
     | 
    
         
             
                #   Returns a hash containing the names and values for the struct’s members.
         
     | 
| 
       101 
101 
     | 
    
         
             
                #
         
     | 
| 
         @@ -104,11 +104,11 @@ module Concurrent 
     | 
|
| 
       104 
104 
     | 
    
         
             
                  synchronize { ns_to_h }
         
     | 
| 
       105 
105 
     | 
    
         
             
                end
         
     | 
| 
       106 
106 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 107 
     | 
    
         
            +
                # @!macro struct_get
         
     | 
| 
       108 
108 
     | 
    
         
             
                #
         
     | 
| 
       109 
109 
     | 
    
         
             
                #   Attribute Reference
         
     | 
| 
       110 
110 
     | 
    
         
             
                #
         
     | 
| 
       111 
     | 
    
         
            -
                #   @param [Symbol, String, Integer] member the string or symbol name of the  
     | 
| 
      
 111 
     | 
    
         
            +
                #   @param [Symbol, String, Integer] member the string or symbol name of the member
         
     | 
| 
       112 
112 
     | 
    
         
             
                #     for which to obtain the value or the member's index
         
     | 
| 
       113 
113 
     | 
    
         
             
                #
         
     | 
| 
       114 
114 
     | 
    
         
             
                #   @return [Object] the value of the given struct member or the member at the given index.
         
     | 
| 
         @@ -119,7 +119,7 @@ module Concurrent 
     | 
|
| 
       119 
119 
     | 
    
         
             
                  synchronize { ns_get(member) }
         
     | 
| 
       120 
120 
     | 
    
         
             
                end
         
     | 
| 
       121 
121 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 122 
     | 
    
         
            +
                # @!macro struct_equality
         
     | 
| 
       123 
123 
     | 
    
         
             
                #
         
     | 
| 
       124 
124 
     | 
    
         
             
                #   Equality
         
     | 
| 
       125 
125 
     | 
    
         
             
                #
         
     | 
| 
         @@ -129,7 +129,7 @@ module Concurrent 
     | 
|
| 
       129 
129 
     | 
    
         
             
                  synchronize { ns_equality(other) }
         
     | 
| 
       130 
130 
     | 
    
         
             
                end
         
     | 
| 
       131 
131 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 132 
     | 
    
         
            +
                # @!macro struct_each
         
     | 
| 
       133 
133 
     | 
    
         
             
                #
         
     | 
| 
       134 
134 
     | 
    
         
             
                #   Yields the value of each struct member in order. If no block is given
         
     | 
| 
       135 
135 
     | 
    
         
             
                #   an enumerator is returned.
         
     | 
| 
         @@ -141,7 +141,7 @@ module Concurrent 
     | 
|
| 
       141 
141 
     | 
    
         
             
                  synchronize { ns_each(&block) }
         
     | 
| 
       142 
142 
     | 
    
         
             
                end
         
     | 
| 
       143 
143 
     | 
    
         | 
| 
       144 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 144 
     | 
    
         
            +
                # @!macro struct_each_pair
         
     | 
| 
       145 
145 
     | 
    
         
             
                #
         
     | 
| 
       146 
146 
     | 
    
         
             
                #   Yields the name and value of each struct member in order. If no block is
         
     | 
| 
       147 
147 
     | 
    
         
             
                #   given an enumerator is returned.
         
     | 
| 
         @@ -154,7 +154,7 @@ module Concurrent 
     | 
|
| 
       154 
154 
     | 
    
         
             
                  synchronize { ns_each_pair(&block) }
         
     | 
| 
       155 
155 
     | 
    
         
             
                end
         
     | 
| 
       156 
156 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 157 
     | 
    
         
            +
                # @!macro struct_select
         
     | 
| 
       158 
158 
     | 
    
         
             
                #
         
     | 
| 
       159 
159 
     | 
    
         
             
                #   Yields each member value from the struct to the block and returns an Array
         
     | 
| 
       160 
160 
     | 
    
         
             
                #   containing the member values from the struct for which the given block
         
     | 
| 
         @@ -169,13 +169,13 @@ module Concurrent 
     | 
|
| 
       169 
169 
     | 
    
         
             
                  synchronize { ns_select(&block) }
         
     | 
| 
       170 
170 
     | 
    
         
             
                end
         
     | 
| 
       171 
171 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 172 
     | 
    
         
            +
                # @!macro struct_set
         
     | 
| 
       173 
173 
     | 
    
         
             
                #
         
     | 
| 
       174 
174 
     | 
    
         
             
                #   Attribute Assignment
         
     | 
| 
       175 
175 
     | 
    
         
             
                #
         
     | 
| 
       176 
176 
     | 
    
         
             
                #   Sets the value of the given struct member or the member at the given index.
         
     | 
| 
       177 
177 
     | 
    
         
             
                #
         
     | 
| 
       178 
     | 
    
         
            -
                #   @param [Symbol, String, Integer] member the string or symbol name of the  
     | 
| 
      
 178 
     | 
    
         
            +
                #   @param [Symbol, String, Integer] member the string or symbol name of the member
         
     | 
| 
       179 
179 
     | 
    
         
             
                #     for which to obtain the value or the member's index
         
     | 
| 
       180 
180 
     | 
    
         
             
                #
         
     | 
| 
       181 
181 
     | 
    
         
             
                #   @return [Object] the value of the given struct member or the member at the given index.
         
     | 
| 
         @@ -212,6 +212,7 @@ module Concurrent 
     | 
|
| 
       212 
212 
     | 
    
         
             
                    synchronize do
         
     | 
| 
       213 
213 
     | 
    
         
             
                      clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block)
         
     | 
| 
       214 
214 
     | 
    
         
             
                      members.each_with_index do |member, index|
         
     | 
| 
      
 215 
     | 
    
         
            +
                        clazz.send :remove_method, member
         
     | 
| 
       215 
216 
     | 
    
         
             
                        clazz.send(:define_method, member) do
         
     | 
| 
       216 
217 
     | 
    
         
             
                          synchronize { @values[index] }
         
     | 
| 
       217 
218 
     | 
    
         
             
                        end
         
     | 
    
        data/lib/concurrent/mvar.rb
    CHANGED
    
    | 
         @@ -40,11 +40,11 @@ module Concurrent 
     | 
|
| 
       40 
40 
     | 
    
         
             
                safe_initialization!
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                # Unique value that represents that an `MVar` was empty
         
     | 
| 
       43 
     | 
    
         
            -
                EMPTY = Object.new
         
     | 
| 
      
 43 
     | 
    
         
            +
                EMPTY = ::Object.new
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                # Unique value that represents that an `MVar` timed out before it was able
         
     | 
| 
       46 
46 
     | 
    
         
             
                # to produce a value.
         
     | 
| 
       47 
     | 
    
         
            -
                TIMEOUT = Object.new
         
     | 
| 
      
 47 
     | 
    
         
            +
                TIMEOUT = ::Object.new
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
                # Create a new `MVar`, either empty or with an initial value.
         
     | 
| 
       50 
50 
     | 
    
         
             
                #
         
     | 
    
        data/lib/concurrent/promise.rb
    CHANGED
    
    | 
         @@ -161,15 +161,15 @@ module Concurrent 
     | 
|
| 
       161 
161 
     | 
    
         
             
              # receive the rejection `reason` as the rejection callable parameter:
         
     | 
| 
       162 
162 
     | 
    
         
             
              #
         
     | 
| 
       163 
163 
     | 
    
         
             
              # ```ruby
         
     | 
| 
       164 
     | 
    
         
            -
              # p =  
     | 
| 
      
 164 
     | 
    
         
            +
              # p = Concurrent::Promise.execute { Thread.pass; raise StandardError }
         
     | 
| 
       165 
165 
     | 
    
         
             
              #
         
     | 
| 
       166 
     | 
    
         
            -
              # c1 = p.then( 
     | 
| 
       167 
     | 
    
         
            -
              # c2 = p.then( 
     | 
| 
      
 166 
     | 
    
         
            +
              # c1 = p.then(-> reason { 42 })
         
     | 
| 
      
 167 
     | 
    
         
            +
              # c2 = p.then(-> reason { raise 'Boom!' })
         
     | 
| 
       168 
168 
     | 
    
         
             
              #
         
     | 
| 
       169 
     | 
    
         
            -
              #  
     | 
| 
       170 
     | 
    
         
            -
              #
         
     | 
| 
       171 
     | 
    
         
            -
              #  
     | 
| 
       172 
     | 
    
         
            -
              # c2. 
     | 
| 
      
 169 
     | 
    
         
            +
              # c1.wait.state  #=> :fulfilled
         
     | 
| 
      
 170 
     | 
    
         
            +
              # c1.value       #=> 45
         
     | 
| 
      
 171 
     | 
    
         
            +
              # c2.wait.state  #=> :rejected
         
     | 
| 
      
 172 
     | 
    
         
            +
              # c2.reason      #=> #<RuntimeError: Boom!>
         
     | 
| 
       173 
173 
     | 
    
         
             
              # ```
         
     | 
| 
       174 
174 
     | 
    
         
             
              #
         
     | 
| 
       175 
175 
     | 
    
         
             
              # Once a promise is rejected it will continue to accept children that will
         
     | 
| 
         @@ -193,7 +193,7 @@ module Concurrent 
     | 
|
| 
       193 
193 
     | 
    
         
             
                #
         
     | 
| 
       194 
194 
     | 
    
         
             
                # @!macro executor_and_deref_options
         
     | 
| 
       195 
195 
     | 
    
         
             
                #
         
     | 
| 
       196 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 196 
     | 
    
         
            +
                # @!macro promise_init_options
         
     | 
| 
       197 
197 
     | 
    
         
             
                #
         
     | 
| 
       198 
198 
     | 
    
         
             
                #   @option opts [Promise] :parent the parent `Promise` when building a chain/tree
         
     | 
| 
       199 
199 
     | 
    
         
             
                #   @option opts [Proc] :on_fulfill fulfillment handler
         
     | 
| 
         @@ -298,16 +298,28 @@ module Concurrent 
     | 
|
| 
       298 
298 
     | 
    
         | 
| 
       299 
299 
     | 
    
         
             
                # Chain a new promise off the current promise.
         
     | 
| 
       300 
300 
     | 
    
         
             
                #
         
     | 
| 
       301 
     | 
    
         
            -
                # @param [Proc] rescuer An optional rescue block to be executed if the
         
     | 
| 
       302 
     | 
    
         
            -
                #   promise is rejected.
         
     | 
| 
       303 
     | 
    
         
            -
                #
         
     | 
| 
       304 
     | 
    
         
            -
                # @param [ThreadPool] executor An optional thread pool executor to be used
         
     | 
| 
       305 
     | 
    
         
            -
                # in the new Promise
         
     | 
| 
       306 
     | 
    
         
            -
                #
         
     | 
| 
       307 
     | 
    
         
            -
                # @yield The block operation to be performed asynchronously.
         
     | 
| 
       308 
     | 
    
         
            -
                #
         
     | 
| 
       309 
301 
     | 
    
         
             
                # @return [Promise] the new promise
         
     | 
| 
       310 
     | 
    
         
            -
                 
     | 
| 
      
 302 
     | 
    
         
            +
                # @yield The block operation to be performed asynchronously.
         
     | 
| 
      
 303 
     | 
    
         
            +
                # @overload then(rescuer, executor, &block)
         
     | 
| 
      
 304 
     | 
    
         
            +
                #   @param [Proc] rescuer An optional rescue block to be executed if the
         
     | 
| 
      
 305 
     | 
    
         
            +
                #     promise is rejected.
         
     | 
| 
      
 306 
     | 
    
         
            +
                #   @param [ThreadPool] executor An optional thread pool executor to be used
         
     | 
| 
      
 307 
     | 
    
         
            +
                #     in the new Promise
         
     | 
| 
      
 308 
     | 
    
         
            +
                # @overload then(rescuer, executor: executor, &block)
         
     | 
| 
      
 309 
     | 
    
         
            +
                #   @param [Proc] rescuer An optional rescue block to be executed if the
         
     | 
| 
      
 310 
     | 
    
         
            +
                #     promise is rejected.
         
     | 
| 
      
 311 
     | 
    
         
            +
                #   @param [ThreadPool] executor An optional thread pool executor to be used
         
     | 
| 
      
 312 
     | 
    
         
            +
                #     in the new Promise
         
     | 
| 
      
 313 
     | 
    
         
            +
                def then(*args, &block)
         
     | 
| 
      
 314 
     | 
    
         
            +
                  if args.last.is_a?(::Hash)
         
     | 
| 
      
 315 
     | 
    
         
            +
                    executor = args.pop[:executor]
         
     | 
| 
      
 316 
     | 
    
         
            +
                    rescuer = args.first
         
     | 
| 
      
 317 
     | 
    
         
            +
                  else
         
     | 
| 
      
 318 
     | 
    
         
            +
                    rescuer, executor = args
         
     | 
| 
      
 319 
     | 
    
         
            +
                  end
         
     | 
| 
      
 320 
     | 
    
         
            +
             
     | 
| 
      
 321 
     | 
    
         
            +
                  executor ||= @executor
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
       311 
323 
     | 
    
         
             
                  raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given?
         
     | 
| 
       312 
324 
     | 
    
         
             
                  block = Proc.new { |result| result } unless block_given?
         
     | 
| 
       313 
325 
     | 
    
         
             
                  child = Promise.new(
         
     | 
| 
         @@ -383,11 +395,24 @@ module Concurrent 
     | 
|
| 
       383 
395 
     | 
    
         
             
                # Builds a promise that produces the result of promises in an Array
         
     | 
| 
       384 
396 
     | 
    
         
             
                # and fails if any of them fails.
         
     | 
| 
       385 
397 
     | 
    
         
             
                #
         
     | 
| 
       386 
     | 
    
         
            -
                # @ 
     | 
| 
      
 398 
     | 
    
         
            +
                # @overload zip(*promises)
         
     | 
| 
      
 399 
     | 
    
         
            +
                #   @param [Array<Promise>] promises
         
     | 
| 
      
 400 
     | 
    
         
            +
                #
         
     | 
| 
      
 401 
     | 
    
         
            +
                # @overload zip(*promises, opts)
         
     | 
| 
      
 402 
     | 
    
         
            +
                #   @param [Array<Promise>] promises
         
     | 
| 
      
 403 
     | 
    
         
            +
                #   @param [Hash] opts the configuration options
         
     | 
| 
      
 404 
     | 
    
         
            +
                #   @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance.
         
     | 
| 
      
 405 
     | 
    
         
            +
                #   @option opts [Boolean] :execute (true) execute promise before returning
         
     | 
| 
       387 
406 
     | 
    
         
             
                #
         
     | 
| 
       388 
407 
     | 
    
         
             
                # @return [Promise<Array>]
         
     | 
| 
       389 
408 
     | 
    
         
             
                def self.zip(*promises)
         
     | 
| 
       390 
     | 
    
         
            -
                   
     | 
| 
      
 409 
     | 
    
         
            +
                  opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {}
         
     | 
| 
      
 410 
     | 
    
         
            +
                  opts[:executor] ||= ImmediateExecutor.new
         
     | 
| 
      
 411 
     | 
    
         
            +
                  zero = if !opts.key?(:execute) || opts.delete(:execute)
         
     | 
| 
      
 412 
     | 
    
         
            +
                    fulfill([], opts)
         
     | 
| 
      
 413 
     | 
    
         
            +
                  else
         
     | 
| 
      
 414 
     | 
    
         
            +
                    Promise.new(opts) { [] }
         
     | 
| 
      
 415 
     | 
    
         
            +
                  end
         
     | 
| 
       391 
416 
     | 
    
         | 
| 
       392 
417 
     | 
    
         
             
                  promises.reduce(zero) do |p1, p2|
         
     | 
| 
       393 
418 
     | 
    
         
             
                    p1.flat_map do |results|
         
     | 
| 
         @@ -401,7 +426,14 @@ module Concurrent 
     | 
|
| 
       401 
426 
     | 
    
         
             
                # Builds a promise that produces the result of self and others in an Array
         
     | 
| 
       402 
427 
     | 
    
         
             
                # and fails if any of them fails.
         
     | 
| 
       403 
428 
     | 
    
         
             
                #
         
     | 
| 
       404 
     | 
    
         
            -
                # @ 
     | 
| 
      
 429 
     | 
    
         
            +
                # @overload zip(*promises)
         
     | 
| 
      
 430 
     | 
    
         
            +
                #   @param [Array<Promise>] others
         
     | 
| 
      
 431 
     | 
    
         
            +
                #
         
     | 
| 
      
 432 
     | 
    
         
            +
                # @overload zip(*promises, opts)
         
     | 
| 
      
 433 
     | 
    
         
            +
                #   @param [Array<Promise>] others
         
     | 
| 
      
 434 
     | 
    
         
            +
                #   @param [Hash] opts the configuration options
         
     | 
| 
      
 435 
     | 
    
         
            +
                #   @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance.
         
     | 
| 
      
 436 
     | 
    
         
            +
                #   @option opts [Boolean] :execute (true) execute promise before returning
         
     | 
| 
       405 
437 
     | 
    
         
             
                #
         
     | 
| 
       406 
438 
     | 
    
         
             
                # @return [Promise<Array>]
         
     | 
| 
       407 
439 
     | 
    
         
             
                def zip(*others)
         
     | 
| 
         @@ -414,7 +446,7 @@ module Concurrent 
     | 
|
| 
       414 
446 
     | 
    
         
             
                # fail. Upon execution will execute any of the aggregate promises that
         
     | 
| 
       415 
447 
     | 
    
         
             
                # were not already executed.
         
     | 
| 
       416 
448 
     | 
    
         
             
                #
         
     | 
| 
       417 
     | 
    
         
            -
                # @!macro  
     | 
| 
      
 449 
     | 
    
         
            +
                # @!macro promise_self_aggregate
         
     | 
| 
       418 
450 
     | 
    
         
             
                #
         
     | 
| 
       419 
451 
     | 
    
         
             
                #   The returned promise will not yet have been executed. Additional `#then`
         
     | 
| 
       420 
452 
     | 
    
         
             
                #   and `#rescue` handlers may still be provided. Once the returned promise
         
     |