farce 0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +26 -0
- data/CONTRIBUTING.md +71 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1525 -0
- data/SECURITY.md +10 -0
- data/docs/benchmarks.md +185 -0
- data/docs/gems/dry-types.md +290 -0
- data/docs/gems/msgpack.md +70 -0
- data/docs/gems/ractor-shim.md +63 -0
- data/docs/modes.md +628 -0
- data/docs/scopes.md +649 -0
- data/docs/variants.md +346 -0
- data/ext/ext_helper.rb +20 -0
- data/ext/farce/README.md +21 -0
- data/ext/farce/atom.c +1023 -0
- data/ext/farce/bounded_map.c +1683 -0
- data/ext/farce/containers.h +77 -0
- data/ext/farce/counter.c +399 -0
- data/ext/farce/darwin.c +100 -0
- data/ext/farce/depend +12 -0
- data/ext/farce/dict.c +1523 -0
- data/ext/farce/dict.h +152 -0
- data/ext/farce/drivers.c +237 -0
- data/ext/farce/exchanger.c +299 -0
- data/ext/farce/extconf.rb +99 -0
- data/ext/farce/farce.c +359 -0
- data/ext/farce/flag.c +288 -0
- data/ext/farce/io.c +338 -0
- data/ext/farce/lock.c +510 -0
- data/ext/farce/map.c +2240 -0
- data/ext/farce/priority_queue.c +2056 -0
- data/ext/farce/queue.c +1059 -0
- data/ext/farce/reactor.c +820 -0
- data/ext/farce/reactor.h +103 -0
- data/ext/farce/shareable.h +31 -0
- data/ext/farce/signal.c +350 -0
- data/ext/farce/transaction.c +354 -0
- data/ext/farce/transaction.h +40 -0
- data/ext/farce/tree_map.c +1953 -0
- data/ext/farce/trie.c +2020 -0
- data/ext/farce/unshareable.c +155 -0
- data/ext/farce/unshared_io_pool.h +234 -0
- data/ext/farce/unshared_signal.c +263 -0
- data/ext/farce/unshared_wait.h +193 -0
- data/ext/farce/unsupported.c +6 -0
- data/ext/farce/vector.c +1195 -0
- data/ext/farce/weak_map.c +1714 -0
- data/ext/java/org/farce/BoundedMap.java +394 -0
- data/ext/java/org/farce/FiberScheduler.java +141 -0
- data/ext/java/org/farce/PriorityKey.java +45 -0
- data/ext/java/org/farce/PriorityQueue.java +373 -0
- data/ext/java/org/farce/QueueSignal.java +28 -0
- data/ext/rebind/README.md +14 -0
- data/ext/rebind/extconf.rb +10 -0
- data/ext/rebind/rebind.c +186 -0
- data/lib/farce/_yard/internal.rb +13 -0
- data/lib/farce/_yard/macros.rb +61 -0
- data/lib/farce/_yard/ractor.rb +46 -0
- data/lib/farce/abstract/atom.rb +186 -0
- data/lib/farce/abstract/bounded_map.rb +232 -0
- data/lib/farce/abstract/collection.rb +151 -0
- data/lib/farce/abstract/concurrent_map.rb +381 -0
- data/lib/farce/abstract/counter.rb +193 -0
- data/lib/farce/abstract/duplicable_map.rb +229 -0
- data/lib/farce/abstract/exchanger.rb +26 -0
- data/lib/farce/abstract/flag.rb +71 -0
- data/lib/farce/abstract/lazy.rb +115 -0
- data/lib/farce/abstract/lease.rb +104 -0
- data/lib/farce/abstract/lease_map.rb +261 -0
- data/lib/farce/abstract/lease_pool.rb +91 -0
- data/lib/farce/abstract/lfu_map.rb +20 -0
- data/lib/farce/abstract/lru_map.rb +25 -0
- data/lib/farce/abstract/map.rb +345 -0
- data/lib/farce/abstract/molecule.rb +245 -0
- data/lib/farce/abstract/port.rb +74 -0
- data/lib/farce/abstract/priority_queue.rb +117 -0
- data/lib/farce/abstract/queue.rb +269 -0
- data/lib/farce/abstract/scheduler.rb +111 -0
- data/lib/farce/abstract/set.rb +910 -0
- data/lib/farce/abstract/sorted_set.rb +172 -0
- data/lib/farce/abstract/timer_queue.rb +136 -0
- data/lib/farce/abstract/tree_map.rb +269 -0
- data/lib/farce/abstract/value.rb +68 -0
- data/lib/farce/abstract/vector.rb +1126 -0
- data/lib/farce/abstract/weak_atom.rb +32 -0
- data/lib/farce/abstract/weak_key_map.rb +12 -0
- data/lib/farce/abstract/weak_map.rb +13 -0
- data/lib/farce/abstract/weak_set.rb +12 -0
- data/lib/farce/abstract/weak_value_map.rb +12 -0
- data/lib/farce/abstract.rb +17 -0
- data/lib/farce/atom.rb +293 -0
- data/lib/farce/class_mirror.rb +87 -0
- data/lib/farce/clock.rb +121 -0
- data/lib/farce/config.rb +229 -0
- data/lib/farce/counter.rb +71 -0
- data/lib/farce/deduper.rb +122 -0
- data/lib/farce/engine/jruby/bounded_map.rb +314 -0
- data/lib/farce/engine/jruby/fiber_scheduler.jar +0 -0
- data/lib/farce/engine/jruby/fiber_scheduler.rb +119 -0
- data/lib/farce/engine/jruby/lease_waiting.rb +19 -0
- data/lib/farce/engine/jruby/map.rb +505 -0
- data/lib/farce/engine/jruby/mutable_numeric_copy.rb +42 -0
- data/lib/farce/engine/jruby/signal.rb +147 -0
- data/lib/farce/engine/jruby.rb +63 -0
- data/lib/farce/engine/jvm/concurrent_weak_registry.rb +55 -0
- data/lib/farce/engine/jvm/counter.rb +102 -0
- data/lib/farce/engine/jvm/extension.rb +32 -0
- data/lib/farce/engine/jvm/farce.jar +0 -0
- data/lib/farce/engine/jvm/flag.rb +79 -0
- data/lib/farce/engine/jvm/priority_queue.rb +217 -0
- data/lib/farce/engine/jvm/tree_map.rb +350 -0
- data/lib/farce/engine/jvm/types.rb +180 -0
- data/lib/farce/engine/jvm.rb +19 -0
- data/lib/farce/engine/ruby/3.4/fiber_scheduler.rb +20 -0
- data/lib/farce/engine/ruby/3.4/port.rb +186 -0
- data/lib/farce/engine/ruby/3.4/ractor_methods.rb +26 -0
- data/lib/farce/engine/ruby/3.4/ractor_selector.rb +92 -0
- data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
- data/lib/farce/engine/ruby/4.0/port.rb +19 -0
- data/lib/farce/engine/ruby/4.0/ractor_methods.rb +20 -0
- data/lib/farce/engine/ruby/4.0/ractor_selector.rb +108 -0
- data/lib/farce/engine/ruby/4.0/vault.rb +74 -0
- data/lib/farce/engine/ruby/4.1/port.rb +21 -0
- data/lib/farce/engine/ruby/4.1/ractor_methods.rb +22 -0
- data/lib/farce/engine/ruby/4.1/ractor_selector.rb +25 -0
- data/lib/farce/engine/ruby/4.1/vault.rb +5 -0
- data/lib/farce/engine/ruby/fiber_scheduler.rb +32 -0
- data/lib/farce/engine/ruby/key_lock_map.rb +28 -0
- data/lib/farce/engine/ruby/shared/lease.rb +26 -0
- data/lib/farce/engine/ruby/shared/lease_pool.rb +24 -0
- data/lib/farce/engine/ruby/shared/main_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/proxy_owner.rb +31 -0
- data/lib/farce/engine/ruby/shared/ractor_methods.rb +34 -0
- data/lib/farce/engine/ruby/shared/ractor_selector.rb +328 -0
- data/lib/farce/engine/ruby/shared/strict_map.rb +13 -0
- data/lib/farce/engine/ruby/shared/unshared_vector.rb +14 -0
- data/lib/farce/engine/ruby/shared/vault.rb +144 -0
- data/lib/farce/engine/ruby/shared/vault_weak_map.rb +336 -0
- data/lib/farce/engine/ruby/shared/weak_atom.rb +54 -0
- data/lib/farce/engine/ruby/shared/weak_map.rb +413 -0
- data/lib/farce/engine/ruby.rb +130 -0
- data/lib/farce/engine/shared/atom.rb +10 -0
- data/lib/farce/engine/shared/exchanger.rb +130 -0
- data/lib/farce/engine/shared/identity_key.rb +22 -0
- data/lib/farce/engine/shared/lease.rb +10 -0
- data/lib/farce/engine/shared/lease_pool.rb +10 -0
- data/lib/farce/engine/shared/main_scheduler.rb +20 -0
- data/lib/farce/engine/shared/map_key_coordination.rb +226 -0
- data/lib/farce/engine/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/shared/port.rb +44 -0
- data/lib/farce/engine/shared/portable_bounded_map.rb +619 -0
- data/lib/farce/engine/shared/proxy_owner.rb +43 -0
- data/lib/farce/engine/shared/queue.rb +233 -0
- data/lib/farce/engine/shared/ractor_methods.rb +73 -0
- data/lib/farce/engine/shared/rebindable.rb +15 -0
- data/lib/farce/engine/shared/strict_atom.rb +73 -0
- data/lib/farce/engine/shared/strict_map.rb +117 -0
- data/lib/farce/engine/shared/strict_queue_values.rb +27 -0
- data/lib/farce/engine/shared/strict_tree_map.rb +56 -0
- data/lib/farce/engine/shared/transaction_map_backend.rb +20 -0
- data/lib/farce/engine/shared/trie.rb +317 -0
- data/lib/farce/engine/shared/trie_builder.rb +199 -0
- data/lib/farce/engine/shared/unshareable.rb +14 -0
- data/lib/farce/engine/shared/unshared_atom.rb +256 -0
- data/lib/farce/engine/shared/unshared_priority_queue.rb +9 -0
- data/lib/farce/engine/shared/unshared_queue.rb +18 -0
- data/lib/farce/engine/shared/unshared_signal.rb +21 -0
- data/lib/farce/engine/shared/unshared_vector.rb +377 -0
- data/lib/farce/engine/shared/unshared_weak_atom.rb +30 -0
- data/lib/farce/engine/shared/unshared_weak_map.rb +445 -0
- data/lib/farce/engine/shared/vault.rb +31 -0
- data/lib/farce/engine/shared/vector.rb +83 -0
- data/lib/farce/engine/shared/weak_atom/base.rb +189 -0
- data/lib/farce/engine/shared/weak_atom.rb +20 -0
- data/lib/farce/engine/shared/weak_map/cell.rb +99 -0
- data/lib/farce/engine/shared/weak_map/index.rb +249 -0
- data/lib/farce/engine/shared/weak_map/lock.rb +80 -0
- data/lib/farce/engine/shared/weak_map/reference.rb +33 -0
- data/lib/farce/engine/shared.rb +63 -0
- data/lib/farce/engine/truffleruby/fiber_scheduler.rb +13 -0
- data/lib/farce/engine/truffleruby/lock.rb +121 -0
- data/lib/farce/engine/truffleruby/map.rb +656 -0
- data/lib/farce/engine/truffleruby/native/counter.rb +105 -0
- data/lib/farce/engine/truffleruby/native/flag.rb +77 -0
- data/lib/farce/engine/truffleruby/native/ordered_array_support.rb +67 -0
- data/lib/farce/engine/truffleruby/native/priority_queue.rb +388 -0
- data/lib/farce/engine/truffleruby/native/tree_map.rb +51 -0
- data/lib/farce/engine/truffleruby/native/unsafe_tree_map.rb +350 -0
- data/lib/farce/engine/truffleruby/signal.rb +77 -0
- data/lib/farce/engine/truffleruby.rb +148 -0
- data/lib/farce/envelope.rb +335 -0
- data/lib/farce/error.rb +35 -0
- data/lib/farce/exchanger.rb +41 -0
- data/lib/farce/flag.rb +27 -0
- data/lib/farce/integrations/active_support/blank.rb +68 -0
- data/lib/farce/integrations/active_support/clock.rb +17 -0
- data/lib/farce/integrations/active_support/duplicable.rb +78 -0
- data/lib/farce/integrations/active_support/map.rb +175 -0
- data/lib/farce/integrations/active_support/set.rb +60 -0
- data/lib/farce/integrations/active_support/value_serialization.rb +17 -0
- data/lib/farce/integrations/active_support/vector.rb +231 -0
- data/lib/farce/integrations/active_support.rb +9 -0
- data/lib/farce/integrations/activesupport.rb +5 -0
- data/lib/farce/integrations/bson.rb +108 -0
- data/lib/farce/integrations/cbor.rb +51 -0
- data/lib/farce/integrations/concurrent.rb +112 -0
- data/lib/farce/integrations/dry-types.rb +5 -0
- data/lib/farce/integrations/dry_types.rb +694 -0
- data/lib/farce/integrations/json.rb +7 -0
- data/lib/farce/integrations/msgpack.rb +112 -0
- data/lib/farce/integrations/oj.rb +69 -0
- data/lib/farce/integrations/psych.rb +191 -0
- data/lib/farce/integrations/ractor-sharing.rb +5 -0
- data/lib/farce/integrations/ractor-tmvar.rb +5 -0
- data/lib/farce/integrations/ractor_sharing.rb +172 -0
- data/lib/farce/integrations/ractor_tmvar.rb +64 -0
- data/lib/farce/integrations/shared/to_json.rb +42 -0
- data/lib/farce/integrations/sorted_set.rb +11 -0
- data/lib/farce/integrations/weakref.rb +38 -0
- data/lib/farce/integrations/yajl.rb +10 -0
- data/lib/farce/integrations.rb +156 -0
- data/lib/farce/internal/_frozen_config.rb +11 -0
- data/lib/farce/internal/autoloads.rb +47 -0
- data/lib/farce/internal/blocking_priority_queue.rb +122 -0
- data/lib/farce/internal/converter.rb +106 -0
- data/lib/farce/internal/copyable.rb +31 -0
- data/lib/farce/internal/delegation.rb +20 -0
- data/lib/farce/internal/external_transaction.rb +59 -0
- data/lib/farce/internal/fake_ractor.rb +179 -0
- data/lib/farce/internal/freeze.rb +118 -0
- data/lib/farce/internal/inspect.rb +157 -0
- data/lib/farce/internal/key_lock_map.rb +29 -0
- data/lib/farce/internal/key_normalizer.rb +289 -0
- data/lib/farce/internal/lease_initialization.rb +115 -0
- data/lib/farce/internal/lease_map.rb +441 -0
- data/lib/farce/internal/lease_pool_state.rb +228 -0
- data/lib/farce/internal/lease_state.rb +342 -0
- data/lib/farce/internal/lease_waiting.rb +13 -0
- data/lib/farce/internal/managed_queue.rb +26 -0
- data/lib/farce/internal/map_value_modes.rb +227 -0
- data/lib/farce/internal/marshal_support.rb +227 -0
- data/lib/farce/internal/mixin.rb +20 -0
- data/lib/farce/internal/mutable_ordered_key_lock_map.rb +63 -0
- data/lib/farce/internal/noncopyable.rb +17 -0
- data/lib/farce/internal/ordered_key_lock_map.rb +69 -0
- data/lib/farce/internal/pool_supervisor.rb +41 -0
- data/lib/farce/internal/pool_worker.rb +61 -0
- data/lib/farce/internal/portable_transaction/reservation_entry.rb +29 -0
- data/lib/farce/internal/portable_transaction/strong_map_entry.rb +137 -0
- data/lib/farce/internal/portable_transaction/strong_map_size_entry.rb +44 -0
- data/lib/farce/internal/portable_transaction/tree_entry.rb +64 -0
- data/lib/farce/internal/portable_transaction.rb +164 -0
- data/lib/farce/internal/proxy_owner_notifications.rb +29 -0
- data/lib/farce/internal/reservation_waiting.rb +24 -0
- data/lib/farce/internal/scheduled_task.rb +48 -0
- data/lib/farce/internal/scheduler_io.rb +171 -0
- data/lib/farce/internal/scheduler_lifecycle.rb +314 -0
- data/lib/farce/internal/select_scheduler.rb +235 -0
- data/lib/farce/internal/storage.rb +162 -0
- data/lib/farce/internal/strict_lease.rb +30 -0
- data/lib/farce/internal/strict_lease_map.rb +20 -0
- data/lib/farce/internal/strict_lease_pool.rb +29 -0
- data/lib/farce/internal/thread_pool.rb +166 -0
- data/lib/farce/internal/transaction_conflict.rb +9 -0
- data/lib/farce/internal/transaction_freeze_guard.rb +30 -0
- data/lib/farce/internal/transaction_map_snapshot.rb +123 -0
- data/lib/farce/internal/undefined.rb +22 -0
- data/lib/farce/internal/unshared_lease.rb +29 -0
- data/lib/farce/internal/unshared_lease_pool.rb +34 -0
- data/lib/farce/internal/unshared_queue_waiting.rb +28 -0
- data/lib/farce/internal/value_serialization.rb +13 -0
- data/lib/farce/internal/weak_map_value_modes.rb +58 -0
- data/lib/farce/internal/weak_mode_manager.rb +26 -0
- data/lib/farce/internal.rb +129 -0
- data/lib/farce/lazy.rb +100 -0
- data/lib/farce/lazy_ref.rb +40 -0
- data/lib/farce/lease.rb +28 -0
- data/lib/farce/lease_map.rb +34 -0
- data/lib/farce/lease_pool.rb +29 -0
- data/lib/farce/lfu_map.rb +53 -0
- data/lib/farce/local/atom.rb +23 -0
- data/lib/farce/local/counter.rb +88 -0
- data/lib/farce/local/flag.rb +65 -0
- data/lib/farce/local/lazy.rb +38 -0
- data/lib/farce/local/lazy_ref.rb +36 -0
- data/lib/farce/local/lease.rb +77 -0
- data/lib/farce/local/lease_map.rb +80 -0
- data/lib/farce/local/lease_pool.rb +38 -0
- data/lib/farce/local/lfu_map.rb +55 -0
- data/lib/farce/local/lru_map.rb +62 -0
- data/lib/farce/local/map.rb +47 -0
- data/lib/farce/local/molecule.rb +45 -0
- data/lib/farce/local/priority_queue.rb +53 -0
- data/lib/farce/local/queue.rb +32 -0
- data/lib/farce/local/scoped.rb +166 -0
- data/lib/farce/local/set.rb +18 -0
- data/lib/farce/local/sorted_set.rb +50 -0
- data/lib/farce/local/timer_queue.rb +41 -0
- data/lib/farce/local/tree_map.rb +47 -0
- data/lib/farce/local/vector.rb +30 -0
- data/lib/farce/local/weak_atom.rb +23 -0
- data/lib/farce/local/weak_key_map.rb +39 -0
- data/lib/farce/local/weak_map.rb +39 -0
- data/lib/farce/local/weak_set.rb +18 -0
- data/lib/farce/local/weak_value_map.rb +39 -0
- data/lib/farce/local.rb +35 -0
- data/lib/farce/lock.rb +54 -0
- data/lib/farce/lru_map.rb +63 -0
- data/lib/farce/map.rb +58 -0
- data/lib/farce/mode_manager.rb +142 -0
- data/lib/farce/molecule.rb +60 -0
- data/lib/farce/mutable.rb +171 -0
- data/lib/farce/pool.rb +332 -0
- data/lib/farce/port.rb +134 -0
- data/lib/farce/priority_queue.rb +70 -0
- data/lib/farce/proxy/register.rb +101 -0
- data/lib/farce/proxy/supervisor.rb +137 -0
- data/lib/farce/proxy/wrapper.rb +49 -0
- data/lib/farce/proxy.rb +291 -0
- data/lib/farce/queue.rb +60 -0
- data/lib/farce/ractor.rb +269 -0
- data/lib/farce/read_write_lock.rb +256 -0
- data/lib/farce/reference.rb +158 -0
- data/lib/farce/resolv/dns.rb +42 -0
- data/lib/farce/resolv.rb +85 -0
- data/lib/farce/scheduler.rb +536 -0
- data/lib/farce/set.rb +39 -0
- data/lib/farce/shareable.rb +150 -0
- data/lib/farce/signal.rb +97 -0
- data/lib/farce/sorted_set.rb +36 -0
- data/lib/farce/strict/atom.rb +34 -0
- data/lib/farce/strict/counter.rb +10 -0
- data/lib/farce/strict/exchanger.rb +25 -0
- data/lib/farce/strict/flag.rb +10 -0
- data/lib/farce/strict/lazy.rb +26 -0
- data/lib/farce/strict/lazy_ref.rb +26 -0
- data/lib/farce/strict/lease.rb +27 -0
- data/lib/farce/strict/lease_map.rb +33 -0
- data/lib/farce/strict/lease_pool.rb +28 -0
- data/lib/farce/strict/lfu_map.rb +27 -0
- data/lib/farce/strict/lru_map.rb +28 -0
- data/lib/farce/strict/map.rb +54 -0
- data/lib/farce/strict/molecule.rb +16 -0
- data/lib/farce/strict/port.rb +40 -0
- data/lib/farce/strict/priority_queue.rb +20 -0
- data/lib/farce/strict/queue.rb +17 -0
- data/lib/farce/strict/set.rb +14 -0
- data/lib/farce/strict/sorted_set.rb +19 -0
- data/lib/farce/strict/timer_queue.rb +13 -0
- data/lib/farce/strict/tree_map.rb +27 -0
- data/lib/farce/strict/vector.rb +24 -0
- data/lib/farce/strict/weak_atom.rb +31 -0
- data/lib/farce/strict/weak_key_map.rb +49 -0
- data/lib/farce/strict/weak_map.rb +49 -0
- data/lib/farce/strict/weak_set.rb +14 -0
- data/lib/farce/strict/weak_value_map.rb +48 -0
- data/lib/farce/strict.rb +28 -0
- data/lib/farce/system.rb +40 -0
- data/lib/farce/thread_scheduler.rb +70 -0
- data/lib/farce/timer_queue.rb +66 -0
- data/lib/farce/transaction/atom.rb +73 -0
- data/lib/farce/transaction/map.rb +25 -0
- data/lib/farce/transaction/map_operations.rb +143 -0
- data/lib/farce/transaction/molecule.rb +90 -0
- data/lib/farce/transaction/mutable.rb +61 -0
- data/lib/farce/transaction/set.rb +17 -0
- data/lib/farce/transaction/set_operations.rb +48 -0
- data/lib/farce/transaction/sorted_set.rb +18 -0
- data/lib/farce/transaction/tree_map.rb +78 -0
- data/lib/farce/transaction/vector.rb +139 -0
- data/lib/farce/transaction/wrapper.rb +202 -0
- data/lib/farce/transaction.rb +343 -0
- data/lib/farce/tree_map.rb +56 -0
- data/lib/farce/unsafe/lfu_map.rb +36 -0
- data/lib/farce/unsafe/lru_map.rb +36 -0
- data/lib/farce/unsafe/tree_map.rb +21 -0
- data/lib/farce/unsafe.rb +29 -0
- data/lib/farce/unshareable.rb +67 -0
- data/lib/farce/unshared/atom.rb +24 -0
- data/lib/farce/unshared/counter.rb +10 -0
- data/lib/farce/unshared/flag.rb +10 -0
- data/lib/farce/unshared/lazy.rb +38 -0
- data/lib/farce/unshared/lazy_ref.rb +26 -0
- data/lib/farce/unshared/lease.rb +27 -0
- data/lib/farce/unshared/lease_map.rb +26 -0
- data/lib/farce/unshared/lease_pool.rb +25 -0
- data/lib/farce/unshared/lfu_map.rb +20 -0
- data/lib/farce/unshared/lru_map.rb +20 -0
- data/lib/farce/unshared/map.rb +49 -0
- data/lib/farce/unshared/molecule.rb +16 -0
- data/lib/farce/unshared/priority_queue.rb +16 -0
- data/lib/farce/unshared/queue.rb +27 -0
- data/lib/farce/unshared/set.rb +14 -0
- data/lib/farce/unshared/sorted_set.rb +28 -0
- data/lib/farce/unshared/timer_queue.rb +16 -0
- data/lib/farce/unshared/tree_map.rb +21 -0
- data/lib/farce/unshared/vector.rb +19 -0
- data/lib/farce/unshared/weak_atom.rb +31 -0
- data/lib/farce/unshared/weak_key_map.rb +44 -0
- data/lib/farce/unshared/weak_map.rb +44 -0
- data/lib/farce/unshared/weak_set.rb +14 -0
- data/lib/farce/unshared/weak_value_map.rb +43 -0
- data/lib/farce/unshared.rb +28 -0
- data/lib/farce/vector.rb +228 -0
- data/lib/farce/version.rb +8 -0
- data/lib/farce/walker/definitions.rb +186 -0
- data/lib/farce/walker/modification.rb +355 -0
- data/lib/farce/walker.rb +319 -0
- data/lib/farce/weak_atom.rb +121 -0
- data/lib/farce/weak_key_map.rb +31 -0
- data/lib/farce/weak_map.rb +33 -0
- data/lib/farce/weak_ref.rb +67 -0
- data/lib/farce/weak_set.rb +82 -0
- data/lib/farce/weak_value.rb +195 -0
- data/lib/farce/weak_value_map.rb +32 -0
- data/lib/farce.rb +519 -0
- metadata +435 -8
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
class Queue
|
|
9
|
+
include Freeze::Unfreezable
|
|
10
|
+
|
|
11
|
+
NIL_VALUE = Object.new.freeze
|
|
12
|
+
attr_reader :capacity
|
|
13
|
+
|
|
14
|
+
def initialize(capacity: 1024, track_age: false)
|
|
15
|
+
@queue = capacity ? Thread::SizedQueue.new(capacity) : Thread::Queue.new
|
|
16
|
+
@capacity = capacity
|
|
17
|
+
@signal = Signal.new
|
|
18
|
+
@tracking = track_age ? { lock: Mutex.new, timestamps: [], generation: 0 } : nil
|
|
19
|
+
@lifecycle = { lock: Mutex.new, hard_closed: false }
|
|
20
|
+
Freeze.publish(self)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def pop(timeout: nil)
|
|
24
|
+
timeout_at = timeout_at(timeout)
|
|
25
|
+
# Observing an empty queue is sufficient for a nonblocking miss. Avoid
|
|
26
|
+
# constructing a ThreadError (and its backtrace) just to return nil.
|
|
27
|
+
if timeout_at&.zero? && @queue.empty?
|
|
28
|
+
raise_closed if closed?
|
|
29
|
+
return block_given? ? yield : nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
while true
|
|
33
|
+
begin
|
|
34
|
+
result = tracked_pop
|
|
35
|
+
raise ThreadError if nil.equal?(result) && @queue.closed?
|
|
36
|
+
broadcast
|
|
37
|
+
return NIL_VALUE.equal?(result) ? nil : result
|
|
38
|
+
rescue ThreadError
|
|
39
|
+
remaining = remaining_timeout(timeout_at)
|
|
40
|
+
return block_given? ? yield : nil unless wait_pop(timeout: remaining)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def push(item, timeout: nil)
|
|
46
|
+
check_value(item)
|
|
47
|
+
item = NIL_VALUE if nil.equal?(item)
|
|
48
|
+
|
|
49
|
+
unless capacity
|
|
50
|
+
tracked_push(item)
|
|
51
|
+
broadcast
|
|
52
|
+
return true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
timeout_at = timeout_at(timeout)
|
|
56
|
+
if timeout_at&.zero? && @queue.size >= @queue.max
|
|
57
|
+
raise_unwritable if sealed?
|
|
58
|
+
return false
|
|
59
|
+
end
|
|
60
|
+
while true
|
|
61
|
+
begin
|
|
62
|
+
tracked_push(item, non_block: true)
|
|
63
|
+
broadcast
|
|
64
|
+
return true
|
|
65
|
+
rescue ThreadError
|
|
66
|
+
return false unless wait_push(timeout: remaining_timeout(timeout_at))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def wait_pop(timeout: nil) = wait(timeout) { size.positive? }
|
|
72
|
+
|
|
73
|
+
def try_pop(&) = pop(timeout: 0, &)
|
|
74
|
+
|
|
75
|
+
def try_push(item) = push(item, timeout: 0)
|
|
76
|
+
|
|
77
|
+
def wait_push(timeout: nil)
|
|
78
|
+
raise_unwritable if sealed?
|
|
79
|
+
return true unless capacity
|
|
80
|
+
wait(timeout) do
|
|
81
|
+
raise_unwritable if sealed?
|
|
82
|
+
size < capacity
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def close
|
|
87
|
+
@lifecycle[:lock].synchronize do
|
|
88
|
+
changed = !@lifecycle[:hard_closed]
|
|
89
|
+
@lifecycle[:hard_closed] = true
|
|
90
|
+
@queue.close
|
|
91
|
+
bump_generation if changed
|
|
92
|
+
end
|
|
93
|
+
broadcast
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def seal
|
|
98
|
+
@lifecycle[:lock].synchronize do
|
|
99
|
+
changed = !@queue.closed?
|
|
100
|
+
@queue.close
|
|
101
|
+
bump_generation if changed
|
|
102
|
+
end
|
|
103
|
+
broadcast
|
|
104
|
+
self
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def clear
|
|
108
|
+
if @tracking
|
|
109
|
+
@tracking[:lock].synchronize do
|
|
110
|
+
changed = @queue.size.positive?
|
|
111
|
+
@queue.clear
|
|
112
|
+
@tracking[:timestamps].clear
|
|
113
|
+
@tracking[:generation] += 1 if changed
|
|
114
|
+
end
|
|
115
|
+
else
|
|
116
|
+
@queue.clear
|
|
117
|
+
end
|
|
118
|
+
broadcast
|
|
119
|
+
self
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def num_waiting = @queue.num_waiting + @signal.num_waiting
|
|
123
|
+
|
|
124
|
+
Internal.delegate(self, :@queue, :size)
|
|
125
|
+
|
|
126
|
+
def sealed? = @queue.closed?
|
|
127
|
+
|
|
128
|
+
def closed?
|
|
129
|
+
@lifecycle[:hard_closed] || (@queue.closed? && @queue.empty?)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def age_tracking? = !@tracking.nil?
|
|
133
|
+
def generation = @tracking && @tracking[:lock].synchronize { @tracking[:generation] }
|
|
134
|
+
|
|
135
|
+
def oldest_enqueued_at
|
|
136
|
+
@tracking && @tracking[:lock].synchronize { @tracking[:timestamps].first }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def oldest_age
|
|
140
|
+
timestamp = oldest_enqueued_at
|
|
141
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) - timestamp if timestamp
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def check_value(item)
|
|
147
|
+
raise Ractor::IsolationError, "value is not Ractor-shareable" unless Ractor.shareable?(item)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def tracked_push(item, non_block: false)
|
|
151
|
+
if @tracking
|
|
152
|
+
@tracking[:lock].synchronize do
|
|
153
|
+
result = non_block ? @queue.push(item, true) : @queue.push(item)
|
|
154
|
+
@tracking[:timestamps] << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
155
|
+
@tracking[:generation] += 1
|
|
156
|
+
result
|
|
157
|
+
end
|
|
158
|
+
else
|
|
159
|
+
non_block ? @queue.push(item, true) : @queue.push(item)
|
|
160
|
+
end
|
|
161
|
+
rescue ::ClosedQueueError
|
|
162
|
+
raise_unwritable
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def tracked_pop
|
|
166
|
+
return @queue.pop(true) unless @tracking
|
|
167
|
+
@tracking[:lock].synchronize do
|
|
168
|
+
result = @queue.pop(true)
|
|
169
|
+
unless nil.equal?(result) && @queue.closed?
|
|
170
|
+
@tracking[:timestamps].shift
|
|
171
|
+
@tracking[:generation] += 1
|
|
172
|
+
end
|
|
173
|
+
result
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def bump_generation
|
|
178
|
+
@tracking[:lock].synchronize { @tracking[:generation] += 1 } if @tracking
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def normalize_timeout(timeout)
|
|
182
|
+
return nil if timeout.nil?
|
|
183
|
+
timeout = Float(timeout)
|
|
184
|
+
raise ArgumentError, "timeout must be non-negative" if timeout.negative?
|
|
185
|
+
raise ArgumentError, "timeout must be finite" unless timeout.finite?
|
|
186
|
+
raise ArgumentError, "timeout must be a number" if timeout.nan?
|
|
187
|
+
timeout
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def wait(timeout)
|
|
191
|
+
timeout_at = timeout_at(timeout)
|
|
192
|
+
|
|
193
|
+
if timeout_at&.zero?
|
|
194
|
+
return true if yield
|
|
195
|
+
raise_closed if closed?
|
|
196
|
+
return false
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
while true
|
|
200
|
+
generation = @signal.generation
|
|
201
|
+
return true if yield
|
|
202
|
+
raise_closed if closed?
|
|
203
|
+
return false unless @signal.wait(generation, timeout: remaining_timeout(timeout_at))
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def raise_closed
|
|
208
|
+
raise ::Farce::ClosedQueueError, "queue is closed"
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def raise_unwritable
|
|
212
|
+
closed = closed?
|
|
213
|
+
error = closed ? ::Farce::ClosedQueueError : ::Farce::SealedQueueError
|
|
214
|
+
raise error, closed ? "queue is closed" : "queue is sealed"
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def timeout_at(timeout)
|
|
218
|
+
return if timeout.nil?
|
|
219
|
+
timeout = normalize_timeout(timeout)
|
|
220
|
+
timeout.zero? ? 0 : Clock.timeout(timeout)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def remaining_timeout(timeout_at)
|
|
224
|
+
return unless timeout_at
|
|
225
|
+
return 0 if timeout_at.zero?
|
|
226
|
+
timeout = timeout_at - Clock.now
|
|
227
|
+
timeout.positive? ? timeout : 0
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def broadcast = @signal.broadcast
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
module RactorMethods
|
|
9
|
+
STORAGE = Storage::ThreadSafe.new
|
|
10
|
+
STORAGES = Storage::ThreadSafe.new
|
|
11
|
+
|
|
12
|
+
def with_storage(key)
|
|
13
|
+
key = key.to_s if key.is_a?(Symbol)
|
|
14
|
+
raise TypeError, "#{key.inspect} is not a symbol nor a string" unless key.is_a?(String)
|
|
15
|
+
storage = Ractor.main? ? STORAGE : STORAGES.store_if_absent(Ractor.current) { Storage::ThreadSafe.new }
|
|
16
|
+
yield(storage, key)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def new(...)
|
|
20
|
+
return super if is_a?(Class)
|
|
21
|
+
FakeRactor::NotMain.new(...)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def current = FakeRactor.current
|
|
25
|
+
def main = FakeRactor::Main::INSTANCE
|
|
26
|
+
|
|
27
|
+
def main?
|
|
28
|
+
return true if Internal.autoload?(:FakeRactor)
|
|
29
|
+
FakeRactor.current.main?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def count
|
|
33
|
+
return 1 if Internal.autoload?(:FakeRactor)
|
|
34
|
+
FakeRactor::GROUPS.size + 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def [](name) = with_storage(name) { _1[_2] }
|
|
38
|
+
def builtin? = false
|
|
39
|
+
def main_thread = FakeRactor.main_thread
|
|
40
|
+
def make_shareable(object, **) = object
|
|
41
|
+
def receive(...) = Ractor.current.receive(...)
|
|
42
|
+
|
|
43
|
+
def shareable?(object)
|
|
44
|
+
unless Kernel === object
|
|
45
|
+
begin
|
|
46
|
+
return object.__send__(:ractor_shareable?)
|
|
47
|
+
rescue NoMethodError => e
|
|
48
|
+
raise unless e.name == :ractor_shareable?
|
|
49
|
+
return true
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
object.respond_to?(:ractor_shareable?) ? object.ractor_shareable? : true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def shareable_lambda(**, &) = Farce.rebind(lambda: true, **, &)
|
|
57
|
+
def shareable_proc(**, &) = Farce.rebind(**, &)
|
|
58
|
+
def shim? = true
|
|
59
|
+
def store_if_absent(name, &) = with_storage(name) { _1.store_if_absent(_2, &) }
|
|
60
|
+
def threads = FakeRactor.threads
|
|
61
|
+
|
|
62
|
+
def []=(name, value)
|
|
63
|
+
with_storage(name) { _1[_2] = value }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def select(...)
|
|
67
|
+
raise "TODO: not implemented"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
alias recv receive
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
# @api private
|
|
9
|
+
# Rebindable implementation shared between JRuby and TruffleRuby engine support.
|
|
10
|
+
def rebindable?(proc)
|
|
11
|
+
return false unless proc.is_a?(Proc)
|
|
12
|
+
proc.inspect !~ /^#<Proc:0x[0-9a-f]+\(&:.*\) \(lambda\)>$/
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
# Preserve the unrestricted Atom backend for unshared internals.
|
|
9
|
+
class StrictAtom < Atom
|
|
10
|
+
def initialize(value = nil, **)
|
|
11
|
+
super(check_value(value), **)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def store(value, **, &)
|
|
15
|
+
check_frozen!
|
|
16
|
+
super(check_value(value), **, &)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def swap(value, **, &)
|
|
20
|
+
check_frozen!
|
|
21
|
+
super(check_value(value), **, &)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def wait_until_changed(expected, **, &) = super(check_value(expected), **, &)
|
|
25
|
+
|
|
26
|
+
def value=(value)
|
|
27
|
+
store(value)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def compare_and_set(expected, value, **)
|
|
31
|
+
check_frozen!
|
|
32
|
+
super(check_value(expected), check_value(value), **)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def store_if_absent(**)
|
|
36
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
37
|
+
check_frozen!
|
|
38
|
+
super do
|
|
39
|
+
value = yield
|
|
40
|
+
check_frozen!
|
|
41
|
+
check_value(value)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def update(**)
|
|
46
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
47
|
+
check_frozen!
|
|
48
|
+
super do |value|
|
|
49
|
+
replacement = yield(value)
|
|
50
|
+
check_frozen!
|
|
51
|
+
check_value(replacement)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def upsert(initial, **)
|
|
56
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
57
|
+
check_frozen!
|
|
58
|
+
super(check_value(initial), **) do |value|
|
|
59
|
+
replacement = yield(value)
|
|
60
|
+
check_frozen!
|
|
61
|
+
check_value(replacement)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def check_value(value)
|
|
68
|
+
return value if Ractor.shareable?(value)
|
|
69
|
+
raise Ractor::IsolationError, "value must be Ractor-shareable"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
module StrictMapValues
|
|
9
|
+
def self.included(base)
|
|
10
|
+
base.class_eval do
|
|
11
|
+
alias_method :assignment_prepared, :[]=
|
|
12
|
+
alias_method :get_prepared, :get
|
|
13
|
+
alias_method :store_prepared, :store
|
|
14
|
+
alias_method :swap_prepared, :swap
|
|
15
|
+
alias_method :update_prepared, :update
|
|
16
|
+
alias_method :wait_until_changed_prepared, :wait_until_changed
|
|
17
|
+
end
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(initial_mapping = nil, **)
|
|
22
|
+
raise TypeError, "initial mapping must be a Hash" unless initial_mapping.nil? || initial_mapping.is_a?(Hash)
|
|
23
|
+
initial_mapping&.each { |key, value| check_pair(key, value) }
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def [](key) = super(check_key(key))
|
|
28
|
+
|
|
29
|
+
def []=(key, value)
|
|
30
|
+
key = check_key(key)
|
|
31
|
+
super(key, check_value(value))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get(key, **) = super(check_key(key), **)
|
|
35
|
+
|
|
36
|
+
def store(key, value, **)
|
|
37
|
+
key = check_key(key)
|
|
38
|
+
super(key, check_value(value), **)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def swap(key, value, **)
|
|
42
|
+
key = check_key(key)
|
|
43
|
+
super(key, check_value(value), **)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def key?(key) = super(check_key(key))
|
|
47
|
+
def delete(key) = super(check_key(key))
|
|
48
|
+
def getkey(key) = super(check_key(key))
|
|
49
|
+
def wait_until_non_nil(key, **) = super(check_key(key), **)
|
|
50
|
+
|
|
51
|
+
def fetch(*arguments, &)
|
|
52
|
+
arguments[0] = check_key(arguments.first) unless arguments.empty?
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def store_if_absent(key, **)
|
|
57
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
58
|
+
super(check_key(key), **) { check_value(yield) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def compare_and_set(key, expected, replacement, **)
|
|
62
|
+
super(check_key(key), check_value(expected), check_value(replacement), **)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def update(key, **)
|
|
66
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
67
|
+
super(check_key(key), **) { |value| check_value(yield(value)) }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def upsert(key, initial, **)
|
|
71
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
72
|
+
super(check_key(key), check_value(initial), **) { |value| check_value(yield(value)) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def wait_until_changed(key, expected, **)
|
|
76
|
+
super(check_key(key), check_value(expected), **)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def normalize_external_key(key) = check_key(key)
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def check_pair(key, value)
|
|
84
|
+
check_key(key)
|
|
85
|
+
check_value(value)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def check_key(key)
|
|
89
|
+
key = String.instance_method(:-@).bind_call(key) if String === key && !key.frozen? && !compare_keys_by_identity?
|
|
90
|
+
return key if Ractor.shareable?(key)
|
|
91
|
+
raise Ractor::IsolationError, "key must be Ractor-shareable"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def check_value(value)
|
|
95
|
+
return value if Ractor.shareable?(value)
|
|
96
|
+
raise Ractor::IsolationError, "value must be Ractor-shareable"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
private_constant :StrictMapValues
|
|
100
|
+
|
|
101
|
+
class StrictMap < Map
|
|
102
|
+
include StrictMapValues
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class StrictWeakKeyMap < WeakKeyMap
|
|
106
|
+
include StrictMapValues
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class StrictWeakValueMap < WeakValueMap
|
|
110
|
+
include StrictMapValues
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class StrictWeakMap < WeakMap
|
|
114
|
+
include StrictMapValues
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
module Internal # :nodoc: all
|
|
7
|
+
module StrictQueueValues
|
|
8
|
+
def push(value, *arguments, **options)
|
|
9
|
+
check_queue_value(value)
|
|
10
|
+
check_queue_value(options[:priority]) if options.key?(:priority)
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def try_push(value, **options, &)
|
|
15
|
+
check_queue_value(value)
|
|
16
|
+
check_queue_value(options[:priority]) if options.key?(:priority)
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def check_queue_value(value)
|
|
23
|
+
raise Ractor::IsolationError, "value is not Ractor-shareable" unless Ractor.shareable?(value)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# @!visibility private
|
|
7
|
+
module Internal # :nodoc: all
|
|
8
|
+
module StrictTreeMapValues
|
|
9
|
+
def initialize(entries = nil)
|
|
10
|
+
unless entries.nil? || entries.is_a?(Hash)
|
|
11
|
+
entries = entries.to_hash if entries.respond_to?(:to_hash)
|
|
12
|
+
raise TypeError, "entries must be a Hash or respond to #to_hash" unless entries.is_a?(Hash)
|
|
13
|
+
end
|
|
14
|
+
entries&.each { |key, value| check_tree_pair(key, value) }
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def [](key) = super(check_tree_key(key))
|
|
19
|
+
|
|
20
|
+
def []=(key, value)
|
|
21
|
+
super(check_tree_key(key), check_tree_value(value))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def delete(key) = super(check_tree_key(key))
|
|
25
|
+
def getkey(key) = super(check_tree_key(key))
|
|
26
|
+
def key?(key) = super(check_tree_key(key))
|
|
27
|
+
|
|
28
|
+
def fetch(*arguments, &)
|
|
29
|
+
check_tree_key(arguments.first) unless arguments.empty?
|
|
30
|
+
super
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def check_tree_pair(key, value)
|
|
36
|
+
check_tree_key(key)
|
|
37
|
+
check_tree_value(value)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def check_tree_key(key)
|
|
41
|
+
return key if String === key || Ractor.shareable?(key)
|
|
42
|
+
raise Ractor::IsolationError, "key must be Ractor-shareable"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def check_tree_value(value)
|
|
46
|
+
return value if Ractor.shareable?(value)
|
|
47
|
+
raise Ractor::IsolationError, "value must be Ractor-shareable"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
private_constant :StrictTreeMapValues
|
|
51
|
+
|
|
52
|
+
class StrictTreeMap < ShareableTreeMap
|
|
53
|
+
include StrictTreeMapValues
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
module Internal # :nodoc: all
|
|
7
|
+
# Transaction hooks for the JRuby and TruffleRuby map backends.
|
|
8
|
+
module TransactionMapBackend
|
|
9
|
+
def transaction_snapshot = PortableTransaction.snapshot(self, :map)
|
|
10
|
+
def transaction_size_snapshot(size) = PortableTransaction::MapSizeEntry.new(self, size)
|
|
11
|
+
def transaction_pairs = entries_snapshot
|
|
12
|
+
|
|
13
|
+
# Whether no native operations, key reservations, or clear are active.
|
|
14
|
+
# Commit calls this with the reservation and state mutexes already held.
|
|
15
|
+
def transaction_idle?
|
|
16
|
+
!@active_owner_fiber && !@active_owners && !@clearing_reservations && @reservations.empty?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|