farce 0.0.1.alpha2-x86_64-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.
Files changed (423) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +26 -0
  3. data/CONTRIBUTING.md +71 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +1524 -0
  6. data/SECURITY.md +10 -0
  7. data/docs/benchmarks.md +185 -0
  8. data/docs/gems/dry-types.md +290 -0
  9. data/docs/gems/msgpack.md +70 -0
  10. data/docs/gems/ractor-shim.md +63 -0
  11. data/docs/modes.md +628 -0
  12. data/docs/scopes.md +649 -0
  13. data/docs/variants.md +346 -0
  14. data/ext/ext_helper.rb +20 -0
  15. data/ext/farce/README.md +21 -0
  16. data/ext/farce/atom.c +1023 -0
  17. data/ext/farce/bounded_map.c +1683 -0
  18. data/ext/farce/containers.h +77 -0
  19. data/ext/farce/counter.c +399 -0
  20. data/ext/farce/darwin.c +100 -0
  21. data/ext/farce/depend +12 -0
  22. data/ext/farce/dict.c +1523 -0
  23. data/ext/farce/dict.h +152 -0
  24. data/ext/farce/drivers.c +237 -0
  25. data/ext/farce/exchanger.c +299 -0
  26. data/ext/farce/extconf.rb +99 -0
  27. data/ext/farce/farce.c +359 -0
  28. data/ext/farce/flag.c +288 -0
  29. data/ext/farce/io.c +338 -0
  30. data/ext/farce/lock.c +510 -0
  31. data/ext/farce/map.c +2240 -0
  32. data/ext/farce/priority_queue.c +2056 -0
  33. data/ext/farce/queue.c +1059 -0
  34. data/ext/farce/reactor.c +820 -0
  35. data/ext/farce/reactor.h +103 -0
  36. data/ext/farce/shareable.h +31 -0
  37. data/ext/farce/signal.c +350 -0
  38. data/ext/farce/transaction.c +354 -0
  39. data/ext/farce/transaction.h +40 -0
  40. data/ext/farce/tree_map.c +1953 -0
  41. data/ext/farce/trie.c +2020 -0
  42. data/ext/farce/unshareable.c +155 -0
  43. data/ext/farce/unshared_io_pool.h +234 -0
  44. data/ext/farce/unshared_signal.c +263 -0
  45. data/ext/farce/unshared_wait.h +193 -0
  46. data/ext/farce/unsupported.c +6 -0
  47. data/ext/farce/vector.c +1195 -0
  48. data/ext/farce/weak_map.c +1714 -0
  49. data/ext/java/org/farce/BoundedMap.java +394 -0
  50. data/ext/java/org/farce/FiberScheduler.java +141 -0
  51. data/ext/java/org/farce/PriorityKey.java +45 -0
  52. data/ext/java/org/farce/PriorityQueue.java +373 -0
  53. data/ext/java/org/farce/QueueSignal.java +28 -0
  54. data/ext/rebind/README.md +14 -0
  55. data/ext/rebind/extconf.rb +10 -0
  56. data/ext/rebind/rebind.c +186 -0
  57. data/lib/farce/_yard/internal.rb +13 -0
  58. data/lib/farce/_yard/macros.rb +61 -0
  59. data/lib/farce/_yard/ractor.rb +46 -0
  60. data/lib/farce/abstract/atom.rb +186 -0
  61. data/lib/farce/abstract/bounded_map.rb +232 -0
  62. data/lib/farce/abstract/collection.rb +151 -0
  63. data/lib/farce/abstract/concurrent_map.rb +381 -0
  64. data/lib/farce/abstract/counter.rb +193 -0
  65. data/lib/farce/abstract/duplicable_map.rb +229 -0
  66. data/lib/farce/abstract/exchanger.rb +26 -0
  67. data/lib/farce/abstract/flag.rb +71 -0
  68. data/lib/farce/abstract/lazy.rb +115 -0
  69. data/lib/farce/abstract/lease.rb +104 -0
  70. data/lib/farce/abstract/lease_map.rb +261 -0
  71. data/lib/farce/abstract/lease_pool.rb +91 -0
  72. data/lib/farce/abstract/lfu_map.rb +20 -0
  73. data/lib/farce/abstract/lru_map.rb +25 -0
  74. data/lib/farce/abstract/map.rb +345 -0
  75. data/lib/farce/abstract/molecule.rb +245 -0
  76. data/lib/farce/abstract/port.rb +74 -0
  77. data/lib/farce/abstract/priority_queue.rb +117 -0
  78. data/lib/farce/abstract/queue.rb +269 -0
  79. data/lib/farce/abstract/scheduler.rb +111 -0
  80. data/lib/farce/abstract/set.rb +910 -0
  81. data/lib/farce/abstract/sorted_set.rb +172 -0
  82. data/lib/farce/abstract/timer_queue.rb +136 -0
  83. data/lib/farce/abstract/tree_map.rb +269 -0
  84. data/lib/farce/abstract/value.rb +68 -0
  85. data/lib/farce/abstract/vector.rb +1126 -0
  86. data/lib/farce/abstract/weak_atom.rb +32 -0
  87. data/lib/farce/abstract/weak_key_map.rb +12 -0
  88. data/lib/farce/abstract/weak_map.rb +13 -0
  89. data/lib/farce/abstract/weak_set.rb +12 -0
  90. data/lib/farce/abstract/weak_value_map.rb +12 -0
  91. data/lib/farce/abstract.rb +17 -0
  92. data/lib/farce/atom.rb +293 -0
  93. data/lib/farce/class_mirror.rb +87 -0
  94. data/lib/farce/clock.rb +121 -0
  95. data/lib/farce/config.rb +229 -0
  96. data/lib/farce/counter.rb +71 -0
  97. data/lib/farce/deduper.rb +122 -0
  98. data/lib/farce/engine/jruby/bounded_map.rb +314 -0
  99. data/lib/farce/engine/jruby/fiber_scheduler.jar +0 -0
  100. data/lib/farce/engine/jruby/fiber_scheduler.rb +119 -0
  101. data/lib/farce/engine/jruby/lease_waiting.rb +19 -0
  102. data/lib/farce/engine/jruby/map.rb +505 -0
  103. data/lib/farce/engine/jruby/mutable_numeric_copy.rb +42 -0
  104. data/lib/farce/engine/jruby/signal.rb +147 -0
  105. data/lib/farce/engine/jruby.rb +63 -0
  106. data/lib/farce/engine/jvm/concurrent_weak_registry.rb +55 -0
  107. data/lib/farce/engine/jvm/counter.rb +102 -0
  108. data/lib/farce/engine/jvm/extension.rb +32 -0
  109. data/lib/farce/engine/jvm/farce.jar +0 -0
  110. data/lib/farce/engine/jvm/flag.rb +79 -0
  111. data/lib/farce/engine/jvm/priority_queue.rb +217 -0
  112. data/lib/farce/engine/jvm/tree_map.rb +350 -0
  113. data/lib/farce/engine/jvm/types.rb +180 -0
  114. data/lib/farce/engine/jvm.rb +19 -0
  115. data/lib/farce/engine/ruby/3.4/farce.so +0 -0
  116. data/lib/farce/engine/ruby/3.4/fiber_scheduler.rb +20 -0
  117. data/lib/farce/engine/ruby/3.4/port.rb +186 -0
  118. data/lib/farce/engine/ruby/3.4/ractor_methods.rb +26 -0
  119. data/lib/farce/engine/ruby/3.4/ractor_selector.rb +92 -0
  120. data/lib/farce/engine/ruby/3.4/rebind.so +0 -0
  121. data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
  122. data/lib/farce/engine/ruby/4.0/farce.so +0 -0
  123. data/lib/farce/engine/ruby/4.0/port.rb +19 -0
  124. data/lib/farce/engine/ruby/4.0/ractor_methods.rb +20 -0
  125. data/lib/farce/engine/ruby/4.0/ractor_selector.rb +108 -0
  126. data/lib/farce/engine/ruby/4.0/rebind.so +0 -0
  127. data/lib/farce/engine/ruby/4.0/vault.rb +74 -0
  128. data/lib/farce/engine/ruby/4.1/port.rb +21 -0
  129. data/lib/farce/engine/ruby/4.1/ractor_methods.rb +22 -0
  130. data/lib/farce/engine/ruby/4.1/ractor_selector.rb +25 -0
  131. data/lib/farce/engine/ruby/4.1/vault.rb +5 -0
  132. data/lib/farce/engine/ruby/fiber_scheduler.rb +32 -0
  133. data/lib/farce/engine/ruby/key_lock_map.rb +28 -0
  134. data/lib/farce/engine/ruby/shared/lease.rb +26 -0
  135. data/lib/farce/engine/ruby/shared/lease_pool.rb +24 -0
  136. data/lib/farce/engine/ruby/shared/main_scheduler.rb +9 -0
  137. data/lib/farce/engine/ruby/shared/parallel_scheduler.rb +9 -0
  138. data/lib/farce/engine/ruby/shared/proxy_owner.rb +31 -0
  139. data/lib/farce/engine/ruby/shared/ractor_methods.rb +34 -0
  140. data/lib/farce/engine/ruby/shared/ractor_selector.rb +328 -0
  141. data/lib/farce/engine/ruby/shared/strict_map.rb +13 -0
  142. data/lib/farce/engine/ruby/shared/unshared_vector.rb +14 -0
  143. data/lib/farce/engine/ruby/shared/vault.rb +144 -0
  144. data/lib/farce/engine/ruby/shared/vault_weak_map.rb +336 -0
  145. data/lib/farce/engine/ruby/shared/weak_atom.rb +54 -0
  146. data/lib/farce/engine/ruby/shared/weak_map.rb +413 -0
  147. data/lib/farce/engine/ruby.rb +130 -0
  148. data/lib/farce/engine/shared/atom.rb +10 -0
  149. data/lib/farce/engine/shared/exchanger.rb +130 -0
  150. data/lib/farce/engine/shared/identity_key.rb +22 -0
  151. data/lib/farce/engine/shared/lease.rb +10 -0
  152. data/lib/farce/engine/shared/lease_pool.rb +10 -0
  153. data/lib/farce/engine/shared/main_scheduler.rb +20 -0
  154. data/lib/farce/engine/shared/map_key_coordination.rb +226 -0
  155. data/lib/farce/engine/shared/parallel_scheduler.rb +9 -0
  156. data/lib/farce/engine/shared/port.rb +44 -0
  157. data/lib/farce/engine/shared/portable_bounded_map.rb +619 -0
  158. data/lib/farce/engine/shared/proxy_owner.rb +43 -0
  159. data/lib/farce/engine/shared/queue.rb +233 -0
  160. data/lib/farce/engine/shared/ractor_methods.rb +73 -0
  161. data/lib/farce/engine/shared/rebindable.rb +15 -0
  162. data/lib/farce/engine/shared/strict_atom.rb +73 -0
  163. data/lib/farce/engine/shared/strict_map.rb +117 -0
  164. data/lib/farce/engine/shared/strict_queue_values.rb +27 -0
  165. data/lib/farce/engine/shared/strict_tree_map.rb +56 -0
  166. data/lib/farce/engine/shared/transaction_map_backend.rb +20 -0
  167. data/lib/farce/engine/shared/trie.rb +317 -0
  168. data/lib/farce/engine/shared/trie_builder.rb +199 -0
  169. data/lib/farce/engine/shared/unshareable.rb +14 -0
  170. data/lib/farce/engine/shared/unshared_atom.rb +256 -0
  171. data/lib/farce/engine/shared/unshared_priority_queue.rb +9 -0
  172. data/lib/farce/engine/shared/unshared_queue.rb +18 -0
  173. data/lib/farce/engine/shared/unshared_signal.rb +21 -0
  174. data/lib/farce/engine/shared/unshared_vector.rb +377 -0
  175. data/lib/farce/engine/shared/unshared_weak_atom.rb +30 -0
  176. data/lib/farce/engine/shared/unshared_weak_map.rb +445 -0
  177. data/lib/farce/engine/shared/vault.rb +31 -0
  178. data/lib/farce/engine/shared/vector.rb +83 -0
  179. data/lib/farce/engine/shared/weak_atom/base.rb +189 -0
  180. data/lib/farce/engine/shared/weak_atom.rb +20 -0
  181. data/lib/farce/engine/shared/weak_map/cell.rb +99 -0
  182. data/lib/farce/engine/shared/weak_map/index.rb +249 -0
  183. data/lib/farce/engine/shared/weak_map/lock.rb +80 -0
  184. data/lib/farce/engine/shared/weak_map/reference.rb +33 -0
  185. data/lib/farce/engine/shared.rb +63 -0
  186. data/lib/farce/engine/truffleruby/fiber_scheduler.rb +13 -0
  187. data/lib/farce/engine/truffleruby/lock.rb +121 -0
  188. data/lib/farce/engine/truffleruby/map.rb +656 -0
  189. data/lib/farce/engine/truffleruby/native/counter.rb +105 -0
  190. data/lib/farce/engine/truffleruby/native/flag.rb +77 -0
  191. data/lib/farce/engine/truffleruby/native/ordered_array_support.rb +67 -0
  192. data/lib/farce/engine/truffleruby/native/priority_queue.rb +388 -0
  193. data/lib/farce/engine/truffleruby/native/tree_map.rb +51 -0
  194. data/lib/farce/engine/truffleruby/native/unsafe_tree_map.rb +350 -0
  195. data/lib/farce/engine/truffleruby/signal.rb +77 -0
  196. data/lib/farce/engine/truffleruby.rb +148 -0
  197. data/lib/farce/envelope.rb +335 -0
  198. data/lib/farce/error.rb +35 -0
  199. data/lib/farce/exchanger.rb +41 -0
  200. data/lib/farce/flag.rb +27 -0
  201. data/lib/farce/integrations/active_support/blank.rb +68 -0
  202. data/lib/farce/integrations/active_support/clock.rb +17 -0
  203. data/lib/farce/integrations/active_support/duplicable.rb +78 -0
  204. data/lib/farce/integrations/active_support/map.rb +175 -0
  205. data/lib/farce/integrations/active_support/set.rb +60 -0
  206. data/lib/farce/integrations/active_support/value_serialization.rb +17 -0
  207. data/lib/farce/integrations/active_support/vector.rb +231 -0
  208. data/lib/farce/integrations/active_support.rb +9 -0
  209. data/lib/farce/integrations/activesupport.rb +5 -0
  210. data/lib/farce/integrations/bson.rb +108 -0
  211. data/lib/farce/integrations/cbor.rb +51 -0
  212. data/lib/farce/integrations/concurrent.rb +112 -0
  213. data/lib/farce/integrations/dry-types.rb +5 -0
  214. data/lib/farce/integrations/dry_types.rb +694 -0
  215. data/lib/farce/integrations/json.rb +7 -0
  216. data/lib/farce/integrations/msgpack.rb +112 -0
  217. data/lib/farce/integrations/oj.rb +69 -0
  218. data/lib/farce/integrations/psych.rb +191 -0
  219. data/lib/farce/integrations/ractor-sharing.rb +5 -0
  220. data/lib/farce/integrations/ractor-tmvar.rb +5 -0
  221. data/lib/farce/integrations/ractor_sharing.rb +172 -0
  222. data/lib/farce/integrations/ractor_tmvar.rb +64 -0
  223. data/lib/farce/integrations/shared/to_json.rb +42 -0
  224. data/lib/farce/integrations/sorted_set.rb +11 -0
  225. data/lib/farce/integrations/weakref.rb +38 -0
  226. data/lib/farce/integrations/yajl.rb +10 -0
  227. data/lib/farce/integrations.rb +156 -0
  228. data/lib/farce/internal/_frozen_config.rb +11 -0
  229. data/lib/farce/internal/autoloads.rb +47 -0
  230. data/lib/farce/internal/blocking_priority_queue.rb +122 -0
  231. data/lib/farce/internal/converter.rb +106 -0
  232. data/lib/farce/internal/copyable.rb +31 -0
  233. data/lib/farce/internal/delegation.rb +20 -0
  234. data/lib/farce/internal/external_transaction.rb +59 -0
  235. data/lib/farce/internal/fake_ractor.rb +179 -0
  236. data/lib/farce/internal/freeze.rb +118 -0
  237. data/lib/farce/internal/inspect.rb +157 -0
  238. data/lib/farce/internal/key_lock_map.rb +29 -0
  239. data/lib/farce/internal/key_normalizer.rb +289 -0
  240. data/lib/farce/internal/lease_initialization.rb +115 -0
  241. data/lib/farce/internal/lease_map.rb +441 -0
  242. data/lib/farce/internal/lease_pool_state.rb +228 -0
  243. data/lib/farce/internal/lease_state.rb +342 -0
  244. data/lib/farce/internal/lease_waiting.rb +13 -0
  245. data/lib/farce/internal/managed_queue.rb +26 -0
  246. data/lib/farce/internal/map_value_modes.rb +227 -0
  247. data/lib/farce/internal/marshal_support.rb +227 -0
  248. data/lib/farce/internal/mixin.rb +20 -0
  249. data/lib/farce/internal/mutable_ordered_key_lock_map.rb +63 -0
  250. data/lib/farce/internal/noncopyable.rb +17 -0
  251. data/lib/farce/internal/ordered_key_lock_map.rb +69 -0
  252. data/lib/farce/internal/pool_supervisor.rb +41 -0
  253. data/lib/farce/internal/pool_worker.rb +61 -0
  254. data/lib/farce/internal/portable_transaction/reservation_entry.rb +29 -0
  255. data/lib/farce/internal/portable_transaction/strong_map_entry.rb +137 -0
  256. data/lib/farce/internal/portable_transaction/strong_map_size_entry.rb +44 -0
  257. data/lib/farce/internal/portable_transaction/tree_entry.rb +64 -0
  258. data/lib/farce/internal/portable_transaction.rb +164 -0
  259. data/lib/farce/internal/proxy_owner_notifications.rb +29 -0
  260. data/lib/farce/internal/reservation_waiting.rb +24 -0
  261. data/lib/farce/internal/scheduled_task.rb +48 -0
  262. data/lib/farce/internal/scheduler_io.rb +171 -0
  263. data/lib/farce/internal/scheduler_lifecycle.rb +314 -0
  264. data/lib/farce/internal/select_scheduler.rb +235 -0
  265. data/lib/farce/internal/storage.rb +162 -0
  266. data/lib/farce/internal/strict_lease.rb +30 -0
  267. data/lib/farce/internal/strict_lease_map.rb +20 -0
  268. data/lib/farce/internal/strict_lease_pool.rb +29 -0
  269. data/lib/farce/internal/thread_pool.rb +166 -0
  270. data/lib/farce/internal/transaction_conflict.rb +9 -0
  271. data/lib/farce/internal/transaction_freeze_guard.rb +30 -0
  272. data/lib/farce/internal/transaction_map_snapshot.rb +123 -0
  273. data/lib/farce/internal/undefined.rb +22 -0
  274. data/lib/farce/internal/unshared_lease.rb +29 -0
  275. data/lib/farce/internal/unshared_lease_pool.rb +34 -0
  276. data/lib/farce/internal/unshared_queue_waiting.rb +28 -0
  277. data/lib/farce/internal/value_serialization.rb +13 -0
  278. data/lib/farce/internal/weak_map_value_modes.rb +58 -0
  279. data/lib/farce/internal/weak_mode_manager.rb +26 -0
  280. data/lib/farce/internal.rb +129 -0
  281. data/lib/farce/lazy.rb +100 -0
  282. data/lib/farce/lazy_ref.rb +40 -0
  283. data/lib/farce/lease.rb +28 -0
  284. data/lib/farce/lease_map.rb +34 -0
  285. data/lib/farce/lease_pool.rb +29 -0
  286. data/lib/farce/lfu_map.rb +53 -0
  287. data/lib/farce/local/atom.rb +23 -0
  288. data/lib/farce/local/counter.rb +88 -0
  289. data/lib/farce/local/flag.rb +65 -0
  290. data/lib/farce/local/lazy.rb +38 -0
  291. data/lib/farce/local/lazy_ref.rb +36 -0
  292. data/lib/farce/local/lease.rb +77 -0
  293. data/lib/farce/local/lease_map.rb +80 -0
  294. data/lib/farce/local/lease_pool.rb +38 -0
  295. data/lib/farce/local/lfu_map.rb +55 -0
  296. data/lib/farce/local/lru_map.rb +62 -0
  297. data/lib/farce/local/map.rb +47 -0
  298. data/lib/farce/local/molecule.rb +45 -0
  299. data/lib/farce/local/priority_queue.rb +53 -0
  300. data/lib/farce/local/queue.rb +32 -0
  301. data/lib/farce/local/scoped.rb +166 -0
  302. data/lib/farce/local/set.rb +18 -0
  303. data/lib/farce/local/sorted_set.rb +50 -0
  304. data/lib/farce/local/timer_queue.rb +41 -0
  305. data/lib/farce/local/tree_map.rb +47 -0
  306. data/lib/farce/local/vector.rb +30 -0
  307. data/lib/farce/local/weak_atom.rb +23 -0
  308. data/lib/farce/local/weak_key_map.rb +39 -0
  309. data/lib/farce/local/weak_map.rb +39 -0
  310. data/lib/farce/local/weak_set.rb +18 -0
  311. data/lib/farce/local/weak_value_map.rb +39 -0
  312. data/lib/farce/local.rb +35 -0
  313. data/lib/farce/lock.rb +54 -0
  314. data/lib/farce/lru_map.rb +63 -0
  315. data/lib/farce/map.rb +58 -0
  316. data/lib/farce/mode_manager.rb +142 -0
  317. data/lib/farce/molecule.rb +60 -0
  318. data/lib/farce/mutable.rb +171 -0
  319. data/lib/farce/pool.rb +332 -0
  320. data/lib/farce/port.rb +134 -0
  321. data/lib/farce/priority_queue.rb +70 -0
  322. data/lib/farce/proxy/register.rb +101 -0
  323. data/lib/farce/proxy/supervisor.rb +137 -0
  324. data/lib/farce/proxy/wrapper.rb +49 -0
  325. data/lib/farce/proxy.rb +291 -0
  326. data/lib/farce/queue.rb +60 -0
  327. data/lib/farce/ractor.rb +269 -0
  328. data/lib/farce/read_write_lock.rb +256 -0
  329. data/lib/farce/reference.rb +158 -0
  330. data/lib/farce/resolv/dns.rb +42 -0
  331. data/lib/farce/resolv.rb +85 -0
  332. data/lib/farce/scheduler.rb +536 -0
  333. data/lib/farce/set.rb +39 -0
  334. data/lib/farce/shareable.rb +150 -0
  335. data/lib/farce/signal.rb +97 -0
  336. data/lib/farce/sorted_set.rb +36 -0
  337. data/lib/farce/strict/atom.rb +34 -0
  338. data/lib/farce/strict/counter.rb +10 -0
  339. data/lib/farce/strict/exchanger.rb +25 -0
  340. data/lib/farce/strict/flag.rb +10 -0
  341. data/lib/farce/strict/lazy.rb +26 -0
  342. data/lib/farce/strict/lazy_ref.rb +26 -0
  343. data/lib/farce/strict/lease.rb +27 -0
  344. data/lib/farce/strict/lease_map.rb +33 -0
  345. data/lib/farce/strict/lease_pool.rb +28 -0
  346. data/lib/farce/strict/lfu_map.rb +27 -0
  347. data/lib/farce/strict/lru_map.rb +28 -0
  348. data/lib/farce/strict/map.rb +54 -0
  349. data/lib/farce/strict/molecule.rb +16 -0
  350. data/lib/farce/strict/port.rb +40 -0
  351. data/lib/farce/strict/priority_queue.rb +20 -0
  352. data/lib/farce/strict/queue.rb +17 -0
  353. data/lib/farce/strict/set.rb +14 -0
  354. data/lib/farce/strict/sorted_set.rb +19 -0
  355. data/lib/farce/strict/timer_queue.rb +13 -0
  356. data/lib/farce/strict/tree_map.rb +27 -0
  357. data/lib/farce/strict/vector.rb +24 -0
  358. data/lib/farce/strict/weak_atom.rb +31 -0
  359. data/lib/farce/strict/weak_key_map.rb +49 -0
  360. data/lib/farce/strict/weak_map.rb +49 -0
  361. data/lib/farce/strict/weak_set.rb +14 -0
  362. data/lib/farce/strict/weak_value_map.rb +48 -0
  363. data/lib/farce/strict.rb +28 -0
  364. data/lib/farce/system.rb +40 -0
  365. data/lib/farce/thread_scheduler.rb +70 -0
  366. data/lib/farce/timer_queue.rb +66 -0
  367. data/lib/farce/transaction/atom.rb +73 -0
  368. data/lib/farce/transaction/map.rb +25 -0
  369. data/lib/farce/transaction/map_operations.rb +143 -0
  370. data/lib/farce/transaction/molecule.rb +90 -0
  371. data/lib/farce/transaction/mutable.rb +61 -0
  372. data/lib/farce/transaction/set.rb +17 -0
  373. data/lib/farce/transaction/set_operations.rb +48 -0
  374. data/lib/farce/transaction/sorted_set.rb +18 -0
  375. data/lib/farce/transaction/tree_map.rb +78 -0
  376. data/lib/farce/transaction/vector.rb +139 -0
  377. data/lib/farce/transaction/wrapper.rb +202 -0
  378. data/lib/farce/transaction.rb +343 -0
  379. data/lib/farce/tree_map.rb +56 -0
  380. data/lib/farce/unsafe/lfu_map.rb +36 -0
  381. data/lib/farce/unsafe/lru_map.rb +36 -0
  382. data/lib/farce/unsafe/tree_map.rb +21 -0
  383. data/lib/farce/unsafe.rb +29 -0
  384. data/lib/farce/unshareable.rb +67 -0
  385. data/lib/farce/unshared/atom.rb +24 -0
  386. data/lib/farce/unshared/counter.rb +10 -0
  387. data/lib/farce/unshared/flag.rb +10 -0
  388. data/lib/farce/unshared/lazy.rb +38 -0
  389. data/lib/farce/unshared/lazy_ref.rb +26 -0
  390. data/lib/farce/unshared/lease.rb +27 -0
  391. data/lib/farce/unshared/lease_map.rb +26 -0
  392. data/lib/farce/unshared/lease_pool.rb +25 -0
  393. data/lib/farce/unshared/lfu_map.rb +20 -0
  394. data/lib/farce/unshared/lru_map.rb +20 -0
  395. data/lib/farce/unshared/map.rb +49 -0
  396. data/lib/farce/unshared/molecule.rb +16 -0
  397. data/lib/farce/unshared/priority_queue.rb +16 -0
  398. data/lib/farce/unshared/queue.rb +27 -0
  399. data/lib/farce/unshared/set.rb +14 -0
  400. data/lib/farce/unshared/sorted_set.rb +28 -0
  401. data/lib/farce/unshared/timer_queue.rb +16 -0
  402. data/lib/farce/unshared/tree_map.rb +21 -0
  403. data/lib/farce/unshared/vector.rb +19 -0
  404. data/lib/farce/unshared/weak_atom.rb +31 -0
  405. data/lib/farce/unshared/weak_key_map.rb +44 -0
  406. data/lib/farce/unshared/weak_map.rb +44 -0
  407. data/lib/farce/unshared/weak_set.rb +14 -0
  408. data/lib/farce/unshared/weak_value_map.rb +43 -0
  409. data/lib/farce/unshared.rb +28 -0
  410. data/lib/farce/vector.rb +228 -0
  411. data/lib/farce/version.rb +8 -0
  412. data/lib/farce/walker/definitions.rb +186 -0
  413. data/lib/farce/walker/modification.rb +355 -0
  414. data/lib/farce/walker.rb +319 -0
  415. data/lib/farce/weak_atom.rb +121 -0
  416. data/lib/farce/weak_key_map.rb +31 -0
  417. data/lib/farce/weak_map.rb +33 -0
  418. data/lib/farce/weak_ref.rb +67 -0
  419. data/lib/farce/weak_set.rb +82 -0
  420. data/lib/farce/weak_value.rb +195 -0
  421. data/lib/farce/weak_value_map.rb +32 -0
  422. data/lib/farce.rb +519 -0
  423. metadata +468 -0
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A Ractor-shareable atomic reference that retains its value weakly.
7
+ # Values support :raise (the default), :make_shareable, and :dedup.
8
+ # The value becomes nil after collection when no strong references remain.
9
+ # With :dedup, retain the canonical result returned by store or update.
10
+ # Keeping only the input alive may not keep the stored result alive.
11
+ # Assignment evaluates to the input rather than the canonical result.
12
+ # Comparisons observe the stored object without preparing their operands.
13
+ #
14
+ # @example Publishing the original object without keeping it alive
15
+ # value = []
16
+ # atom = Farce::WeakAtom.new(value, mode: :make_shareable)
17
+ # atom.value.equal?(value) # => true
18
+ # value = nil
19
+ # # After collection, atom.value returns nil.
20
+ class WeakAtom < Farce::Abstract::WeakAtom
21
+ include Shareable::Delegated
22
+
23
+ TIMED_OUT = Object.new.freeze
24
+ private_constant :TIMED_OUT
25
+
26
+ # @param value [BasicObject, nil] the initial value
27
+ # @param mode [Symbol] :raise, :make_shareable, or :dedup
28
+ # @param compare_by_identity [Boolean] whether comparisons use object identity
29
+ def initialize(value = nil, mode: :raise, compare_by_identity: false)
30
+ @manager = Internal::WeakModeManager.new(mode:)
31
+ super(@manager.wrap(value), compare_by_identity:)
32
+ end
33
+
34
+ # The default mode used to prepare replacement values.
35
+ # @return [Symbol]
36
+ def mode = @manager.mode
37
+
38
+ # (see Abstract::Atom#store)
39
+ # @param mode [Symbol, nil] the replacement's mode, or nil for the default
40
+ def store(new_value, mode: nil, timeout: nil, &)
41
+ check_frozen!
42
+ super(@manager.wrap(new_value, mode:), timeout:, &)
43
+ end
44
+
45
+ # (see Abstract::Atom#swap)
46
+ # @param mode [Symbol, nil] the replacement's mode, or nil for the default
47
+ def swap(new_value, mode: nil, timeout: nil, &)
48
+ check_frozen!
49
+ super(@manager.wrap(new_value, mode:), timeout:, &)
50
+ end
51
+
52
+ # (see Abstract::Atom#store_if_absent)
53
+ # @param mode [Symbol, nil] the result's mode, or nil for the default
54
+ def store_if_absent(mode: nil, timeout: nil)
55
+ raise LocalJumpError, "no block given" unless block_given?
56
+ @manager.validate_mode!(mode)
57
+ super(timeout:) do
58
+ value = yield
59
+ check_frozen!
60
+ @manager.wrap(value, mode:)
61
+ end
62
+ end
63
+
64
+ # (see Abstract::Atom#update)
65
+ # @param mode [Symbol, nil] the result's mode, or nil for the default
66
+ def update(mode: nil, timeout: nil)
67
+ raise LocalJumpError, "no block given" unless block_given?
68
+ @manager.validate_mode!(mode)
69
+ super(timeout:) do |current|
70
+ value = yield(current)
71
+ check_frozen!
72
+ @manager.wrap(value, mode:)
73
+ end
74
+ end
75
+
76
+ # (see Abstract::Atom#upsert)
77
+ # @param mode [Symbol, nil] the replacement's mode, or nil for the default
78
+ def upsert(initial, mode: nil, timeout: nil)
79
+ raise LocalJumpError, "no block given" unless block_given?
80
+ @manager.validate_mode!(mode)
81
+ @atom.update(timeout:) do |current|
82
+ value = nil.equal?(current) ? initial : yield(current)
83
+ check_frozen!
84
+ @manager.wrap(value, mode:)
85
+ end
86
+ end
87
+
88
+ # (see Abstract::Atom#compare_and_set)
89
+ # @param mode [Symbol, nil] the replacement's mode, or nil for the default
90
+ def compare_and_set(expected, replacement, mode: nil, timeout: nil)
91
+ @manager.validate_mode!(mode)
92
+ matched = false
93
+ @atom.update(timeout:) do |current|
94
+ next current unless values_equal?(current, expected)
95
+ check_frozen!
96
+ prepared = @manager.wrap(replacement, mode:)
97
+ matched = true
98
+ prepared
99
+ end
100
+ matched
101
+ end
102
+
103
+ # (see Abstract::Atom#wait_until_changed)
104
+ def wait_until_changed(expected, timeout: nil, &fallback)
105
+ deadline = Internal.timeout_deadline(timeout)
106
+ while true
107
+ current = @atom.get(timeout: Internal.remaining_timeout(deadline)) { TIMED_OUT }
108
+ return fallback&.call if TIMED_OUT.equal?(current)
109
+ return current unless values_equal?(current, expected)
110
+ result = @atom.wait_until_changed(current, timeout: Internal.remaining_timeout(deadline)) { TIMED_OUT }
111
+ return fallback&.call if TIMED_OUT.equal?(result)
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def internal_atom_class = Internal::WeakAtom
118
+ def freeze_backend = @atom
119
+ def values_equal?(left, right) = @manager.same_value?(left, right, identity: compare_by_identity?)
120
+ end
121
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A concurrent map with weak shareable keys and strongly retained values.
7
+ # Transfer modes apply only to values. Keys are stored directly.
8
+ # Entries disappear after their keys are collected. A value that references
9
+ # its key, including through an envelope, can keep that key alive.
10
+ #
11
+ # @example Associating mutable metadata with a shareable object
12
+ # owner = Object.new.freeze
13
+ # map = Farce::WeakKeyMap.new
14
+ # map[owner] = { visits: 1 }
15
+ # map.update(owner) { |metadata| { visits: metadata[:visits] + 1 } }
16
+ # map[owner] # => { visits: 2 }
17
+ #
18
+ # # The entry can disappear once its key is collected.
19
+ # owner = nil
20
+ class WeakKeyMap < Farce::Abstract::WeakKeyMap
21
+ include Internal::MapValueModes
22
+ include Shareable::Delegated
23
+
24
+ private
25
+
26
+ def new_map(**) = Internal::StrictWeakKeyMap.new(**)
27
+ def freeze_backend = @map
28
+ end
29
+
30
+ Internal::KeyNormalizer.prepare_concurrent_class(Internal::StrictWeakKeyMap)
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A Ractor-shareable concurrent map with weak shareable keys and weak values.
7
+ # Entries disappear after a weakly held object is collected.
8
+ #
9
+ # Supported modes are `:raise` (the default), `:make_shareable`, and `:dedup`.
10
+ # Modes apply only to values. Keys must already be shareable.
11
+ #
12
+ # With `:dedup`, retain the canonical result returned by store or update,
13
+ # as it might differ from the input and could be immediately collected.
14
+ # Assignment evaluates to the input rather than the canonical result.
15
+ #
16
+ # @example Publishing a value without retaining it strongly
17
+ # key = Object.new.freeze
18
+ # value = []
19
+ # map = Farce::WeakMap.new(mode: :make_shareable)
20
+ # map[key] = value
21
+ # map[key].equal?(value) # => true
22
+ class WeakMap < Farce::Abstract::WeakMap
23
+ include Internal::WeakMapValueModes
24
+ include Shareable::Delegated
25
+
26
+ private
27
+
28
+ def new_map(**) = Internal::StrictWeakMap.new(**)
29
+ def freeze_backend = @map
30
+ end
31
+
32
+ Internal::KeyNormalizer.prepare_concurrent_class(Internal::StrictWeakMap)
33
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "delegate"
6
+
7
+ module Farce
8
+ # Drop-in replacement for Ruby's WeakRef class that is Ractor-friendly.
9
+ #
10
+ # @example
11
+ # foo = Object.new # create a new object instance
12
+ # p foo.to_s # original's class
13
+ # foo = Farce::WeakRef.new(foo) # reassign foo with WeakRef instance
14
+ # p foo.to_s # should be same class
15
+ # GC.start # start the garbage collector
16
+ # p foo.to_s # should raise exception (recycled)
17
+ class WeakRef < Delegator
18
+ include Internal::MarshalSupport::WeakRef
19
+
20
+ recycled = allocate
21
+ recycled.instance_variable_set(:@value, WeakValue::RECYCLED)
22
+
23
+ class << recycled
24
+ undef marshal_dump
25
+
26
+ # @api private
27
+ def _dump(_) = "recycled"
28
+ end
29
+
30
+ # @api private
31
+ RECYCLED = Kernel.instance_method(:freeze).bind_call(recycled)
32
+
33
+ # Alias for {WeakRefError} to mimic `::WeakRef::RefError`
34
+ RefError = WeakRefError
35
+
36
+ # @api private
37
+ def self._load(state)
38
+ raise TypeError, "invalid weak reference state" unless state == "recycled"
39
+ RECYCLED
40
+ end
41
+
42
+ def initialize(value)
43
+ @value = WeakValue.new(value)
44
+ super
45
+ Kernel.instance_method(:freeze).bind_call(self)
46
+ end
47
+
48
+ # @api private
49
+ def __getobj__ = @value.value # :nodoc:
50
+
51
+ # @api private
52
+ def __setobj__(_) = nil # :nodoc:
53
+
54
+ # @return [Boolean] true if the referenced object is still alive and reachable
55
+ def weakref_alive? = @value.alive?
56
+
57
+ private
58
+
59
+ def respond_to_missing?(name, include_private = false)
60
+ return false if Internal.marshal_protocol_method?(name)
61
+ super
62
+ end
63
+
64
+ def initialize_dup(other) = initialize_copy(other)
65
+ def initialize_clone(other, **) = initialize_copy(other)
66
+ end
67
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A Ractor-shareable concurrent set that retains prepared elements weakly.
7
+ # Elements support :raise (the default), :make_shareable, and :dedup.
8
+ # Membership refers to the prepared element itself. Lookup and deletion do
9
+ # not freeze or deduplicate their arguments. Already-shareable elements pass
10
+ # through unchanged, as with other mode-backed containers.
11
+ #
12
+ # With :dedup, the stored canonical element can differ from the input.
13
+ # Keeping only the input alive may not keep that element alive. Callers are
14
+ # responsible for retaining elements they need. Both add and add? retain
15
+ # their usual set return values rather than returning the stored element.
16
+ #
17
+ # @example Tracking an object without keeping it alive
18
+ # resource = []
19
+ # set = Farce::WeakSet.new(mode: :make_shareable)
20
+ # set.add(resource)
21
+ # set.first.equal?(resource) # => true
22
+ # resource = nil
23
+ # # After collection, the set can become empty.
24
+ class WeakSet < Farce::Abstract::WeakSet
25
+ include Shareable::Delegated
26
+
27
+ # The default mode used to prepare elements for insertion.
28
+ # @return [Symbol] :raise, :make_shareable, or :dedup
29
+ def mode = @manager.mode
30
+
31
+ # (see Abstract::Set#include?)
32
+ def include?(element)
33
+ key = lookup_key(normalize_element(element))
34
+ !MISSING_KEY.equal?(key) && @map.key?(key)
35
+ end
36
+ alias member? include?
37
+ alias === include?
38
+
39
+ # (see Abstract::Set#delete)
40
+ def delete(element)
41
+ check_frozen!
42
+ key = lookup_key(normalize_element(element))
43
+ @map.delete(key) unless MISSING_KEY.equal?(key)
44
+ self
45
+ end
46
+
47
+ # (see Abstract::Set#delete?)
48
+ def delete?(element) # rubocop:disable Naming/PredicateMethod
49
+ check_frozen!
50
+ key = lookup_key(normalize_element(element))
51
+ self unless MISSING_KEY.equal?(key) || !@map.delete(key)
52
+ end
53
+
54
+ protected
55
+
56
+ # Canonical imports bypass normalization, but still prepare external elements.
57
+ def add_stored(key, value) = super(@manager.wrap(key), value)
58
+
59
+ private
60
+
61
+ def initialize_value_mode(mode)
62
+ mode = :raise if UNDEFINED.equal?(mode)
63
+ @manager = Internal::WeakModeManager.new(mode:)
64
+ end
65
+
66
+ def add_normalized?(element, mode: UNDEFINED)
67
+ selected = UNDEFINED.equal?(mode) ? nil : mode
68
+ super(@manager.wrap(element, mode: selected))
69
+ end
70
+
71
+ def lookup_key(element)
72
+ return element if Ractor.shareable?(element)
73
+ return MISSING_KEY if identity_membership?(element)
74
+ structural_key(element)
75
+ end
76
+
77
+ def new_map(entries = nil, **)
78
+ entries = entries&.map { |element, value| [@manager.wrap(element), value] }
79
+ Strict::WeakMap.new(entries, **)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A weak value is similar to a {WeakRef}, but does not delegate method calls to the referenced object.
7
+ # If a weak value is created for a shareable object, it will also be shareable.
8
+ # If {#freeze} is called, the referenced object will be made shareable (unless it has been garbage collected).
9
+ #
10
+ # @example
11
+ # object = Object.new
12
+ # weak = Farce::WeakValue.new(object)
13
+ # weak.value == object # => true
14
+ # weak.alive? # => true
15
+ #
16
+ # # Shareability traversal
17
+ # Ractor.shareable?(object) # => false
18
+ # Ractor.shareable?(weak) # => false
19
+ #
20
+ # Ractor.make_shareable(weak)
21
+ # Ractor.shareable?(weak) # => true
22
+ # Ractor.shareable?(object) # => true
23
+ #
24
+ # # lets assume that the object has been garbage collected
25
+ # object = nil
26
+ # GC.start
27
+ #
28
+ # weak.alive? # => false
29
+ # weak.value # WeakRefError: Invalid Reference - probably recycled
30
+ class WeakValue
31
+ include Internal::MarshalSupport::WeakValue
32
+ include Abstract::Value
33
+ include Internal::Inspect
34
+
35
+ MOVED = Object.new.freeze
36
+ private_constant :MOVED
37
+
38
+ nil_value = new
39
+
40
+ class << nil_value
41
+ undef marshal_dump
42
+
43
+ # @api private
44
+ def _dump(_) = "nil"
45
+
46
+ def dup = self
47
+ def clone(**) = self
48
+ def value = nil
49
+ def alive? = true
50
+ def moved? = false
51
+ def ractor_shareable? = true
52
+
53
+ private
54
+
55
+ def _value = nil
56
+ def state_and_value = [:alive, nil]
57
+ end
58
+
59
+ nil_value.instance_variable_set(:@mutex, nil)
60
+
61
+ NIL_VALUE = nil_value.freeze
62
+ private_constant :NIL_VALUE
63
+
64
+ recycled = new
65
+ class << recycled
66
+ undef marshal_dump
67
+
68
+ # @api private
69
+ def _dump(_) = "recycled"
70
+
71
+ def dup = self
72
+ def clone(**) = self
73
+ def alive? = false
74
+ def moved? = false
75
+ def ractor_shareable? = true
76
+
77
+ private
78
+
79
+ def _value = nil
80
+ def state_and_value = [:recycled, nil]
81
+ end
82
+
83
+ # @api private
84
+ RECYCLED = recycled.freeze
85
+
86
+ # @param (see #initialize)
87
+ # @return [WeakValue] a new weak value wrapping the given object
88
+ # @see #initialize
89
+ def self.new(value) = value.nil? ? NIL_VALUE : super
90
+
91
+ # @api private
92
+ def self._load(state)
93
+ case state
94
+ when "nil" then NIL_VALUE
95
+ when "recycled" then RECYCLED
96
+ else raise TypeError, "invalid weak value state"
97
+ end
98
+ end
99
+
100
+ # @param value [Object] the object to be weakly referenced
101
+ def initialize(value)
102
+ if Ractor.shareable?(value)
103
+ @atom = Strict::WeakAtom.new(value)
104
+ @mutex = nil
105
+ else
106
+ @atom = Unshared::WeakAtom.new(value)
107
+ @mutex = Mutex.new
108
+ end
109
+ end
110
+
111
+ # Checks whether the referenced object has avoided garbage collection and has not been moved.
112
+ # @return [Boolean] true if the weak value is still alive, false otherwise
113
+ def alive?
114
+ !_value.nil?
115
+ rescue Ractor::MovedError
116
+ false
117
+ end
118
+
119
+ # Freezes the weak value, making the referenced object shareable if it is still alive.
120
+ # Can be called after the value has been garbage collected or moved.
121
+ # Will raise however if the referenced object is still alive and cannot be made shareable.
122
+ # @return [self] the frozen weak value
123
+ def freeze
124
+ @mutex&.synchronize do
125
+ return self if frozen?
126
+ value = begin
127
+ Ractor.make_shareable(_value)
128
+ rescue Ractor::MovedError
129
+ MOVED
130
+ end
131
+ @atom = Strict::WeakAtom.new(value)
132
+ @mutex = nil
133
+ end
134
+ super
135
+ end
136
+
137
+ # Checks if the referenced object has been moved to another Ractor.
138
+ # @return [Boolean] true if the referenced object has been moved, false otherwise
139
+ def moved?
140
+ Ractor::MovedObject === _value
141
+ rescue Ractor::MovedError
142
+ true
143
+ end
144
+
145
+ # @return [Boolean] true if the referenced object is shareable by Ractor, false otherwise
146
+ def ractor_shareable?
147
+ return false unless Ractor.shareable?(_value)
148
+ freeze && true
149
+ rescue Ractor::MovedError
150
+ freeze && true
151
+ end
152
+
153
+ # Retrieves the referenced object if it is still alive and has not been moved.
154
+ # Raises if it is no longer reachable.
155
+ # @return [BasicObject] the referenced object if it is still alive and has not been moved
156
+ # @raise [WeakRefError] if the referenced object is no longer reachable or has been moved
157
+ def value
158
+ value = _value
159
+ raise WeakRefError, "Invalid Reference - probably recycled" if value.nil?
160
+ value
161
+ rescue Ractor::MovedError
162
+ raise WeakRefError, "Invalid Reference - referenced object has been moved"
163
+ end
164
+
165
+ # @api private
166
+ def inspect_with(inspector)
167
+ state, value = state_and_value
168
+ super do
169
+ inspector.attribute(:state, state)
170
+ inspector.attribute(:value, value) if state == :alive
171
+ end
172
+ end
173
+
174
+ private
175
+
176
+ def initialize_clone(other, freeze: nil)
177
+ super
178
+ self.freeze if freeze == true
179
+ end
180
+
181
+ def _value
182
+ value = @atom.value
183
+ raise Ractor::MovedError, "referenced object has been moved" if MOVED.equal?(value)
184
+ value
185
+ end
186
+
187
+ def state_and_value
188
+ value = _value
189
+ return :recycled if value.nil?
190
+ [:alive, value]
191
+ rescue Ractor::MovedError
192
+ :moved
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # A Ractor-shareable concurrent map with strong shareable keys and weak values.
7
+ #
8
+ # Supported modes are `:raise` (the default), `:make_shareable`, and `:dedup`.
9
+ # Modes apply only to values. Keys must already be shareable.
10
+ # Entries disappear after a weakly held object is collected.
11
+ #
12
+ # With `:dedup`, retain the canonical result returned by store or update,
13
+ # as it might differ from the input and could be immediately collected.
14
+ # Assignment evaluates to the input rather than the canonical result.
15
+ #
16
+ # @example Publishing a value without retaining it strongly
17
+ # value = []
18
+ # map = Farce::WeakValueMap.new(mode: :make_shareable)
19
+ # map[:result] = value
20
+ # map[:result].equal?(value) # => true
21
+ class WeakValueMap < Farce::Abstract::WeakValueMap
22
+ include Internal::WeakMapValueModes
23
+ include Shareable::Delegated
24
+
25
+ private
26
+
27
+ def new_map(**) = Internal::StrictWeakValueMap.new(**)
28
+ def freeze_backend = @map
29
+ end
30
+
31
+ Internal::KeyNormalizer.prepare_concurrent_class(Internal::StrictWeakValueMap)
32
+ end