farce 0.0.1.alpha2-java
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/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 +420 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
module Abstract
|
|
7
|
+
# @abstract Superclass for maps that retain at most a configured number of entries.
|
|
8
|
+
#
|
|
9
|
+
# Successful individual value reads and writes update the map's eviction policy.
|
|
10
|
+
# Observational operations such as iteration, {#key?}, and {#getkey} do not.
|
|
11
|
+
# Copies preserve capacity and eviction history without counting copying as an access.
|
|
12
|
+
class BoundedMap < Map
|
|
13
|
+
include DuplicableMap
|
|
14
|
+
|
|
15
|
+
# @param entries [Hash, Array<Array(BasicObject, BasicObject)>, Map, #each, nil]
|
|
16
|
+
# Optional initial entries. Entries are stored sequentially and may be evicted.
|
|
17
|
+
# @param max_size [Integer] Maximum number of retained entries.
|
|
18
|
+
# @!macro key_normalization
|
|
19
|
+
# @param compare_by_identity [Boolean] Whether keys and values are compared by identity.
|
|
20
|
+
# @param compare_keys_by_identity [Boolean] Whether keys are compared by identity.
|
|
21
|
+
# @param compare_values_by_identity [Boolean] Whether values are compared by identity.
|
|
22
|
+
def initialize(
|
|
23
|
+
entries = nil,
|
|
24
|
+
max_size:,
|
|
25
|
+
normalize_keys: nil,
|
|
26
|
+
compare_by_identity: false,
|
|
27
|
+
compare_keys_by_identity: compare_by_identity,
|
|
28
|
+
compare_values_by_identity: compare_by_identity
|
|
29
|
+
)
|
|
30
|
+
entries = convert_entries(entries)
|
|
31
|
+
@map = new_bounded_map(
|
|
32
|
+
max_size:,
|
|
33
|
+
compare_by_identity:,
|
|
34
|
+
compare_keys_by_identity:,
|
|
35
|
+
compare_values_by_identity:,
|
|
36
|
+
)
|
|
37
|
+
@key_locks = new_key_locks(compare_keys_by_identity:)
|
|
38
|
+
restoring = Internal::KeyNormalizer.restoration?(normalize_keys)
|
|
39
|
+
normalizer = Internal::KeyNormalizer.build(
|
|
40
|
+
normalize_keys,
|
|
41
|
+
shareable: normalize_keys && Internal::KeyNormalizer.shareable_target?(self),
|
|
42
|
+
)
|
|
43
|
+
Internal::KeyNormalizer.install(self, normalizer, Internal::KeyNormalizer::BoundedOperations) unless restoring
|
|
44
|
+
entries&.each { self[_1] = _2 }
|
|
45
|
+
Internal::KeyNormalizer.install(self, normalizer, Internal::KeyNormalizer::BoundedOperations) if restoring
|
|
46
|
+
super()
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# (see Map#[])
|
|
50
|
+
def [](key) = unwrap_value(internal_map[prepare_key(key)])
|
|
51
|
+
|
|
52
|
+
# (see Map#[]=)
|
|
53
|
+
def []=(key, value)
|
|
54
|
+
key = prepare_store_key(key)
|
|
55
|
+
with_key_lock(key) { internal_map[key] = wrap_value(value) }
|
|
56
|
+
value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Return an existing value, or store the block result for an absent key.
|
|
60
|
+
# Coordinated implementations share one initialization among concurrent
|
|
61
|
+
# callers for equal keys. Unsafe implementations can run competing loaders.
|
|
62
|
+
# The block runs without holding the map's structural lock, so other keys
|
|
63
|
+
# remain accessible. Coordinated assignment waits for initialization.
|
|
64
|
+
# Deletion or clearing can precede a pending initialization's insertion.
|
|
65
|
+
# At zero capacity, coordinated implementations run equal-key loaders
|
|
66
|
+
# sequentially. Each loader validates and transfers its result, but the
|
|
67
|
+
# map retains no value.
|
|
68
|
+
# @param key [BasicObject] The key to retrieve or initialize.
|
|
69
|
+
# @yieldreturn [BasicObject] The value to store.
|
|
70
|
+
# @return [BasicObject] The existing or newly stored value.
|
|
71
|
+
# @raise [LocalJumpError] If no block is given, even when the key exists.
|
|
72
|
+
# @raise [ThreadError] If coordinated initialization recursively accesses its own gate.
|
|
73
|
+
def store_if_absent(key)
|
|
74
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
75
|
+
|
|
76
|
+
map = internal_map
|
|
77
|
+
found = true
|
|
78
|
+
stored = map.fetch(prepare_key(key)) { found = false }
|
|
79
|
+
return unwrap_value(stored) if found
|
|
80
|
+
|
|
81
|
+
key = prepare_store_key(key)
|
|
82
|
+
with_key_lock(key) do
|
|
83
|
+
stored = map.fetch(key) do
|
|
84
|
+
wrapped = wrap_value(yield)
|
|
85
|
+
map[key] = wrapped
|
|
86
|
+
return unwrap_value(wrapped)
|
|
87
|
+
end
|
|
88
|
+
unwrap_value(stored)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# (see Map#clear)
|
|
93
|
+
def clear
|
|
94
|
+
internal_map.clear
|
|
95
|
+
self
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# (see Map#compare_keys_by_identity?)
|
|
99
|
+
def compare_keys_by_identity? = internal_map.compare_keys_by_identity?
|
|
100
|
+
|
|
101
|
+
# (see Map#compare_values_by_identity?)
|
|
102
|
+
def compare_values_by_identity? = internal_map.compare_values_by_identity?
|
|
103
|
+
|
|
104
|
+
# (see Map#delete)
|
|
105
|
+
def delete(key) = unwrap_value(internal_map.delete(prepare_key(key)))
|
|
106
|
+
|
|
107
|
+
# (see Map#fetch)
|
|
108
|
+
def fetch(*arguments)
|
|
109
|
+
unless arguments.length.between?(1, 2)
|
|
110
|
+
raise ArgumentError, "wrong number of arguments (given #{arguments.length}, expected 1..2)"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
key, default = arguments
|
|
114
|
+
prepared_key = prepare_key(key)
|
|
115
|
+
warn "block supersedes default value argument", uplevel: 1 if block_given? && arguments.length == 2
|
|
116
|
+
value = internal_map.fetch(prepared_key) do
|
|
117
|
+
return yield(key) if block_given?
|
|
118
|
+
return default if arguments.length == 2
|
|
119
|
+
raise KeyError.new("key not found: #{key.inspect}", receiver: self, key: key)
|
|
120
|
+
end
|
|
121
|
+
unwrap_value(value)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# (see Map#getkey)
|
|
125
|
+
def getkey(key) = internal_map.getkey(prepare_key(key))
|
|
126
|
+
|
|
127
|
+
# (see Map#key?)
|
|
128
|
+
def key?(key) = internal_map.key?(prepare_key(key))
|
|
129
|
+
|
|
130
|
+
# Return the maximum number of entries retained by the current backing map.
|
|
131
|
+
# @return [Integer]
|
|
132
|
+
def max_size = internal_map.max_size
|
|
133
|
+
|
|
134
|
+
# Change the maximum number of retained entries and immediately evict any excess.
|
|
135
|
+
# @param limit [Integer] The new non-negative capacity.
|
|
136
|
+
# @return [Integer] `limit`
|
|
137
|
+
def max_size=(limit)
|
|
138
|
+
internal_map.max_size = limit
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Remove entries selected by the eviction policy until at most `to` remain.
|
|
142
|
+
# This does not change {#max_size}.
|
|
143
|
+
# @param to [Integer] The non-negative target size.
|
|
144
|
+
# @return [Integer] Number of entries removed.
|
|
145
|
+
def prune(to:) = internal_map.prune(to:)
|
|
146
|
+
|
|
147
|
+
# Remove and return the next entry selected by the eviction policy.
|
|
148
|
+
# @return [Array(BasicObject, BasicObject), nil]
|
|
149
|
+
def shift
|
|
150
|
+
pair = internal_map.shift
|
|
151
|
+
[pair.first, unwrap_value(pair.last)] if pair
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# (see Map#size)
|
|
155
|
+
def size = internal_map.size
|
|
156
|
+
alias length size
|
|
157
|
+
|
|
158
|
+
# Iterate over a snapshot without updating eviction history.
|
|
159
|
+
# @overload each
|
|
160
|
+
# @yield [pair] Called once for each entry.
|
|
161
|
+
# @yieldparam pair [Array<BasicObject>] A two-element `[key, value]` pair.
|
|
162
|
+
# @return [self]
|
|
163
|
+
# @overload each
|
|
164
|
+
# @return [Enumerator]
|
|
165
|
+
def each
|
|
166
|
+
return enum_for(__method__) unless block_given?
|
|
167
|
+
internal_map.each { |key, value| yield [key, unwrap_value(value)] }
|
|
168
|
+
self
|
|
169
|
+
end
|
|
170
|
+
alias each_pair each
|
|
171
|
+
|
|
172
|
+
# Iterate over a snapshot of stored keys without updating eviction history.
|
|
173
|
+
# @return [self, Enumerator]
|
|
174
|
+
def each_key
|
|
175
|
+
return enum_for(__method__) unless block_given?
|
|
176
|
+
internal_map.each_key { yield it }
|
|
177
|
+
self
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Iterate over a snapshot of stored values without updating eviction history.
|
|
181
|
+
# @return [self, Enumerator]
|
|
182
|
+
def each_value
|
|
183
|
+
return enum_for(__method__) unless block_given?
|
|
184
|
+
internal_map.each_value { yield unwrap_value(it) }
|
|
185
|
+
self
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Return a frozen snapshot of stored keys.
|
|
189
|
+
# @return [Array<BasicObject>]
|
|
190
|
+
def keys = each_key.to_a.freeze
|
|
191
|
+
|
|
192
|
+
# Return a frozen snapshot of stored values.
|
|
193
|
+
# @return [Array<BasicObject>]
|
|
194
|
+
def values = each_value.to_a.freeze
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
|
|
198
|
+
def copy_map_backend(source, empty: false)
|
|
199
|
+
return source.dup unless empty
|
|
200
|
+
source.class.new(
|
|
201
|
+
max_size: source.max_size,
|
|
202
|
+
compare_keys_by_identity: source.compare_keys_by_identity?,
|
|
203
|
+
compare_values_by_identity: source.compare_values_by_identity?,
|
|
204
|
+
)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def install_copied_map(map)
|
|
208
|
+
super
|
|
209
|
+
@key_locks = new_key_locks(compare_keys_by_identity: map.compare_keys_by_identity?)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def each_for_inspect(&) = each(&)
|
|
213
|
+
def prepare_key(key) = key
|
|
214
|
+
def prepare_store_key(key) = internal_map.prepare_key(prepare_key(key))
|
|
215
|
+
def with_key_lock(key, &) = @key_locks.synchronize(key, &)
|
|
216
|
+
|
|
217
|
+
# simplecov:disable
|
|
218
|
+
def new_key_locks(...)
|
|
219
|
+
raise "subclass failed to implement #new_key_locks" unless instance_of?(BoundedMap)
|
|
220
|
+
raise NoMethodError, "Farce::Abstract::BoundedMap should not be instantiated directly. Use a subclass instead."
|
|
221
|
+
end
|
|
222
|
+
# simplecov:enable
|
|
223
|
+
|
|
224
|
+
# simplecov:disable
|
|
225
|
+
def new_bounded_map(...)
|
|
226
|
+
raise "subclass failed to implement #new_bounded_map" unless instance_of?(BoundedMap)
|
|
227
|
+
raise NoMethodError, "Farce::Abstract::BoundedMap should not be instantiated directly. Use a subclass instead."
|
|
228
|
+
end
|
|
229
|
+
# simplecov:enable
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
module Abstract
|
|
7
|
+
# @abstract Superclass for a collection of elements.
|
|
8
|
+
#
|
|
9
|
+
# Subclasses define traversal, comparison, and insertion rules.
|
|
10
|
+
# They may accept additional optional parameters for the methods below.
|
|
11
|
+
#
|
|
12
|
+
# Notable subclasses include {Vector}, {Set}, and {SortedSet}.
|
|
13
|
+
#
|
|
14
|
+
# @!method each
|
|
15
|
+
# Iterate over the elements currently present.
|
|
16
|
+
# @yield [element] Visit each element. Returns an Enumerator without a block.
|
|
17
|
+
# @yieldparam element [BasicObject] The current element.
|
|
18
|
+
# @yieldreturn [void] The result is ignored.
|
|
19
|
+
# @return [self, Enumerator] Self, or a sized Enumerator without a block.
|
|
20
|
+
# @abstract
|
|
21
|
+
#
|
|
22
|
+
# @!method size
|
|
23
|
+
# Return the number of elements currently present.
|
|
24
|
+
# @return [Integer] The number of elements.
|
|
25
|
+
# @abstract
|
|
26
|
+
#
|
|
27
|
+
# @!method to_a
|
|
28
|
+
# Return the observed elements in a new Array.
|
|
29
|
+
# @return [Array<BasicObject>] The observed elements.
|
|
30
|
+
# @abstract
|
|
31
|
+
#
|
|
32
|
+
# @!method clear
|
|
33
|
+
# Remove all elements and return self.
|
|
34
|
+
# @return [self] The collection.
|
|
35
|
+
# @abstract
|
|
36
|
+
#
|
|
37
|
+
# @!method include?(element)
|
|
38
|
+
# Return whether an element is present using the collection's membership rules.
|
|
39
|
+
# @param element [BasicObject] The element to look up.
|
|
40
|
+
# @return [Boolean] Whether the element is present.
|
|
41
|
+
# @abstract
|
|
42
|
+
#
|
|
43
|
+
# @!method member?(element)
|
|
44
|
+
# Return whether an element is present, as with {#include?}.
|
|
45
|
+
# @param element [BasicObject] The element to look up.
|
|
46
|
+
# @return [Boolean] Whether the element is present.
|
|
47
|
+
# @see #include?
|
|
48
|
+
# @abstract
|
|
49
|
+
#
|
|
50
|
+
# @!method compare_by_identity?
|
|
51
|
+
# Return whether elements are compared by object identity.
|
|
52
|
+
# @return [Boolean] Whether identity comparison is enabled.
|
|
53
|
+
# @abstract
|
|
54
|
+
#
|
|
55
|
+
# @!method select
|
|
56
|
+
# Return a collection of the same kind containing elements accepted by the block.
|
|
57
|
+
# @yield [element] Test each element. Returns an Enumerator without a block.
|
|
58
|
+
# @yieldparam element [BasicObject] The current element.
|
|
59
|
+
# @yieldreturn [BasicObject] A truthy value to retain the element.
|
|
60
|
+
# @return [Farce::Abstract::Collection, Enumerator] A new collection, or an Enumerator without a block.
|
|
61
|
+
# @abstract
|
|
62
|
+
#
|
|
63
|
+
# @!method filter
|
|
64
|
+
# Return elements accepted by the block, as with {#select}.
|
|
65
|
+
# @yield [element] Test each element. Returns an Enumerator without a block.
|
|
66
|
+
# @yieldparam element [BasicObject] The current element.
|
|
67
|
+
# @yieldreturn [BasicObject] A truthy value to retain the element.
|
|
68
|
+
# @return [Farce::Abstract::Collection, Enumerator] A new collection of the same kind, or an Enumerator.
|
|
69
|
+
# @see #select
|
|
70
|
+
# @abstract
|
|
71
|
+
#
|
|
72
|
+
# @!method reject
|
|
73
|
+
# Return a collection of the same kind excluding elements accepted by the block.
|
|
74
|
+
# @yield [element] Test each element. Returns an Enumerator without a block.
|
|
75
|
+
# @yieldparam element [BasicObject] The current element.
|
|
76
|
+
# @yieldreturn [BasicObject] A truthy value to exclude the element.
|
|
77
|
+
# @return [Farce::Abstract::Collection, Enumerator] A new collection, or an Enumerator without a block.
|
|
78
|
+
# @abstract
|
|
79
|
+
#
|
|
80
|
+
# @!method <<(element)
|
|
81
|
+
# Add an element using the collection's insertion rules and return self.
|
|
82
|
+
# @param element [BasicObject] The element to add.
|
|
83
|
+
# @return [self] The collection.
|
|
84
|
+
# @abstract
|
|
85
|
+
class Collection
|
|
86
|
+
include Enumerable
|
|
87
|
+
include Internal::Copyable
|
|
88
|
+
include Internal::Inspect
|
|
89
|
+
|
|
90
|
+
# @overload [](*elements, **options)
|
|
91
|
+
# Construct a collection from the arguments.
|
|
92
|
+
# @param elements [Array<BasicObject>] The initial elements.
|
|
93
|
+
# @param **options [Hash] Additional options passed to the constructor.
|
|
94
|
+
# @return [Farce::Abstract::Collection] A new instance of the receiving class.
|
|
95
|
+
def self.[](*elements, **) = new(elements, **)
|
|
96
|
+
|
|
97
|
+
# Return the number of elements currently present.
|
|
98
|
+
# @return [Integer] The collection's size.
|
|
99
|
+
def length = size
|
|
100
|
+
|
|
101
|
+
# Return whether no elements are present.
|
|
102
|
+
# @return [Boolean] Whether the collection is empty.
|
|
103
|
+
def empty? = size.zero?
|
|
104
|
+
|
|
105
|
+
# Count all elements, matching elements, or elements accepted by a block.
|
|
106
|
+
# Without an argument or block, read the size without traversing elements.
|
|
107
|
+
# @param item [BasicObject] The value to count. Omit to count all elements or use the block.
|
|
108
|
+
# @yield [element] Select elements to count when item is omitted.
|
|
109
|
+
# @yieldparam element [BasicObject] The current element.
|
|
110
|
+
# @yieldreturn [BasicObject] A truthy value to count the element.
|
|
111
|
+
# @return [Integer] The number of matching elements.
|
|
112
|
+
def count(item = UNDEFINED)
|
|
113
|
+
return size if item.equal?(UNDEFINED) && !block_given?
|
|
114
|
+
|
|
115
|
+
if item.equal?(UNDEFINED)
|
|
116
|
+
super() { yield it }
|
|
117
|
+
else
|
|
118
|
+
warn("given block not used") if block_given?
|
|
119
|
+
super(item, &nil)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Join the elements through Array#join.
|
|
124
|
+
# @param separator [String, nil] The separator. Nil uses Array's default separator.
|
|
125
|
+
# @return [String] The joined elements.
|
|
126
|
+
def join(separator = nil) = to_a.join(separator)
|
|
127
|
+
|
|
128
|
+
# @return [String] The class name and observed elements, suitable for debugging.
|
|
129
|
+
def to_s = inspect
|
|
130
|
+
|
|
131
|
+
# @api private
|
|
132
|
+
def inspect_with(inspector)
|
|
133
|
+
super do
|
|
134
|
+
yield if block_given?
|
|
135
|
+
inspector.breakable
|
|
136
|
+
inspector.group("[", "]") do
|
|
137
|
+
inspector.breakable ""
|
|
138
|
+
inspector.seplist(self, nil, :each_for_inspect) do |value|
|
|
139
|
+
inspector.group { inspect_value(inspector, value) }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
def each_for_inspect(&) = each(&)
|
|
148
|
+
def inspect_value(inspector, ...) = inspector.object(...)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|