farce 0.0.1.alpha2-x86-linux-gnu
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 +7 -0
- data/CODE_OF_CONDUCT.md +26 -0
- data/CONTRIBUTING.md +71 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1524 -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/farce.so +0 -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/rebind.so +0 -0
- data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
- data/lib/farce/engine/ruby/4.0/farce.so +0 -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/rebind.so +0 -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 +468 -0
|
@@ -0,0 +1,289 @@
|
|
|
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 KeyNormalizer
|
|
9
|
+
class CanonicalEntries < Array
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
Restoration = Data.define(:value)
|
|
13
|
+
|
|
14
|
+
private_constant :CanonicalEntries
|
|
15
|
+
|
|
16
|
+
class SymbolNormalizer
|
|
17
|
+
attr_reader :value
|
|
18
|
+
|
|
19
|
+
def initialize(method)
|
|
20
|
+
@value = method
|
|
21
|
+
freeze
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(key) = key.public_send(@value)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class ProcNormalizer
|
|
28
|
+
def initialize(callable)
|
|
29
|
+
@callable = callable
|
|
30
|
+
freeze
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def call(key) = @callable.call(key)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class LookupNormalizer
|
|
37
|
+
attr_reader :source
|
|
38
|
+
|
|
39
|
+
def initialize(source)
|
|
40
|
+
@source = source
|
|
41
|
+
freeze
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def call(key) = @source.fetch(key, key)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module CommonOperations
|
|
48
|
+
private def normalize_key(key) = @key_normalizer.call(key)
|
|
49
|
+
|
|
50
|
+
def [](key) = super(normalize_key(key))
|
|
51
|
+
|
|
52
|
+
def []=(key, value)
|
|
53
|
+
super(normalize_key(key), value)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def delete(key) = super(normalize_key(key))
|
|
57
|
+
def getkey(key) = super(normalize_key(key))
|
|
58
|
+
def key?(key) = super(normalize_key(key))
|
|
59
|
+
|
|
60
|
+
def fetch(*arguments)
|
|
61
|
+
return super unless arguments.length.between?(1, 2)
|
|
62
|
+
|
|
63
|
+
original, default = arguments
|
|
64
|
+
canonical = normalize_key(original)
|
|
65
|
+
warn "block supersedes default value argument", uplevel: 1 if block_given? && arguments.length == 2
|
|
66
|
+
super(canonical) do
|
|
67
|
+
return yield(original) if block_given?
|
|
68
|
+
return default if arguments.length == 2
|
|
69
|
+
raise KeyError.new("key not found: #{original.inspect}", receiver: self, key: original)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class ConcurrentMap
|
|
75
|
+
def initialize(map, normalizer)
|
|
76
|
+
@map = map
|
|
77
|
+
@normalizer = normalizer
|
|
78
|
+
Internal::Freeze.publish(self) if Ractor.shareable?(map)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @api private
|
|
82
|
+
def transaction_source = @map
|
|
83
|
+
|
|
84
|
+
# @api private
|
|
85
|
+
def transaction_key(key) = @normalizer.call(key)
|
|
86
|
+
|
|
87
|
+
def freeze
|
|
88
|
+
@map.freeze
|
|
89
|
+
self
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def frozen? = @map.frozen?
|
|
93
|
+
|
|
94
|
+
def [](key) = @map[@normalizer.call(key)]
|
|
95
|
+
|
|
96
|
+
def []=(key, value)
|
|
97
|
+
@map[@normalizer.call(key)] = value
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def fetch(key, &) = @map.fetch(@normalizer.call(key), &)
|
|
101
|
+
def get(key, ...) = @map.get(@normalizer.call(key), ...)
|
|
102
|
+
def store(key, value, ...) = @map.store(@normalizer.call(key), value, ...)
|
|
103
|
+
def swap(key, value, ...) = @map.swap(@normalizer.call(key), value, ...)
|
|
104
|
+
def store_if_absent(key, ...) = @map.store_if_absent(@normalizer.call(key), ...)
|
|
105
|
+
|
|
106
|
+
def compare_and_set(key, expected, replacement, ...)
|
|
107
|
+
@map.compare_and_set(@normalizer.call(key), expected, replacement, ...)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def update(key, ...) = @map.update(@normalizer.call(key), ...)
|
|
111
|
+
def modify(key, ...) = @map.modify(@normalizer.call(key), ...)
|
|
112
|
+
def upsert(key, initial, ...) = @map.upsert(@normalizer.call(key), initial, ...)
|
|
113
|
+
def delete(key) = @map.delete(@normalizer.call(key))
|
|
114
|
+
def key?(key) = @map.key?(@normalizer.call(key))
|
|
115
|
+
def getkey(key) = @map.getkey(@normalizer.call(key))
|
|
116
|
+
def wait_until_changed(key, expected, ...) = @map.wait_until_changed(@normalizer.call(key), expected, ...)
|
|
117
|
+
def wait_until_non_nil(key, ...) = @map.wait_until_non_nil(@normalizer.call(key), ...)
|
|
118
|
+
def normalize_external_key(key) = @map.normalize_external_key(@normalizer.call(key))
|
|
119
|
+
def check_mutation = @map.check_mutation
|
|
120
|
+
|
|
121
|
+
def get_prepared(...) = @map.get_prepared(...)
|
|
122
|
+
def store_prepared(...) = @map.store_prepared(...)
|
|
123
|
+
def swap_prepared(...) = @map.swap_prepared(...)
|
|
124
|
+
def update_prepared(...) = @map.update_prepared(...)
|
|
125
|
+
def assignment_prepared(...) = @map.assignment_prepared(...)
|
|
126
|
+
def wait_until_changed_prepared(...) = @map.wait_until_changed_prepared(...)
|
|
127
|
+
def size = @map.size
|
|
128
|
+
def keys = @map.keys
|
|
129
|
+
def each(&) = @map.each(&)
|
|
130
|
+
def each_live(&) = @map.each_live(&)
|
|
131
|
+
def each_key(&) = @map.each_key(&)
|
|
132
|
+
def each_value(&) = @map.each_value(&)
|
|
133
|
+
def clear = @map.clear
|
|
134
|
+
def compare_keys_by_identity? = @map.compare_keys_by_identity?
|
|
135
|
+
def compare_values_by_identity? = @map.compare_values_by_identity?
|
|
136
|
+
def ractor_shareable? = Ractor.shareable?(@map)
|
|
137
|
+
|
|
138
|
+
def prepare_mutation_key(key)
|
|
139
|
+
@map.check_mutation
|
|
140
|
+
@map.prepare_mutation_key(@normalizer.call(key))
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
module ConcurrentBackend
|
|
145
|
+
def self.included(base)
|
|
146
|
+
base.class_eval do
|
|
147
|
+
alias_method :assignment_prepared, :[]=
|
|
148
|
+
alias_method :get_prepared, :get
|
|
149
|
+
alias_method :store_prepared, :store
|
|
150
|
+
alias_method :swap_prepared, :swap
|
|
151
|
+
alias_method :update_prepared, :update
|
|
152
|
+
alias_method :wait_until_changed_prepared, :wait_until_changed
|
|
153
|
+
end
|
|
154
|
+
super
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def normalize_external_key(key)
|
|
158
|
+
if String === key && !key.frozen? && !compare_keys_by_identity?
|
|
159
|
+
key = String.instance_method(:-@).bind_call(key)
|
|
160
|
+
end
|
|
161
|
+
return key if Ractor.shareable?(key)
|
|
162
|
+
raise Ractor::IsolationError, "key must be Ractor-shareable"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
module TreeOperations
|
|
167
|
+
include CommonOperations
|
|
168
|
+
|
|
169
|
+
def store_if_absent(key, &) = super(normalize_key(key), &)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
module BoundedOperations
|
|
173
|
+
include CommonOperations
|
|
174
|
+
|
|
175
|
+
def store_if_absent(key, &) = super(normalize_key(key), &)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
module LeaseOperations
|
|
179
|
+
include CommonOperations
|
|
180
|
+
|
|
181
|
+
def checkout(key, timeout: nil, &)
|
|
182
|
+
canonical = normalize_key(key)
|
|
183
|
+
checkout_canonical(canonical, missing_key: key, timeout:, &)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def try_checkout(key, &)
|
|
187
|
+
canonical = normalize_key(key)
|
|
188
|
+
try_checkout_canonical(canonical, missing_key: key, &)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def checkin(key, resource)
|
|
192
|
+
canonical = normalize_key(key)
|
|
193
|
+
checkin_canonical(canonical, resource, missing_key: key)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def lease_for(key)
|
|
197
|
+
canonical = normalize_key(key)
|
|
198
|
+
lease_for_canonical(canonical, missing_key: key)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def store_if_absent(key, &) = super(normalize_key(key), &)
|
|
202
|
+
def available?(key) = super(normalize_key(key))
|
|
203
|
+
def checked_out?(key) = super(normalize_key(key))
|
|
204
|
+
def owned?(key) = super(normalize_key(key))
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
module_function
|
|
208
|
+
|
|
209
|
+
def restore(value) = Restoration.new(value)
|
|
210
|
+
|
|
211
|
+
def dump(normalizer)
|
|
212
|
+
case normalizer
|
|
213
|
+
when SymbolNormalizer then normalizer.value
|
|
214
|
+
when LookupNormalizer then normalizer.source
|
|
215
|
+
else raise TypeError, "Proc key normalizers cannot be serialized"
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def build(value, shareable:)
|
|
220
|
+
return if value.nil?
|
|
221
|
+
restoring = value.is_a?(Restoration)
|
|
222
|
+
value = value.value if restoring
|
|
223
|
+
|
|
224
|
+
normalizer =
|
|
225
|
+
case value
|
|
226
|
+
when Symbol
|
|
227
|
+
SymbolNormalizer.new(value)
|
|
228
|
+
when Proc
|
|
229
|
+
value = Ractor.shareable_proc(&value) if shareable && !Ractor.shareable?(value)
|
|
230
|
+
ProcNormalizer.new(value)
|
|
231
|
+
when Hash, Farce::Abstract::Map
|
|
232
|
+
Ractor.make_shareable(value) if restoring && shareable && !Ractor.shareable?(value)
|
|
233
|
+
if shareable && !Ractor.shareable?(value)
|
|
234
|
+
raise Ractor::IsolationError, "normalizer source must already be Ractor-shareable"
|
|
235
|
+
end
|
|
236
|
+
LookupNormalizer.new(value)
|
|
237
|
+
else
|
|
238
|
+
raise TypeError, "normalizer must be a Symbol, Proc, Hash, or Farce map"
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
Ractor.make_shareable(normalizer) if shareable
|
|
242
|
+
normalizer
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def install(target, normalizer, operations)
|
|
246
|
+
return unless normalizer
|
|
247
|
+
target.instance_variable_set(:@key_normalizer, normalizer)
|
|
248
|
+
target.extend(operations)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def install_concurrent(target, normalizer)
|
|
252
|
+
return unless normalizer
|
|
253
|
+
target.instance_variable_set(:@key_normalizer, normalizer)
|
|
254
|
+
map = target.instance_variable_get(:@map)
|
|
255
|
+
target.instance_variable_set(:@map, ConcurrentMap.new(map, normalizer))
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def prepare_concurrent(map)
|
|
259
|
+
prepare_concurrent_class(map.class)
|
|
260
|
+
map
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def prepare_concurrent_class(type)
|
|
264
|
+
type.include(ConcurrentBackend) unless type < ConcurrentBackend
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def wrap_concurrent(map, normalizer) = normalizer ? ConcurrentMap.new(map, normalizer) : map
|
|
268
|
+
|
|
269
|
+
def canonical_entries = CanonicalEntries.new
|
|
270
|
+
|
|
271
|
+
def canonical_entries?(entries) = entries.is_a?(CanonicalEntries)
|
|
272
|
+
|
|
273
|
+
def restoration?(value) = value.is_a?(Restoration)
|
|
274
|
+
|
|
275
|
+
def operations_for(target)
|
|
276
|
+
case target
|
|
277
|
+
when Farce::Abstract::LeaseMap then LeaseOperations
|
|
278
|
+
when Farce::Abstract::BoundedMap then BoundedOperations
|
|
279
|
+
when Farce::Abstract::TreeMap then TreeOperations
|
|
280
|
+
else raise ArgumentError, "concurrent maps use an internal key normalizer"
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def shareable_target?(target)
|
|
285
|
+
target.respond_to?(:ractor_shareable?) ? target.ractor_shareable? : false
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
# Coordinates lazy Lease construction without running user code under a storage lock.
|
|
9
|
+
class LeaseInitialization
|
|
10
|
+
def initialize
|
|
11
|
+
@mutex = Mutex.new
|
|
12
|
+
@signal = Signal.new
|
|
13
|
+
@lease = nil
|
|
14
|
+
@initializing = false
|
|
15
|
+
@owner_fiber = nil
|
|
16
|
+
@owner_thread = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fetch(timeout: nil, wait: true, &initializer)
|
|
20
|
+
raise LocalJumpError, "no block given" unless initializer
|
|
21
|
+
deadline = timeout_deadline(timeout)
|
|
22
|
+
|
|
23
|
+
loop do
|
|
24
|
+
initializing_here = false
|
|
25
|
+
observed = @signal.generation
|
|
26
|
+
begin
|
|
27
|
+
Thread.handle_interrupt(INTERRUPT_MASK) { initializing_here = reserve }
|
|
28
|
+
return @lease unless @lease.nil?
|
|
29
|
+
return initialize_lease(&initializer) if initializing_here
|
|
30
|
+
|
|
31
|
+
reject_recursive_initialization!
|
|
32
|
+
return unless wait
|
|
33
|
+
|
|
34
|
+
remaining = deadline - Clock.now if deadline
|
|
35
|
+
return if remaining && !remaining.positive?
|
|
36
|
+
reject_unscheduled_fiber_wait!
|
|
37
|
+
@signal.wait(observed, timeout: wait_interval(remaining))
|
|
38
|
+
ensure
|
|
39
|
+
cancel_reservation if initializing_here
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def reserve
|
|
47
|
+
@mutex.synchronize do
|
|
48
|
+
return false if @lease || @initializing
|
|
49
|
+
|
|
50
|
+
@initializing = true
|
|
51
|
+
@owner_fiber = Fiber.current
|
|
52
|
+
@owner_thread = Thread.current
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def initialize_lease(&initializer)
|
|
58
|
+
lease = initializer.call
|
|
59
|
+
Thread.handle_interrupt(INTERRUPT_MASK) do
|
|
60
|
+
@mutex.synchronize do
|
|
61
|
+
@lease = lease
|
|
62
|
+
clear_reservation
|
|
63
|
+
end
|
|
64
|
+
@signal.broadcast
|
|
65
|
+
end
|
|
66
|
+
lease
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def cancel_reservation
|
|
70
|
+
Thread.handle_interrupt(INTERRUPT_MASK) do
|
|
71
|
+
canceled = @mutex.synchronize do
|
|
72
|
+
next false unless @initializing && @owner_fiber.equal?(Fiber.current)
|
|
73
|
+
|
|
74
|
+
clear_reservation
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
@signal.broadcast if canceled
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def clear_reservation
|
|
82
|
+
@initializing = false
|
|
83
|
+
@owner_fiber = nil
|
|
84
|
+
@owner_thread = nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def reject_unscheduled_fiber_wait!
|
|
88
|
+
return unless @owner_thread.equal?(Thread.current)
|
|
89
|
+
return if Fiber.respond_to?(:scheduler) && Fiber.scheduler
|
|
90
|
+
|
|
91
|
+
raise ThreadError, "deadlock; lease is initialized by another unscheduled Fiber on the same thread"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def reject_recursive_initialization!
|
|
95
|
+
return unless @owner_fiber.equal?(Fiber.current)
|
|
96
|
+
|
|
97
|
+
raise ThreadError, "deadlock; recursive lease initialization"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def timeout_deadline(timeout)
|
|
101
|
+
return if timeout.nil?
|
|
102
|
+
|
|
103
|
+
timeout = Float(timeout)
|
|
104
|
+
unless timeout.finite? && !timeout.negative?
|
|
105
|
+
raise ArgumentError, "timeout must be a finite, non-negative number or nil"
|
|
106
|
+
end
|
|
107
|
+
Clock.now + timeout
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def wait_interval(remaining)
|
|
111
|
+
LeaseWaiting.wait_interval(remaining)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|