farce 0.0.1.alpha2-x86-linux-musl

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,29 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # Module holding classes with instances which are not thread-safe and cannot be shared between Ractors.
7
+ module Unsafe
8
+ include Unshared
9
+ include Internal::Autoloads
10
+
11
+ # @overload enfarce(object, freeze: nil)
12
+ # Converts vanilla Ruby objects into their {Farce::Unsafe} equivalents.
13
+ #
14
+ # @example
15
+ # Farce::Unsafe.enfarce({ foo: ["bar"] })
16
+ # # => #<Farce::Unsafe::Map {foo: #<Farce::Unsafe::Vector ["bar"]>}>
17
+ #
18
+ # @yield [object] Optional block, called with any object that doesn't have a specific conversion defined.
19
+ # @yieldparam object [BasicObject] the object to convert
20
+ # @yieldreturn [BasicObject] the converted object
21
+ # @param object [BasicObject] The root object to convert
22
+ # @param freeze [Boolean, nil]
23
+ # Whether to freeze the converted objects.
24
+ # If set to `nil` (default), the freezing behavior will depend on the original object's frozen state.
25
+ # @return [BasicObject] the converted object
26
+ # @see Farce.enfarce
27
+ def self.enfarce(object, **, &) = Internal::Converter.new(self, **, &).convert(object)
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # Mixin that makes sure instances cannot be shared between Ractors.
7
+ # @note Mixin in this module will remove the `freeze` method from the class.
8
+ #
9
+ # @example
10
+ # class MyClass
11
+ # include Farce::Unshareable
12
+ # end
13
+ #
14
+ # object = MyClass.new
15
+ # object.freeze # this would normally make it shareable
16
+ #
17
+ # Ractor.shareable?(object) # => false
18
+ module Unshareable
19
+ # @api private
20
+ module UndefFreeze # :nodoc: all
21
+ # @api private
22
+ def append_features(mod)
23
+ super
24
+ if mod.is_a?(Class)
25
+ mod.class_eval { undef freeze if method_defined?(:freeze) }
26
+ else
27
+ mod.extend(UndefFreeze)
28
+ end
29
+ end
30
+ end
31
+
32
+ private_constant :UndefFreeze
33
+ extend UndefFreeze
34
+
35
+ # Mixin for classes that cannot be shared across Ractors, but may be moved between them.
36
+ module Movable
37
+ include Unshareable
38
+ end
39
+
40
+ # Mixin for classes that cannot be shared across Ractors, but may be copied between them.
41
+ module Copyable
42
+ include Unshareable
43
+ end
44
+
45
+ # Make sure to call `super` if you include this module.
46
+ # Accepts any arguments and passes them on to the superclass initializer.
47
+ def initialize(...)
48
+ pin_unshareable
49
+ super
50
+ end
51
+
52
+ # @return [Boolean] false
53
+ # @see Shareable#ractor_shareable?
54
+ def ractor_shareable? = false
55
+
56
+ private
57
+
58
+ def pin_unshareable
59
+ return unless Internal.native_ractors?
60
+ case self
61
+ when Movable then Internal::Unshareable.prevent_copyable(self) unless is_a?(Copyable)
62
+ when Copyable then Internal::Unshareable.prevent_movable(self)
63
+ else Internal::Unshareable.pin_to_current_ractor(self)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe atomic reference that retains values directly within one Ractor.
8
+ # Mutable values keep their identity. Updates are serialized between threads.
9
+ #
10
+ # @example Updating an array atomically
11
+ # atom = Farce::Unshared::Atom.new([])
12
+ # atom.update { |items| items + [:job] }
13
+ class Atom < Abstract::Atom
14
+ include Unshareable
15
+
16
+ # @param value [BasicObject, nil] the initial value
17
+ # @param compare_by_identity [Boolean] whether comparisons use object identity
18
+ def initialize(value = nil, compare_by_identity: false)
19
+ @atom = Internal::UnsharedAtom.new(value, compare_by_identity:)
20
+ super()
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # Alias for {Farce::Counter} so {Unshared} can be more easily used as a namespace.
8
+ Counter = Farce::Counter
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # Alias for {Farce::Flag} so {Unshared} can be more easily used as a namespace.
8
+ Flag = Farce::Flag
9
+ end
10
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe lazy value within one Ractor.
8
+ # Its factory may capture mutable state. The result retains its identity.
9
+ # Factory failures can be retried on the next access.
10
+ #
11
+ # @example Build a mutable cache on first access
12
+ # lazy = Farce::Unshared::Lazy.new { {} }
13
+ # lazy.value[:job] = :ready
14
+ #
15
+ # @!parse
16
+ # class Lazy < Abstract::Lazy
17
+ # # Without `self:`, the block keeps its original receiver.
18
+ # # @overload initialize(factory)
19
+ # # @param factory [Class, Proc, #call] the factory, which may retain mutable state
20
+ # # @overload initialize(self: nil)
21
+ # # @param self [BasicObject] the receiver to bind to the block
22
+ # # @yield computes the value on first access, preserving captured state
23
+ # # @yieldreturn [BasicObject] the cached result
24
+ # def initialize(...) = nil
25
+ # end
26
+ class Lazy < Abstract::Lazy
27
+ include Unshareable
28
+
29
+ private
30
+
31
+ def new_internal_atom = Internal::UnsharedAtom.new
32
+
33
+ def prepare_proc(factory, **options)
34
+ options.empty? ? factory : Farce.rebind(factory, **options)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # @!parse
8
+ # # A {Reference} for a {Unshared::Lazy} value.
9
+ # # Delegates to the result after computing it on first access.
10
+ # # Calling `freeze` resolves and freezes the target.
11
+ # #
12
+ # # @example
13
+ # # reference = Farce::Unshared::LazyRef.new { [] }
14
+ # # reference.push(:ready) # => [:ready]
15
+ # class LazyRef < Farce::Reference
16
+ # # @overload initialize(factory)
17
+ # # @param factory [Class, Proc, #call] the factory for the lazy value
18
+ # # @overload initialize(self: nil)
19
+ # # @param self [BasicObject] the receiver to bind to the block
20
+ # # @yield computes the value on first access
21
+ # # @yieldreturn [BasicObject] the computed result
22
+ # def initialize(...) = nil
23
+ # end
24
+ LazyRef = Reference[Farce::Unshared::Lazy]
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe lease that passes one resource directly within a Ractor.
8
+ #
9
+ # @example Updating one object from multiple threads
10
+ # lease = Farce::Unshared::Lease.new { { count: 0 } }
11
+ # workers = 3.times.map do
12
+ # Thread.new do
13
+ # lease.checkout { |state| state[:count] += 1 }
14
+ # end
15
+ # end
16
+ # workers.each(&:join)
17
+ #
18
+ # lease.checkout { |state| state[:count] } # => 3
19
+ class Lease < Abstract::Lease
20
+ include Unshareable
21
+
22
+ private
23
+
24
+ def new_internal_lease(resource) = Internal::UnsharedLease.new(resource)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe map that passes independently leased resources within one Ractor.
8
+ #
9
+ # @example Coordinating mutable resources between threads
10
+ # leases = Farce::Unshared::LeaseMap.new { { jobs: [] } }
11
+ # workers = 2.times.map do
12
+ # Thread.new { leases.checkout(:jobs) { |jobs| jobs << :finished } }
13
+ # end
14
+ # workers.each(&:join)
15
+ # leases.checkout(:jobs, &:length) # => 2
16
+ class LeaseMap < Abstract::LeaseMap
17
+ include Unshareable
18
+
19
+ private
20
+
21
+ def new_internal_lease_map(mapping)
22
+ Internal::LeaseMap.new(mapping, lease_class: Farce::Unshared::Lease, registry_class: Farce::Unshared::Map)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe pool that passes resource references within one Ractor.
8
+ #
9
+ # @example Reusing objects from multiple threads
10
+ # pool = Farce::Unshared::LeasePool.new(max_size: 1) { { uses: 0 } }
11
+ # workers = 2.times.map do
12
+ # Thread.new { pool.checkout { |state| state[:uses] += 1 } }
13
+ # end
14
+ # workers.each(&:join)
15
+ #
16
+ # pool.checkout { |state| state[:uses] } # => 2
17
+ class LeasePool < Abstract::LeasePool
18
+ include Unshareable
19
+
20
+ private
21
+
22
+ def new_internal_pool(max_size) = Internal::UnsharedLeasePool.new(max_size)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe LFU map for mutable keys and values used within one Ractor.
8
+ class LFUMap < Abstract::LFUMap
9
+ include Unshareable
10
+
11
+ private
12
+
13
+ def new_bounded_map(...) = Internal::LFUMap.new(...)
14
+
15
+ def new_key_locks(compare_keys_by_identity:)
16
+ Internal::KeyLockMap.new(registry_class: Farce::Unshared::Map, compare_keys_by_identity:)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe LRU map for mutable keys and values used within one Ractor.
8
+ class LRUMap < Abstract::LRUMap
9
+ include Unshareable
10
+
11
+ private
12
+
13
+ def new_bounded_map(...) = Internal::LRUMap.new(...)
14
+
15
+ def new_key_locks(compare_keys_by_identity:)
16
+ Internal::KeyLockMap.new(registry_class: Farce::Unshared::Map, compare_keys_by_identity:)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe concurrent map for mutable objects used within one Ractor.
8
+ # Updates on different keys can run concurrently.
9
+ #
10
+ # Clearing the map invalidates unfinished updates so they cannot restore removed entries.
11
+ #
12
+ # `dup` and `clone` copy entries into independent storage while sharing stored values.
13
+ class Map < Abstract::ConcurrentMap
14
+ include Unshareable
15
+
16
+ # @!macro map_initialization
17
+ #
18
+ # @example Atomically updating a mutable value
19
+ # counters = Farce::Unshared::Map.new({ jobs: [] })
20
+ # counters.update(:jobs) { |jobs| jobs << :finished }
21
+ # counters[:jobs] # => [:finished]
22
+ #
23
+ def initialize(
24
+ initial_mapping = nil,
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
+ initial_mapping = convert_entries(initial_mapping)
31
+ restoring = Internal::KeyNormalizer.restoration?(normalize_keys)
32
+ normalizer = Internal::KeyNormalizer.build(normalize_keys, shareable: false)
33
+ populate = initial_mapping && ((normalizer && !restoring) || !initial_mapping.is_a?(Hash))
34
+ @map = Internal::UnsharedMap.new(
35
+ populate ? nil : initial_mapping,
36
+ compare_by_identity:,
37
+ compare_keys_by_identity:,
38
+ compare_values_by_identity:,
39
+ )
40
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) unless restoring
41
+ initial_mapping.each { |key, value| self[key] = value } if populate
42
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) if restoring
43
+ super()
44
+ end
45
+
46
+ Internal.prepare_map_access(self, :unshared)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe record whose atoms retain values directly within one Ractor.
8
+ # Use {Abstract::Molecule.define} to declare named fields.
9
+ # Explicitly supplied atoms keep their own storage and comparison policies.
10
+ class Molecule < Abstract::Molecule
11
+ include Unshareable
12
+
13
+ private def create_atom(_, value) = Atom.new(value, compare_by_identity: compare_by_identity?)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A priority queue that stores and returns values directly.
8
+ class PriorityQueue < Abstract::PriorityQueue
9
+ include Unshareable
10
+ include Internal::UnsharedQueueWaiting
11
+
12
+ # @return [Symbol] always returns :local
13
+ def mode = :local
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A FIFO queue that stores and returns values directly.
8
+ class Queue < Abstract::Queue
9
+ include Unshareable
10
+
11
+ # @overload initialize(capacity: 1024, track_age: false)
12
+ # (see Farce::Abstract::Queue#initialize)
13
+ def initialize(capacity: 1024, fiber_wait: :auto, track_age: false)
14
+ @queue = Internal::UnsharedQueue.new(capacity:, fiber_wait:, track_age:)
15
+ super()
16
+ end
17
+
18
+ # (see Farce::Abstract::Queue#mode)
19
+ # @return [Symbol] always returns :local
20
+ def mode = :local
21
+
22
+ # The resolved fiber waiting strategy. Other Ruby engines may return :auto.
23
+ # @api private
24
+ def fiber_wait = @queue.fiber_wait
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe set for mutable elements used within one Ractor.
8
+ class Set < Farce::Abstract::Set
9
+ include Unshareable
10
+
11
+ private def new_map(...) = Farce::Unshared::Map.new(...)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe set maintained in ascending order within one Ractor.
8
+ class SortedSet < Farce::Abstract::SortedSet
9
+ include Unshareable
10
+
11
+ class MutableTreeMap < Farce::Unshared::TreeMap # :nodoc:
12
+ private
13
+
14
+ def prepare_key(key) = key
15
+ def new_key_locks = Internal::MutableOrderedKeyLockMap.new
16
+ def new_tree_map(...) = Internal::MutableTreeMap.new(...)
17
+ end
18
+ private_constant :MutableTreeMap
19
+
20
+ private
21
+
22
+ def new_map(entries = nil, compare_keys_by_identity: false, **)
23
+ raise ArgumentError, "sorted sets do not support identity comparison" if compare_keys_by_identity
24
+ MutableTreeMap.new(entries)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A timer queue that stores and returns values directly.
8
+ class TimerQueue < Abstract::TimerQueue
9
+ include Unshareable
10
+ include Internal::UnsharedQueueWaiting
11
+
12
+ # @return [Symbol] always returns :local
13
+ def mode = :local
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe map that keeps entries sorted by key within one Ractor.
8
+ # Mutable string keys become immutable. Values are stored directly and may be mutable.
9
+ #
10
+ # @example Keeping mutable values in key order
11
+ # value = []
12
+ # map = Farce::Unshared::TreeMap.new(2 => value, 1 => [])
13
+ #
14
+ # map[2].equal?(value) # => true
15
+ class TreeMap < Abstract::TreeMap
16
+ include Unshareable
17
+
18
+ private def new_tree_map(...) = Internal::TreeMap.new(...)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe vector for mutable values used within one Ractor.
8
+ class Vector < Abstract::Vector
9
+ include Unshareable
10
+
11
+ # @param source [Array, nil] Initial values. Values are retained directly.
12
+ # @param compare_by_identity [Boolean] Whether values are compared by identity.
13
+ def initialize(source = nil, compare_by_identity: false)
14
+ @vector = Internal::UnsharedVector.new(source, compare_by_identity:)
15
+ super()
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe weak atomic reference for values used within one Ractor.
8
+ #
9
+ # @example Referencing a mutable object within one Ractor
10
+ # items = []
11
+ # atom = Farce::Unshared::WeakAtom.new(items)
12
+ # atom.value.equal?(items) # => true
13
+ # items << :job
14
+ # atom.value # => [:job]
15
+ #
16
+ # items = nil
17
+ # # Once the array is collected, atom.value returns nil.
18
+ #
19
+ # @example Atomically replacing the referenced object
20
+ # original = []
21
+ # replacement = [:job]
22
+ # atom = Farce::Unshared::WeakAtom.new(original, compare_by_identity: true)
23
+ # atom.compare_and_set(original, replacement) # => true
24
+ # atom.value.equal?(replacement) # => true
25
+ class WeakAtom < Abstract::WeakAtom
26
+ include Unshareable
27
+
28
+ private def internal_atom_class = Internal::UnsharedWeakAtom
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe map with weak keys for use within one Ractor.
8
+ #
9
+ # @example Associating data with a mutable object
10
+ # owner = Object.new
11
+ # map = Farce::Unshared::WeakKeyMap.new
12
+ # map[owner] = []
13
+ # map[owner] << :job
14
+ #
15
+ # # The entry can disappear once its key is collected.
16
+ # owner = nil
17
+ class WeakKeyMap < Abstract::WeakKeyMap
18
+ include Unshareable
19
+
20
+ def initialize(
21
+ initial_mapping = nil,
22
+ normalize_keys: nil,
23
+ compare_by_identity: false,
24
+ compare_keys_by_identity: compare_by_identity,
25
+ compare_values_by_identity: compare_by_identity
26
+ )
27
+ initial_mapping = convert_entries(initial_mapping)
28
+ restoring = Internal::KeyNormalizer.restoration?(normalize_keys)
29
+ normalizer = Internal::KeyNormalizer.build(normalize_keys, shareable: false)
30
+ populate = initial_mapping && ((normalizer && !restoring) || !initial_mapping.is_a?(Hash))
31
+ @map = Internal::UnsharedWeakKeyMap.new(
32
+ populate ? nil : initial_mapping,
33
+ compare_by_identity:,
34
+ compare_keys_by_identity:,
35
+ compare_values_by_identity:,
36
+ )
37
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) unless restoring
38
+ initial_mapping.each { |key, value| self[key] = value } if populate
39
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) if restoring
40
+ super()
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ module Unshared
7
+ # A thread-safe map with weak keys and values for use within one Ractor.
8
+ #
9
+ # @example Keeping a relationship while both mutable objects remain alive
10
+ # key = Object.new
11
+ # value = Object.new
12
+ # map = Farce::Unshared::WeakMap.new({ key => value })
13
+ # map[key].equal?(value) # => true
14
+ #
15
+ # # The entry can disappear once its key or value is collected
16
+ # value = nil
17
+ class WeakMap < Abstract::WeakMap
18
+ include Unshareable
19
+
20
+ def initialize(
21
+ initial_mapping = nil,
22
+ normalize_keys: nil,
23
+ compare_by_identity: false,
24
+ compare_keys_by_identity: compare_by_identity,
25
+ compare_values_by_identity: compare_by_identity
26
+ )
27
+ initial_mapping = convert_entries(initial_mapping)
28
+ restoring = Internal::KeyNormalizer.restoration?(normalize_keys)
29
+ normalizer = Internal::KeyNormalizer.build(normalize_keys, shareable: false)
30
+ populate = initial_mapping && ((normalizer && !restoring) || !initial_mapping.is_a?(Hash))
31
+ @map = Internal::UnsharedWeakMap.new(
32
+ populate ? nil : initial_mapping,
33
+ compare_by_identity:,
34
+ compare_keys_by_identity:,
35
+ compare_values_by_identity:,
36
+ )
37
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) unless restoring
38
+ initial_mapping.each { |key, value| self[key] = value } if populate
39
+ Internal::KeyNormalizer.install_concurrent(self, normalizer) if restoring
40
+ super()
41
+ end
42
+ end
43
+ end
44
+ end