farce 0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/CODE_OF_CONDUCT.md +26 -0
  4. data/CONTRIBUTING.md +71 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +1525 -0
  7. data/SECURITY.md +10 -0
  8. data/docs/benchmarks.md +185 -0
  9. data/docs/gems/dry-types.md +290 -0
  10. data/docs/gems/msgpack.md +70 -0
  11. data/docs/gems/ractor-shim.md +63 -0
  12. data/docs/modes.md +628 -0
  13. data/docs/scopes.md +649 -0
  14. data/docs/variants.md +346 -0
  15. data/ext/ext_helper.rb +20 -0
  16. data/ext/farce/README.md +21 -0
  17. data/ext/farce/atom.c +1023 -0
  18. data/ext/farce/bounded_map.c +1683 -0
  19. data/ext/farce/containers.h +77 -0
  20. data/ext/farce/counter.c +399 -0
  21. data/ext/farce/darwin.c +100 -0
  22. data/ext/farce/depend +12 -0
  23. data/ext/farce/dict.c +1523 -0
  24. data/ext/farce/dict.h +152 -0
  25. data/ext/farce/drivers.c +237 -0
  26. data/ext/farce/exchanger.c +299 -0
  27. data/ext/farce/extconf.rb +99 -0
  28. data/ext/farce/farce.c +359 -0
  29. data/ext/farce/flag.c +288 -0
  30. data/ext/farce/io.c +338 -0
  31. data/ext/farce/lock.c +510 -0
  32. data/ext/farce/map.c +2240 -0
  33. data/ext/farce/priority_queue.c +2056 -0
  34. data/ext/farce/queue.c +1059 -0
  35. data/ext/farce/reactor.c +820 -0
  36. data/ext/farce/reactor.h +103 -0
  37. data/ext/farce/shareable.h +31 -0
  38. data/ext/farce/signal.c +350 -0
  39. data/ext/farce/transaction.c +354 -0
  40. data/ext/farce/transaction.h +40 -0
  41. data/ext/farce/tree_map.c +1953 -0
  42. data/ext/farce/trie.c +2020 -0
  43. data/ext/farce/unshareable.c +155 -0
  44. data/ext/farce/unshared_io_pool.h +234 -0
  45. data/ext/farce/unshared_signal.c +263 -0
  46. data/ext/farce/unshared_wait.h +193 -0
  47. data/ext/farce/unsupported.c +6 -0
  48. data/ext/farce/vector.c +1195 -0
  49. data/ext/farce/weak_map.c +1714 -0
  50. data/ext/java/org/farce/BoundedMap.java +394 -0
  51. data/ext/java/org/farce/FiberScheduler.java +141 -0
  52. data/ext/java/org/farce/PriorityKey.java +45 -0
  53. data/ext/java/org/farce/PriorityQueue.java +373 -0
  54. data/ext/java/org/farce/QueueSignal.java +28 -0
  55. data/ext/rebind/README.md +14 -0
  56. data/ext/rebind/extconf.rb +10 -0
  57. data/ext/rebind/rebind.c +186 -0
  58. data/lib/farce/_yard/internal.rb +13 -0
  59. data/lib/farce/_yard/macros.rb +61 -0
  60. data/lib/farce/_yard/ractor.rb +46 -0
  61. data/lib/farce/abstract/atom.rb +186 -0
  62. data/lib/farce/abstract/bounded_map.rb +232 -0
  63. data/lib/farce/abstract/collection.rb +151 -0
  64. data/lib/farce/abstract/concurrent_map.rb +381 -0
  65. data/lib/farce/abstract/counter.rb +193 -0
  66. data/lib/farce/abstract/duplicable_map.rb +229 -0
  67. data/lib/farce/abstract/exchanger.rb +26 -0
  68. data/lib/farce/abstract/flag.rb +71 -0
  69. data/lib/farce/abstract/lazy.rb +115 -0
  70. data/lib/farce/abstract/lease.rb +104 -0
  71. data/lib/farce/abstract/lease_map.rb +261 -0
  72. data/lib/farce/abstract/lease_pool.rb +91 -0
  73. data/lib/farce/abstract/lfu_map.rb +20 -0
  74. data/lib/farce/abstract/lru_map.rb +25 -0
  75. data/lib/farce/abstract/map.rb +345 -0
  76. data/lib/farce/abstract/molecule.rb +245 -0
  77. data/lib/farce/abstract/port.rb +74 -0
  78. data/lib/farce/abstract/priority_queue.rb +117 -0
  79. data/lib/farce/abstract/queue.rb +269 -0
  80. data/lib/farce/abstract/scheduler.rb +111 -0
  81. data/lib/farce/abstract/set.rb +910 -0
  82. data/lib/farce/abstract/sorted_set.rb +172 -0
  83. data/lib/farce/abstract/timer_queue.rb +136 -0
  84. data/lib/farce/abstract/tree_map.rb +269 -0
  85. data/lib/farce/abstract/value.rb +68 -0
  86. data/lib/farce/abstract/vector.rb +1126 -0
  87. data/lib/farce/abstract/weak_atom.rb +32 -0
  88. data/lib/farce/abstract/weak_key_map.rb +12 -0
  89. data/lib/farce/abstract/weak_map.rb +13 -0
  90. data/lib/farce/abstract/weak_set.rb +12 -0
  91. data/lib/farce/abstract/weak_value_map.rb +12 -0
  92. data/lib/farce/abstract.rb +17 -0
  93. data/lib/farce/atom.rb +293 -0
  94. data/lib/farce/class_mirror.rb +87 -0
  95. data/lib/farce/clock.rb +121 -0
  96. data/lib/farce/config.rb +229 -0
  97. data/lib/farce/counter.rb +71 -0
  98. data/lib/farce/deduper.rb +122 -0
  99. data/lib/farce/engine/jruby/bounded_map.rb +314 -0
  100. data/lib/farce/engine/jruby/fiber_scheduler.jar +0 -0
  101. data/lib/farce/engine/jruby/fiber_scheduler.rb +119 -0
  102. data/lib/farce/engine/jruby/lease_waiting.rb +19 -0
  103. data/lib/farce/engine/jruby/map.rb +505 -0
  104. data/lib/farce/engine/jruby/mutable_numeric_copy.rb +42 -0
  105. data/lib/farce/engine/jruby/signal.rb +147 -0
  106. data/lib/farce/engine/jruby.rb +63 -0
  107. data/lib/farce/engine/jvm/concurrent_weak_registry.rb +55 -0
  108. data/lib/farce/engine/jvm/counter.rb +102 -0
  109. data/lib/farce/engine/jvm/extension.rb +32 -0
  110. data/lib/farce/engine/jvm/farce.jar +0 -0
  111. data/lib/farce/engine/jvm/flag.rb +79 -0
  112. data/lib/farce/engine/jvm/priority_queue.rb +217 -0
  113. data/lib/farce/engine/jvm/tree_map.rb +350 -0
  114. data/lib/farce/engine/jvm/types.rb +180 -0
  115. data/lib/farce/engine/jvm.rb +19 -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/vault.rb +56 -0
  121. data/lib/farce/engine/ruby/4.0/port.rb +19 -0
  122. data/lib/farce/engine/ruby/4.0/ractor_methods.rb +20 -0
  123. data/lib/farce/engine/ruby/4.0/ractor_selector.rb +108 -0
  124. data/lib/farce/engine/ruby/4.0/vault.rb +74 -0
  125. data/lib/farce/engine/ruby/4.1/port.rb +21 -0
  126. data/lib/farce/engine/ruby/4.1/ractor_methods.rb +22 -0
  127. data/lib/farce/engine/ruby/4.1/ractor_selector.rb +25 -0
  128. data/lib/farce/engine/ruby/4.1/vault.rb +5 -0
  129. data/lib/farce/engine/ruby/fiber_scheduler.rb +32 -0
  130. data/lib/farce/engine/ruby/key_lock_map.rb +28 -0
  131. data/lib/farce/engine/ruby/shared/lease.rb +26 -0
  132. data/lib/farce/engine/ruby/shared/lease_pool.rb +24 -0
  133. data/lib/farce/engine/ruby/shared/main_scheduler.rb +9 -0
  134. data/lib/farce/engine/ruby/shared/parallel_scheduler.rb +9 -0
  135. data/lib/farce/engine/ruby/shared/proxy_owner.rb +31 -0
  136. data/lib/farce/engine/ruby/shared/ractor_methods.rb +34 -0
  137. data/lib/farce/engine/ruby/shared/ractor_selector.rb +328 -0
  138. data/lib/farce/engine/ruby/shared/strict_map.rb +13 -0
  139. data/lib/farce/engine/ruby/shared/unshared_vector.rb +14 -0
  140. data/lib/farce/engine/ruby/shared/vault.rb +144 -0
  141. data/lib/farce/engine/ruby/shared/vault_weak_map.rb +336 -0
  142. data/lib/farce/engine/ruby/shared/weak_atom.rb +54 -0
  143. data/lib/farce/engine/ruby/shared/weak_map.rb +413 -0
  144. data/lib/farce/engine/ruby.rb +130 -0
  145. data/lib/farce/engine/shared/atom.rb +10 -0
  146. data/lib/farce/engine/shared/exchanger.rb +130 -0
  147. data/lib/farce/engine/shared/identity_key.rb +22 -0
  148. data/lib/farce/engine/shared/lease.rb +10 -0
  149. data/lib/farce/engine/shared/lease_pool.rb +10 -0
  150. data/lib/farce/engine/shared/main_scheduler.rb +20 -0
  151. data/lib/farce/engine/shared/map_key_coordination.rb +226 -0
  152. data/lib/farce/engine/shared/parallel_scheduler.rb +9 -0
  153. data/lib/farce/engine/shared/port.rb +44 -0
  154. data/lib/farce/engine/shared/portable_bounded_map.rb +619 -0
  155. data/lib/farce/engine/shared/proxy_owner.rb +43 -0
  156. data/lib/farce/engine/shared/queue.rb +233 -0
  157. data/lib/farce/engine/shared/ractor_methods.rb +73 -0
  158. data/lib/farce/engine/shared/rebindable.rb +15 -0
  159. data/lib/farce/engine/shared/strict_atom.rb +73 -0
  160. data/lib/farce/engine/shared/strict_map.rb +117 -0
  161. data/lib/farce/engine/shared/strict_queue_values.rb +27 -0
  162. data/lib/farce/engine/shared/strict_tree_map.rb +56 -0
  163. data/lib/farce/engine/shared/transaction_map_backend.rb +20 -0
  164. data/lib/farce/engine/shared/trie.rb +317 -0
  165. data/lib/farce/engine/shared/trie_builder.rb +199 -0
  166. data/lib/farce/engine/shared/unshareable.rb +14 -0
  167. data/lib/farce/engine/shared/unshared_atom.rb +256 -0
  168. data/lib/farce/engine/shared/unshared_priority_queue.rb +9 -0
  169. data/lib/farce/engine/shared/unshared_queue.rb +18 -0
  170. data/lib/farce/engine/shared/unshared_signal.rb +21 -0
  171. data/lib/farce/engine/shared/unshared_vector.rb +377 -0
  172. data/lib/farce/engine/shared/unshared_weak_atom.rb +30 -0
  173. data/lib/farce/engine/shared/unshared_weak_map.rb +445 -0
  174. data/lib/farce/engine/shared/vault.rb +31 -0
  175. data/lib/farce/engine/shared/vector.rb +83 -0
  176. data/lib/farce/engine/shared/weak_atom/base.rb +189 -0
  177. data/lib/farce/engine/shared/weak_atom.rb +20 -0
  178. data/lib/farce/engine/shared/weak_map/cell.rb +99 -0
  179. data/lib/farce/engine/shared/weak_map/index.rb +249 -0
  180. data/lib/farce/engine/shared/weak_map/lock.rb +80 -0
  181. data/lib/farce/engine/shared/weak_map/reference.rb +33 -0
  182. data/lib/farce/engine/shared.rb +63 -0
  183. data/lib/farce/engine/truffleruby/fiber_scheduler.rb +13 -0
  184. data/lib/farce/engine/truffleruby/lock.rb +121 -0
  185. data/lib/farce/engine/truffleruby/map.rb +656 -0
  186. data/lib/farce/engine/truffleruby/native/counter.rb +105 -0
  187. data/lib/farce/engine/truffleruby/native/flag.rb +77 -0
  188. data/lib/farce/engine/truffleruby/native/ordered_array_support.rb +67 -0
  189. data/lib/farce/engine/truffleruby/native/priority_queue.rb +388 -0
  190. data/lib/farce/engine/truffleruby/native/tree_map.rb +51 -0
  191. data/lib/farce/engine/truffleruby/native/unsafe_tree_map.rb +350 -0
  192. data/lib/farce/engine/truffleruby/signal.rb +77 -0
  193. data/lib/farce/engine/truffleruby.rb +148 -0
  194. data/lib/farce/envelope.rb +335 -0
  195. data/lib/farce/error.rb +35 -0
  196. data/lib/farce/exchanger.rb +41 -0
  197. data/lib/farce/flag.rb +27 -0
  198. data/lib/farce/integrations/active_support/blank.rb +68 -0
  199. data/lib/farce/integrations/active_support/clock.rb +17 -0
  200. data/lib/farce/integrations/active_support/duplicable.rb +78 -0
  201. data/lib/farce/integrations/active_support/map.rb +175 -0
  202. data/lib/farce/integrations/active_support/set.rb +60 -0
  203. data/lib/farce/integrations/active_support/value_serialization.rb +17 -0
  204. data/lib/farce/integrations/active_support/vector.rb +231 -0
  205. data/lib/farce/integrations/active_support.rb +9 -0
  206. data/lib/farce/integrations/activesupport.rb +5 -0
  207. data/lib/farce/integrations/bson.rb +108 -0
  208. data/lib/farce/integrations/cbor.rb +51 -0
  209. data/lib/farce/integrations/concurrent.rb +112 -0
  210. data/lib/farce/integrations/dry-types.rb +5 -0
  211. data/lib/farce/integrations/dry_types.rb +694 -0
  212. data/lib/farce/integrations/json.rb +7 -0
  213. data/lib/farce/integrations/msgpack.rb +112 -0
  214. data/lib/farce/integrations/oj.rb +69 -0
  215. data/lib/farce/integrations/psych.rb +191 -0
  216. data/lib/farce/integrations/ractor-sharing.rb +5 -0
  217. data/lib/farce/integrations/ractor-tmvar.rb +5 -0
  218. data/lib/farce/integrations/ractor_sharing.rb +172 -0
  219. data/lib/farce/integrations/ractor_tmvar.rb +64 -0
  220. data/lib/farce/integrations/shared/to_json.rb +42 -0
  221. data/lib/farce/integrations/sorted_set.rb +11 -0
  222. data/lib/farce/integrations/weakref.rb +38 -0
  223. data/lib/farce/integrations/yajl.rb +10 -0
  224. data/lib/farce/integrations.rb +156 -0
  225. data/lib/farce/internal/_frozen_config.rb +11 -0
  226. data/lib/farce/internal/autoloads.rb +47 -0
  227. data/lib/farce/internal/blocking_priority_queue.rb +122 -0
  228. data/lib/farce/internal/converter.rb +106 -0
  229. data/lib/farce/internal/copyable.rb +31 -0
  230. data/lib/farce/internal/delegation.rb +20 -0
  231. data/lib/farce/internal/external_transaction.rb +59 -0
  232. data/lib/farce/internal/fake_ractor.rb +179 -0
  233. data/lib/farce/internal/freeze.rb +118 -0
  234. data/lib/farce/internal/inspect.rb +157 -0
  235. data/lib/farce/internal/key_lock_map.rb +29 -0
  236. data/lib/farce/internal/key_normalizer.rb +289 -0
  237. data/lib/farce/internal/lease_initialization.rb +115 -0
  238. data/lib/farce/internal/lease_map.rb +441 -0
  239. data/lib/farce/internal/lease_pool_state.rb +228 -0
  240. data/lib/farce/internal/lease_state.rb +342 -0
  241. data/lib/farce/internal/lease_waiting.rb +13 -0
  242. data/lib/farce/internal/managed_queue.rb +26 -0
  243. data/lib/farce/internal/map_value_modes.rb +227 -0
  244. data/lib/farce/internal/marshal_support.rb +227 -0
  245. data/lib/farce/internal/mixin.rb +20 -0
  246. data/lib/farce/internal/mutable_ordered_key_lock_map.rb +63 -0
  247. data/lib/farce/internal/noncopyable.rb +17 -0
  248. data/lib/farce/internal/ordered_key_lock_map.rb +69 -0
  249. data/lib/farce/internal/pool_supervisor.rb +41 -0
  250. data/lib/farce/internal/pool_worker.rb +61 -0
  251. data/lib/farce/internal/portable_transaction/reservation_entry.rb +29 -0
  252. data/lib/farce/internal/portable_transaction/strong_map_entry.rb +137 -0
  253. data/lib/farce/internal/portable_transaction/strong_map_size_entry.rb +44 -0
  254. data/lib/farce/internal/portable_transaction/tree_entry.rb +64 -0
  255. data/lib/farce/internal/portable_transaction.rb +164 -0
  256. data/lib/farce/internal/proxy_owner_notifications.rb +29 -0
  257. data/lib/farce/internal/reservation_waiting.rb +24 -0
  258. data/lib/farce/internal/scheduled_task.rb +48 -0
  259. data/lib/farce/internal/scheduler_io.rb +171 -0
  260. data/lib/farce/internal/scheduler_lifecycle.rb +314 -0
  261. data/lib/farce/internal/select_scheduler.rb +235 -0
  262. data/lib/farce/internal/storage.rb +162 -0
  263. data/lib/farce/internal/strict_lease.rb +30 -0
  264. data/lib/farce/internal/strict_lease_map.rb +20 -0
  265. data/lib/farce/internal/strict_lease_pool.rb +29 -0
  266. data/lib/farce/internal/thread_pool.rb +166 -0
  267. data/lib/farce/internal/transaction_conflict.rb +9 -0
  268. data/lib/farce/internal/transaction_freeze_guard.rb +30 -0
  269. data/lib/farce/internal/transaction_map_snapshot.rb +123 -0
  270. data/lib/farce/internal/undefined.rb +22 -0
  271. data/lib/farce/internal/unshared_lease.rb +29 -0
  272. data/lib/farce/internal/unshared_lease_pool.rb +34 -0
  273. data/lib/farce/internal/unshared_queue_waiting.rb +28 -0
  274. data/lib/farce/internal/value_serialization.rb +13 -0
  275. data/lib/farce/internal/weak_map_value_modes.rb +58 -0
  276. data/lib/farce/internal/weak_mode_manager.rb +26 -0
  277. data/lib/farce/internal.rb +129 -0
  278. data/lib/farce/lazy.rb +100 -0
  279. data/lib/farce/lazy_ref.rb +40 -0
  280. data/lib/farce/lease.rb +28 -0
  281. data/lib/farce/lease_map.rb +34 -0
  282. data/lib/farce/lease_pool.rb +29 -0
  283. data/lib/farce/lfu_map.rb +53 -0
  284. data/lib/farce/local/atom.rb +23 -0
  285. data/lib/farce/local/counter.rb +88 -0
  286. data/lib/farce/local/flag.rb +65 -0
  287. data/lib/farce/local/lazy.rb +38 -0
  288. data/lib/farce/local/lazy_ref.rb +36 -0
  289. data/lib/farce/local/lease.rb +77 -0
  290. data/lib/farce/local/lease_map.rb +80 -0
  291. data/lib/farce/local/lease_pool.rb +38 -0
  292. data/lib/farce/local/lfu_map.rb +55 -0
  293. data/lib/farce/local/lru_map.rb +62 -0
  294. data/lib/farce/local/map.rb +47 -0
  295. data/lib/farce/local/molecule.rb +45 -0
  296. data/lib/farce/local/priority_queue.rb +53 -0
  297. data/lib/farce/local/queue.rb +32 -0
  298. data/lib/farce/local/scoped.rb +166 -0
  299. data/lib/farce/local/set.rb +18 -0
  300. data/lib/farce/local/sorted_set.rb +50 -0
  301. data/lib/farce/local/timer_queue.rb +41 -0
  302. data/lib/farce/local/tree_map.rb +47 -0
  303. data/lib/farce/local/vector.rb +30 -0
  304. data/lib/farce/local/weak_atom.rb +23 -0
  305. data/lib/farce/local/weak_key_map.rb +39 -0
  306. data/lib/farce/local/weak_map.rb +39 -0
  307. data/lib/farce/local/weak_set.rb +18 -0
  308. data/lib/farce/local/weak_value_map.rb +39 -0
  309. data/lib/farce/local.rb +35 -0
  310. data/lib/farce/lock.rb +54 -0
  311. data/lib/farce/lru_map.rb +63 -0
  312. data/lib/farce/map.rb +58 -0
  313. data/lib/farce/mode_manager.rb +142 -0
  314. data/lib/farce/molecule.rb +60 -0
  315. data/lib/farce/mutable.rb +171 -0
  316. data/lib/farce/pool.rb +332 -0
  317. data/lib/farce/port.rb +134 -0
  318. data/lib/farce/priority_queue.rb +70 -0
  319. data/lib/farce/proxy/register.rb +101 -0
  320. data/lib/farce/proxy/supervisor.rb +137 -0
  321. data/lib/farce/proxy/wrapper.rb +49 -0
  322. data/lib/farce/proxy.rb +291 -0
  323. data/lib/farce/queue.rb +60 -0
  324. data/lib/farce/ractor.rb +269 -0
  325. data/lib/farce/read_write_lock.rb +256 -0
  326. data/lib/farce/reference.rb +158 -0
  327. data/lib/farce/resolv/dns.rb +42 -0
  328. data/lib/farce/resolv.rb +85 -0
  329. data/lib/farce/scheduler.rb +536 -0
  330. data/lib/farce/set.rb +39 -0
  331. data/lib/farce/shareable.rb +150 -0
  332. data/lib/farce/signal.rb +97 -0
  333. data/lib/farce/sorted_set.rb +36 -0
  334. data/lib/farce/strict/atom.rb +34 -0
  335. data/lib/farce/strict/counter.rb +10 -0
  336. data/lib/farce/strict/exchanger.rb +25 -0
  337. data/lib/farce/strict/flag.rb +10 -0
  338. data/lib/farce/strict/lazy.rb +26 -0
  339. data/lib/farce/strict/lazy_ref.rb +26 -0
  340. data/lib/farce/strict/lease.rb +27 -0
  341. data/lib/farce/strict/lease_map.rb +33 -0
  342. data/lib/farce/strict/lease_pool.rb +28 -0
  343. data/lib/farce/strict/lfu_map.rb +27 -0
  344. data/lib/farce/strict/lru_map.rb +28 -0
  345. data/lib/farce/strict/map.rb +54 -0
  346. data/lib/farce/strict/molecule.rb +16 -0
  347. data/lib/farce/strict/port.rb +40 -0
  348. data/lib/farce/strict/priority_queue.rb +20 -0
  349. data/lib/farce/strict/queue.rb +17 -0
  350. data/lib/farce/strict/set.rb +14 -0
  351. data/lib/farce/strict/sorted_set.rb +19 -0
  352. data/lib/farce/strict/timer_queue.rb +13 -0
  353. data/lib/farce/strict/tree_map.rb +27 -0
  354. data/lib/farce/strict/vector.rb +24 -0
  355. data/lib/farce/strict/weak_atom.rb +31 -0
  356. data/lib/farce/strict/weak_key_map.rb +49 -0
  357. data/lib/farce/strict/weak_map.rb +49 -0
  358. data/lib/farce/strict/weak_set.rb +14 -0
  359. data/lib/farce/strict/weak_value_map.rb +48 -0
  360. data/lib/farce/strict.rb +28 -0
  361. data/lib/farce/system.rb +40 -0
  362. data/lib/farce/thread_scheduler.rb +70 -0
  363. data/lib/farce/timer_queue.rb +66 -0
  364. data/lib/farce/transaction/atom.rb +73 -0
  365. data/lib/farce/transaction/map.rb +25 -0
  366. data/lib/farce/transaction/map_operations.rb +143 -0
  367. data/lib/farce/transaction/molecule.rb +90 -0
  368. data/lib/farce/transaction/mutable.rb +61 -0
  369. data/lib/farce/transaction/set.rb +17 -0
  370. data/lib/farce/transaction/set_operations.rb +48 -0
  371. data/lib/farce/transaction/sorted_set.rb +18 -0
  372. data/lib/farce/transaction/tree_map.rb +78 -0
  373. data/lib/farce/transaction/vector.rb +139 -0
  374. data/lib/farce/transaction/wrapper.rb +202 -0
  375. data/lib/farce/transaction.rb +343 -0
  376. data/lib/farce/tree_map.rb +56 -0
  377. data/lib/farce/unsafe/lfu_map.rb +36 -0
  378. data/lib/farce/unsafe/lru_map.rb +36 -0
  379. data/lib/farce/unsafe/tree_map.rb +21 -0
  380. data/lib/farce/unsafe.rb +29 -0
  381. data/lib/farce/unshareable.rb +67 -0
  382. data/lib/farce/unshared/atom.rb +24 -0
  383. data/lib/farce/unshared/counter.rb +10 -0
  384. data/lib/farce/unshared/flag.rb +10 -0
  385. data/lib/farce/unshared/lazy.rb +38 -0
  386. data/lib/farce/unshared/lazy_ref.rb +26 -0
  387. data/lib/farce/unshared/lease.rb +27 -0
  388. data/lib/farce/unshared/lease_map.rb +26 -0
  389. data/lib/farce/unshared/lease_pool.rb +25 -0
  390. data/lib/farce/unshared/lfu_map.rb +20 -0
  391. data/lib/farce/unshared/lru_map.rb +20 -0
  392. data/lib/farce/unshared/map.rb +49 -0
  393. data/lib/farce/unshared/molecule.rb +16 -0
  394. data/lib/farce/unshared/priority_queue.rb +16 -0
  395. data/lib/farce/unshared/queue.rb +27 -0
  396. data/lib/farce/unshared/set.rb +14 -0
  397. data/lib/farce/unshared/sorted_set.rb +28 -0
  398. data/lib/farce/unshared/timer_queue.rb +16 -0
  399. data/lib/farce/unshared/tree_map.rb +21 -0
  400. data/lib/farce/unshared/vector.rb +19 -0
  401. data/lib/farce/unshared/weak_atom.rb +31 -0
  402. data/lib/farce/unshared/weak_key_map.rb +44 -0
  403. data/lib/farce/unshared/weak_map.rb +44 -0
  404. data/lib/farce/unshared/weak_set.rb +14 -0
  405. data/lib/farce/unshared/weak_value_map.rb +43 -0
  406. data/lib/farce/unshared.rb +28 -0
  407. data/lib/farce/vector.rb +228 -0
  408. data/lib/farce/version.rb +8 -0
  409. data/lib/farce/walker/definitions.rb +186 -0
  410. data/lib/farce/walker/modification.rb +355 -0
  411. data/lib/farce/walker.rb +319 -0
  412. data/lib/farce/weak_atom.rb +121 -0
  413. data/lib/farce/weak_key_map.rb +31 -0
  414. data/lib/farce/weak_map.rb +33 -0
  415. data/lib/farce/weak_ref.rb +67 -0
  416. data/lib/farce/weak_set.rb +82 -0
  417. data/lib/farce/weak_value.rb +195 -0
  418. data/lib/farce/weak_value_map.rb +32 -0
  419. data/lib/farce.rb +519 -0
  420. metadata +435 -8
data/docs/variants.md ADDED
@@ -0,0 +1,346 @@
1
+ <!--
2
+ # @title Variants
3
+ -->
4
+
5
+ # Variants
6
+
7
+ Most Farce classes implement a set of variants as separate subclasses within module namespaces.
8
+
9
+ These namespaces and variants are:
10
+
11
+ * **Farce**: Data containers that support both shareable and unshareable content. Unshareable content is usually handled by implementing [mode support](modes.md). Keep in mind that this is also the top level namespace for Farce in general, so it contains other classes and modules not implementing variants (including the variant namespaces themselves).
12
+ * **Farce::Strict**: Variants that enforce strict sharing rules. Unshareable content will be rejected.
13
+ * **Farce::Local**: Variants that hold concrete, independent data for each [scope](scopes.md) (i.e., one copy per ractor, thread, etc). As no scope stretches across multiple ractors, these may contain unshareable content without issue.
14
+ * **Farce::Unshared**: Variants that explicitly allow unshareable content. These cannot be shared across multiple ractors.
15
+ * **Farce::Unsafe**: Variants that aren't shareable but moreover aren't guaranteed to be thread-safe either. They only exist if they give a significant performance or usability benefit despite these limitations.
16
+ * **Farce::Transaction**: Variants generated by transactions.
17
+
18
+ You can choose the variant based on your needs:
19
+
20
+ ```ruby
21
+ global_map = Farce::Map.new
22
+ local_map = Farce::Local::Map.new(scope: :thread)
23
+ ```
24
+
25
+ None of the namespaces define any instance methods, so they are safe to include:
26
+
27
+ ```ruby
28
+ class MyClass
29
+ include Farce::Strict
30
+
31
+ @register = Map.new
32
+ @cache = LRUMap.new
33
+ end
34
+ ```
35
+
36
+ ## Classes implementing Variants
37
+
38
+ <table>
39
+ <thead>
40
+ <tr>
41
+ <th></th>
42
+ <th width="120" align="center" style="text-align: center">Farce</th>
43
+ <th width="120" align="center" style="text-align: center">Strict</th>
44
+ <th width="120" align="center" style="text-align: center">Local</th>
45
+ <th width="120" align="center" style="text-align: center">Unshared</th>
46
+ <th width="120" align="center" style="text-align: center">Unsafe</th>
47
+ <th width="120" align="center" style="text-align: center">Transaction</th>
48
+ </tr>
49
+ </thead>
50
+ <tbody>
51
+ <tr>
52
+ <td><tt>Atom</tt></td>
53
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
54
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
55
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
56
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
57
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
58
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
59
+ </tr>
60
+ <tr>
61
+ <td><tt>Counter</tt></td>
62
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
63
+ <td align="center" style="text-align: center">🔗</td> <!-- Strict -->
64
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
65
+ <td align="center" style="text-align: center">🔗</td> <!-- Unshared -->
66
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
67
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
68
+ </tr>
69
+ <tr>
70
+ <td><tt>Exchanger</tt></td>
71
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
72
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
73
+ <td align="center" style="text-align: center">➖</td> <!-- Local -->
74
+ <td align="center" style="text-align: center">➖</td> <!-- Unshared -->
75
+ <td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
76
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
77
+ </tr>
78
+ <tr>
79
+ <td><tt>Flag</tt></td>
80
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
81
+ <td align="center" style="text-align: center">🔗</td> <!-- Strict -->
82
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
83
+ <td align="center" style="text-align: center">🔗</td> <!-- Unshared -->
84
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
85
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
86
+ </tr>
87
+ <tr>
88
+ <td><tt>Lazy</tt></td>
89
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
90
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
91
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
92
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
93
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
94
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
95
+ </tr>
96
+ <tr>
97
+ <td><tt>LazyRef</tt></td>
98
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
99
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
100
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
101
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
102
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
103
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
104
+ </tr>
105
+ <tr>
106
+ <td><tt>Lease</tt></td>
107
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
108
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
109
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
110
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
111
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
112
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
113
+ </tr>
114
+ <tr>
115
+ <td><tt>LeaseMap</tt></td>
116
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
117
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
118
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
119
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
120
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
121
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
122
+ </tr>
123
+ <tr>
124
+ <td><tt>LeasePool</tt></td>
125
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
126
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
127
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
128
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
129
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
130
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
131
+ </tr>
132
+ <tr>
133
+ <td><tt>LFUMap</tt></td>
134
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
135
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
136
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
137
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
138
+ <td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
139
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
140
+ </tr>
141
+ <tr>
142
+ <td><tt>LRUMap</tt></td>
143
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
144
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
145
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
146
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
147
+ <td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
148
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
149
+ </tr>
150
+ <tr>
151
+ <td><tt>Molecule</tt></td>
152
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
153
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
154
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
155
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
156
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
157
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
158
+ </tr>
159
+ <tr>
160
+ <td><tt>Map</tt></td>
161
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
162
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
163
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
164
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
165
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
166
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
167
+ </tr>
168
+ <tr>
169
+ <td><tt>Mutable</tt></td>
170
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
171
+ <td align="center" style="text-align: center">➖</td> <!-- Strict -->
172
+ <td align="center" style="text-align: center">➖</td> <!-- Local -->
173
+ <td align="center" style="text-align: center">➖</td> <!-- Unshared -->
174
+ <td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
175
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
176
+ </tr>
177
+ <tr>
178
+ <td><tt>Port</tt></td>
179
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
180
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
181
+ <td align="center" style="text-align: center">➖</td> <!-- Local -->
182
+ <td align="center" style="text-align: center">➖</td> <!-- Unshared -->
183
+ <td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
184
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
185
+ </tr>
186
+ <tr>
187
+ <td><tt>PriorityQueue</tt></td>
188
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
189
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
190
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
191
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
192
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
193
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
194
+ </tr>
195
+ <tr>
196
+ <td><tt>Queue</tt></td>
197
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
198
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
199
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
200
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
201
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
202
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
203
+ </tr>
204
+ <tr>
205
+ <td><tt>Set</tt></td>
206
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
207
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
208
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
209
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
210
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
211
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
212
+ </tr>
213
+ <tr>
214
+ <td><tt>SortedSet</tt></td>
215
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
216
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
217
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
218
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
219
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
220
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
221
+ </tr>
222
+ <tr>
223
+ <td><tt>TimerQueue</tt></td>
224
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
225
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
226
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
227
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
228
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
229
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
230
+ </tr>
231
+ <tr>
232
+ <td><tt>TreeMap</tt></td>
233
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
234
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
235
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
236
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
237
+ <td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
238
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
239
+ </tr>
240
+ <tr>
241
+ <td><tt>Vector</tt></td>
242
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
243
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
244
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
245
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
246
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
247
+ <td align="center" style="text-align: center">✅</td> <!-- Transaction -->
248
+ </tr>
249
+ <tr>
250
+ <td><tt>WeakAtom</tt></td>
251
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
252
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
253
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
254
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
255
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
256
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
257
+ </tr>
258
+ <tr>
259
+ <td><tt>WeakKeyMap</tt></td>
260
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
261
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
262
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
263
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
264
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
265
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
266
+ </tr>
267
+ <tr>
268
+ <td><tt>WeakMap</tt></td>
269
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
270
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
271
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
272
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
273
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
274
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
275
+ </tr>
276
+ <tr>
277
+ <td><tt>WeakSet</tt></td>
278
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
279
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
280
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
281
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
282
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
283
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
284
+ </tr>
285
+ <tr>
286
+ <td><tt>WeakValueMap</tt></td>
287
+ <td align="center" style="text-align: center">✅</td> <!-- Farce -->
288
+ <td align="center" style="text-align: center">✅</td> <!-- Strict -->
289
+ <td align="center" style="text-align: center">✅</td> <!-- Local -->
290
+ <td align="center" style="text-align: center">✅</td> <!-- Unshared -->
291
+ <td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
292
+ <td align="center" style="text-align: center">➖</td> <!-- Transaction -->
293
+ </tr>
294
+ </tbody>
295
+ </table>
296
+
297
+ Legend:
298
+ * ✅ Defined
299
+ * ➖ Not defined
300
+ * 🔗 Alias for another variant
301
+
302
+ ## Classes without Variants
303
+
304
+ When using the variant namespaces interchangeably, keep in mind that some classes do not come with variants.
305
+
306
+ This is obvious for classes that aren't data containers, like `Signal` or `Lock`, but also include classes like `Envelope` and `Scheduler`, which support modes, and `WeakValue` and `WeakRef`, which will choose (and switch) between the correct `WeakAtom` variants automatically.
307
+
308
+ ## Abstract Classes and Modules
309
+
310
+ Classes with variants will typically have at least one abstract class or module that they implement.
311
+ This is helpful for type checking and as a possible extension point, while doing a better job at substitution.
312
+
313
+ For example, `Farce::Map` subclasses should all implement mode support, but the same cannot be said for all `Farce::Abstract::Map` subclasses.
314
+
315
+ This makes type checking easy:
316
+
317
+ ```ruby
318
+ def self.increment_counter(counter)
319
+ case counter
320
+ when Farce::Abstract::Counter then counter.increment
321
+ when Ratomic::Counter then counter.increment(1) # required argument
322
+ else raise "Unsupported counter type"
323
+ end
324
+ end
325
+
326
+ counter = Farce::Counter.new
327
+ increment_counter(counter)
328
+
329
+ counter = Farce::Local::Counter.new(scope: :fiber)
330
+ increment_counter(counter)
331
+ ```
332
+
333
+ Abstract classes may in turn have abstract subclasses to group functionality. For instance, all `PriorityQueue` variants inherit from `Farce::Abstract::PriorityQueue`, which in turn is a subclass of `Farce::Abstract::Queue`.
334
+
335
+ A noticeably more complex abstract hierarchy exists for maps:
336
+
337
+ * `Farce::Abstract::Map`: Superclass for all map variants. Contains the almost complete set of Hash-compatible methods, as well as some additional methods like `store_if_absent`.
338
+ * `Farce::Abstract::ConcurrentMap`: Superclass for maps with an extended concurrency API, including `Farce::Map` and its variants.
339
+ * `Farce::Abstract::WeakMap`: Superclass for all `WeakMap` variants.
340
+ * `Farce::Abstract::WeakKeyMap`: Superclass for all `WeakKeyMap` variants.
341
+ * `Farce::Abstract::WeakValueMap`: Superclass for all `WeakValueMap` variants.
342
+ * `Farce::Abstract::BoundedMap`: Superclass for all map variants with an enforced size limit. All current variants enforce this limit via eviction, but a subclass rejecting writes could be a valid implementation.
343
+ * `Farce::Abstract::LFUMap`: Superclass for all Least Frequently Used (LFU) map variants.
344
+ * `Farce::Abstract::LRUMap`: Superclass for all Least Recently Used (LRU) map variants.
345
+ * `Farce::Abstract::LeaseMap`: Superclass for all `LeaseMap` variants.
346
+ * `Farce::Abstract::TreeMap`: Superclass for all `TreeMap` variants.
data/ext/ext_helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExtHelper
4
+ extend self
5
+
6
+ def ext_path(ext_name = nil, engine: RUBY_ENGINE, version: RUBY_ENGINE_VERSION, lib: false)
7
+ # Build explicitly because Ruby 4 freezes interpolated literals under
8
+ # `frozen_string_literal`, while this path is assembled incrementally.
9
+ dir = String.new
10
+ dir << "lib/" if lib
11
+ dir << "farce/engine/" << engine
12
+
13
+ case engine
14
+ when "ruby" then dir << "/#{version[/^\d+\.\d+/]}"
15
+ when "truffleruby" then dir << "/#{TruffleRuby.native? ? "native" : "graalvm"}/#{version}"
16
+ end
17
+ dir << "/#{File.basename(ext_name)}" if ext_name
18
+ dir.freeze
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # Native extension
2
+
3
+ Farce's CRuby extension defines its internal coordinated containers, including `Atom`, `Counter`, `Exchanger`, `Flag`, `Lock`, `Map`, `Queue`, `Signal`, `Vector`, `UnsafeTreeMap`, `TreeMap`, `ShareableTreeMap`, and `PriorityQueue`. CRuby 4.1+ also gets native `WeakAtom`, `WeakMap`, `WeakKeyMap`, and `WeakValueMap` implementations.
4
+
5
+ On platforms with epoll or kqueue, the same extension also provides Farce's native fiber scheduler. The scheduler class is initialized lazily so selecting the Ruby `select` implementation does not load or expose the native scheduler.
6
+
7
+ The tree maps use a red-black tree. String keys are normalized like `-key`, producing frozen, globally deduplicated keys that
8
+ can be recovered with `getkey`. Other keys must already be Ractor-shareable. `UnsafeTreeMap` is unsynchronized, while `TreeMap` is synchronized. Both accept arbitrary values and follow ordinary Ruby freeze semantics. `ShareableTreeMap` is synchronized, requires shareable values, and is itself frozen and Ractor-shareable.
9
+
10
+ `PriorityQueue` uses the vendored Kazlib dictionary implementation with one FIFO bucket per priority (this is the same implementation used by the rbtree gem). Exact deletion visits only the requested priority's bucket. Kazlib's copyright and license remain in `dict.c` and `dict.h`.
11
+
12
+ `Queue` uses a bounded or growing FIFO ring. Its `try_push` and `try_pop` entry points share the checked operation bodies with `push` and `pop`, while avoiding keyword allocation and clock reads for polling. Vacated slots are cleared, and the GC hooks visit only the live portion of the ring.
13
+
14
+ The extension is built and loaded only on CRuby. Other engines use their Ruby or JVM implementations and never compile this directory.
15
+
16
+ This extension is intentionally kept separate from the `rebind` extension, as the other extension is tightly bound to CRuby internals and may have to be adjusted for each new Ruby version.
17
+
18
+
19
+ ## AI Usage
20
+
21
+ OpenAI's Astra has been used to explore and fix bugs in this extensions, primarily for implementing Windows support, as well as for performance and high contention testing. All generated code has been reviewed extensively if it ended up being used in the final implementation.