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,233 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ class Queue
9
+ include Freeze::Unfreezable
10
+
11
+ NIL_VALUE = Object.new.freeze
12
+ attr_reader :capacity
13
+
14
+ def initialize(capacity: 1024, track_age: false)
15
+ @queue = capacity ? Thread::SizedQueue.new(capacity) : Thread::Queue.new
16
+ @capacity = capacity
17
+ @signal = Signal.new
18
+ @tracking = track_age ? { lock: Mutex.new, timestamps: [], generation: 0 } : nil
19
+ @lifecycle = { lock: Mutex.new, hard_closed: false }
20
+ Freeze.publish(self)
21
+ end
22
+
23
+ def pop(timeout: nil)
24
+ timeout_at = timeout_at(timeout)
25
+ # Observing an empty queue is sufficient for a nonblocking miss. Avoid
26
+ # constructing a ThreadError (and its backtrace) just to return nil.
27
+ if timeout_at&.zero? && @queue.empty?
28
+ raise_closed if closed?
29
+ return block_given? ? yield : nil
30
+ end
31
+
32
+ while true
33
+ begin
34
+ result = tracked_pop
35
+ raise ThreadError if nil.equal?(result) && @queue.closed?
36
+ broadcast
37
+ return NIL_VALUE.equal?(result) ? nil : result
38
+ rescue ThreadError
39
+ remaining = remaining_timeout(timeout_at)
40
+ return block_given? ? yield : nil unless wait_pop(timeout: remaining)
41
+ end
42
+ end
43
+ end
44
+
45
+ def push(item, timeout: nil)
46
+ check_value(item)
47
+ item = NIL_VALUE if nil.equal?(item)
48
+
49
+ unless capacity
50
+ tracked_push(item)
51
+ broadcast
52
+ return true
53
+ end
54
+
55
+ timeout_at = timeout_at(timeout)
56
+ if timeout_at&.zero? && @queue.size >= @queue.max
57
+ raise_unwritable if sealed?
58
+ return false
59
+ end
60
+ while true
61
+ begin
62
+ tracked_push(item, non_block: true)
63
+ broadcast
64
+ return true
65
+ rescue ThreadError
66
+ return false unless wait_push(timeout: remaining_timeout(timeout_at))
67
+ end
68
+ end
69
+ end
70
+
71
+ def wait_pop(timeout: nil) = wait(timeout) { size.positive? }
72
+
73
+ def try_pop(&) = pop(timeout: 0, &)
74
+
75
+ def try_push(item) = push(item, timeout: 0)
76
+
77
+ def wait_push(timeout: nil)
78
+ raise_unwritable if sealed?
79
+ return true unless capacity
80
+ wait(timeout) do
81
+ raise_unwritable if sealed?
82
+ size < capacity
83
+ end
84
+ end
85
+
86
+ def close
87
+ @lifecycle[:lock].synchronize do
88
+ changed = !@lifecycle[:hard_closed]
89
+ @lifecycle[:hard_closed] = true
90
+ @queue.close
91
+ bump_generation if changed
92
+ end
93
+ broadcast
94
+ self
95
+ end
96
+
97
+ def seal
98
+ @lifecycle[:lock].synchronize do
99
+ changed = !@queue.closed?
100
+ @queue.close
101
+ bump_generation if changed
102
+ end
103
+ broadcast
104
+ self
105
+ end
106
+
107
+ def clear
108
+ if @tracking
109
+ @tracking[:lock].synchronize do
110
+ changed = @queue.size.positive?
111
+ @queue.clear
112
+ @tracking[:timestamps].clear
113
+ @tracking[:generation] += 1 if changed
114
+ end
115
+ else
116
+ @queue.clear
117
+ end
118
+ broadcast
119
+ self
120
+ end
121
+
122
+ def num_waiting = @queue.num_waiting + @signal.num_waiting
123
+
124
+ Internal.delegate(self, :@queue, :size)
125
+
126
+ def sealed? = @queue.closed?
127
+
128
+ def closed?
129
+ @lifecycle[:hard_closed] || (@queue.closed? && @queue.empty?)
130
+ end
131
+
132
+ def age_tracking? = !@tracking.nil?
133
+ def generation = @tracking && @tracking[:lock].synchronize { @tracking[:generation] }
134
+
135
+ def oldest_enqueued_at
136
+ @tracking && @tracking[:lock].synchronize { @tracking[:timestamps].first }
137
+ end
138
+
139
+ def oldest_age
140
+ timestamp = oldest_enqueued_at
141
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - timestamp if timestamp
142
+ end
143
+
144
+ private
145
+
146
+ def check_value(item)
147
+ raise Ractor::IsolationError, "value is not Ractor-shareable" unless Ractor.shareable?(item)
148
+ end
149
+
150
+ def tracked_push(item, non_block: false)
151
+ if @tracking
152
+ @tracking[:lock].synchronize do
153
+ result = non_block ? @queue.push(item, true) : @queue.push(item)
154
+ @tracking[:timestamps] << Process.clock_gettime(Process::CLOCK_MONOTONIC)
155
+ @tracking[:generation] += 1
156
+ result
157
+ end
158
+ else
159
+ non_block ? @queue.push(item, true) : @queue.push(item)
160
+ end
161
+ rescue ::ClosedQueueError
162
+ raise_unwritable
163
+ end
164
+
165
+ def tracked_pop
166
+ return @queue.pop(true) unless @tracking
167
+ @tracking[:lock].synchronize do
168
+ result = @queue.pop(true)
169
+ unless nil.equal?(result) && @queue.closed?
170
+ @tracking[:timestamps].shift
171
+ @tracking[:generation] += 1
172
+ end
173
+ result
174
+ end
175
+ end
176
+
177
+ def bump_generation
178
+ @tracking[:lock].synchronize { @tracking[:generation] += 1 } if @tracking
179
+ end
180
+
181
+ def normalize_timeout(timeout)
182
+ return nil if timeout.nil?
183
+ timeout = Float(timeout)
184
+ raise ArgumentError, "timeout must be non-negative" if timeout.negative?
185
+ raise ArgumentError, "timeout must be finite" unless timeout.finite?
186
+ raise ArgumentError, "timeout must be a number" if timeout.nan?
187
+ timeout
188
+ end
189
+
190
+ def wait(timeout)
191
+ timeout_at = timeout_at(timeout)
192
+
193
+ if timeout_at&.zero?
194
+ return true if yield
195
+ raise_closed if closed?
196
+ return false
197
+ end
198
+
199
+ while true
200
+ generation = @signal.generation
201
+ return true if yield
202
+ raise_closed if closed?
203
+ return false unless @signal.wait(generation, timeout: remaining_timeout(timeout_at))
204
+ end
205
+ end
206
+
207
+ def raise_closed
208
+ raise ::Farce::ClosedQueueError, "queue is closed"
209
+ end
210
+
211
+ def raise_unwritable
212
+ closed = closed?
213
+ error = closed ? ::Farce::ClosedQueueError : ::Farce::SealedQueueError
214
+ raise error, closed ? "queue is closed" : "queue is sealed"
215
+ end
216
+
217
+ def timeout_at(timeout)
218
+ return if timeout.nil?
219
+ timeout = normalize_timeout(timeout)
220
+ timeout.zero? ? 0 : Clock.timeout(timeout)
221
+ end
222
+
223
+ def remaining_timeout(timeout_at)
224
+ return unless timeout_at
225
+ return 0 if timeout_at.zero?
226
+ timeout = timeout_at - Clock.now
227
+ timeout.positive? ? timeout : 0
228
+ end
229
+
230
+ def broadcast = @signal.broadcast
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ module RactorMethods
9
+ STORAGE = Storage::ThreadSafe.new
10
+ STORAGES = Storage::ThreadSafe.new
11
+
12
+ def with_storage(key)
13
+ key = key.to_s if key.is_a?(Symbol)
14
+ raise TypeError, "#{key.inspect} is not a symbol nor a string" unless key.is_a?(String)
15
+ storage = Ractor.main? ? STORAGE : STORAGES.store_if_absent(Ractor.current) { Storage::ThreadSafe.new }
16
+ yield(storage, key)
17
+ end
18
+
19
+ def new(...)
20
+ return super if is_a?(Class)
21
+ FakeRactor::NotMain.new(...)
22
+ end
23
+
24
+ def current = FakeRactor.current
25
+ def main = FakeRactor::Main::INSTANCE
26
+
27
+ def main?
28
+ return true if Internal.autoload?(:FakeRactor)
29
+ FakeRactor.current.main?
30
+ end
31
+
32
+ def count
33
+ return 1 if Internal.autoload?(:FakeRactor)
34
+ FakeRactor::GROUPS.size + 1
35
+ end
36
+
37
+ def [](name) = with_storage(name) { _1[_2] }
38
+ def builtin? = false
39
+ def main_thread = FakeRactor.main_thread
40
+ def make_shareable(object, **) = object
41
+ def receive(...) = Ractor.current.receive(...)
42
+
43
+ def shareable?(object)
44
+ unless Kernel === object
45
+ begin
46
+ return object.__send__(:ractor_shareable?)
47
+ rescue NoMethodError => e
48
+ raise unless e.name == :ractor_shareable?
49
+ return true
50
+ end
51
+ end
52
+
53
+ object.respond_to?(:ractor_shareable?) ? object.ractor_shareable? : true
54
+ end
55
+
56
+ def shareable_lambda(**, &) = Farce.rebind(lambda: true, **, &)
57
+ def shareable_proc(**, &) = Farce.rebind(**, &)
58
+ def shim? = true
59
+ def store_if_absent(name, &) = with_storage(name) { _1.store_if_absent(_2, &) }
60
+ def threads = FakeRactor.threads
61
+
62
+ def []=(name, value)
63
+ with_storage(name) { _1[_2] = value }
64
+ end
65
+
66
+ def select(...)
67
+ raise "TODO: not implemented"
68
+ end
69
+
70
+ alias recv receive
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ # @api private
9
+ # Rebindable implementation shared between JRuby and TruffleRuby engine support.
10
+ def rebindable?(proc)
11
+ return false unless proc.is_a?(Proc)
12
+ proc.inspect !~ /^#<Proc:0x[0-9a-f]+\(&:.*\) \(lambda\)>$/
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ # Preserve the unrestricted Atom backend for unshared internals.
9
+ class StrictAtom < Atom
10
+ def initialize(value = nil, **)
11
+ super(check_value(value), **)
12
+ end
13
+
14
+ def store(value, **, &)
15
+ check_frozen!
16
+ super(check_value(value), **, &)
17
+ end
18
+
19
+ def swap(value, **, &)
20
+ check_frozen!
21
+ super(check_value(value), **, &)
22
+ end
23
+
24
+ def wait_until_changed(expected, **, &) = super(check_value(expected), **, &)
25
+
26
+ def value=(value)
27
+ store(value)
28
+ end
29
+
30
+ def compare_and_set(expected, value, **)
31
+ check_frozen!
32
+ super(check_value(expected), check_value(value), **)
33
+ end
34
+
35
+ def store_if_absent(**)
36
+ raise LocalJumpError, "no block given" unless block_given?
37
+ check_frozen!
38
+ super do
39
+ value = yield
40
+ check_frozen!
41
+ check_value(value)
42
+ end
43
+ end
44
+
45
+ def update(**)
46
+ raise LocalJumpError, "no block given" unless block_given?
47
+ check_frozen!
48
+ super do |value|
49
+ replacement = yield(value)
50
+ check_frozen!
51
+ check_value(replacement)
52
+ end
53
+ end
54
+
55
+ def upsert(initial, **)
56
+ raise LocalJumpError, "no block given" unless block_given?
57
+ check_frozen!
58
+ super(check_value(initial), **) do |value|
59
+ replacement = yield(value)
60
+ check_frozen!
61
+ check_value(replacement)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def check_value(value)
68
+ return value if Ractor.shareable?(value)
69
+ raise Ractor::IsolationError, "value must be Ractor-shareable"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ module StrictMapValues
9
+ def self.included(base)
10
+ base.class_eval do
11
+ alias_method :assignment_prepared, :[]=
12
+ alias_method :get_prepared, :get
13
+ alias_method :store_prepared, :store
14
+ alias_method :swap_prepared, :swap
15
+ alias_method :update_prepared, :update
16
+ alias_method :wait_until_changed_prepared, :wait_until_changed
17
+ end
18
+ super
19
+ end
20
+
21
+ def initialize(initial_mapping = nil, **)
22
+ raise TypeError, "initial mapping must be a Hash" unless initial_mapping.nil? || initial_mapping.is_a?(Hash)
23
+ initial_mapping&.each { |key, value| check_pair(key, value) }
24
+ super
25
+ end
26
+
27
+ def [](key) = super(check_key(key))
28
+
29
+ def []=(key, value)
30
+ key = check_key(key)
31
+ super(key, check_value(value))
32
+ end
33
+
34
+ def get(key, **) = super(check_key(key), **)
35
+
36
+ def store(key, value, **)
37
+ key = check_key(key)
38
+ super(key, check_value(value), **)
39
+ end
40
+
41
+ def swap(key, value, **)
42
+ key = check_key(key)
43
+ super(key, check_value(value), **)
44
+ end
45
+
46
+ def key?(key) = super(check_key(key))
47
+ def delete(key) = super(check_key(key))
48
+ def getkey(key) = super(check_key(key))
49
+ def wait_until_non_nil(key, **) = super(check_key(key), **)
50
+
51
+ def fetch(*arguments, &)
52
+ arguments[0] = check_key(arguments.first) unless arguments.empty?
53
+ super
54
+ end
55
+
56
+ def store_if_absent(key, **)
57
+ raise LocalJumpError, "no block given" unless block_given?
58
+ super(check_key(key), **) { check_value(yield) }
59
+ end
60
+
61
+ def compare_and_set(key, expected, replacement, **)
62
+ super(check_key(key), check_value(expected), check_value(replacement), **)
63
+ end
64
+
65
+ def update(key, **)
66
+ raise LocalJumpError, "no block given" unless block_given?
67
+ super(check_key(key), **) { |value| check_value(yield(value)) }
68
+ end
69
+
70
+ def upsert(key, initial, **)
71
+ raise LocalJumpError, "no block given" unless block_given?
72
+ super(check_key(key), check_value(initial), **) { |value| check_value(yield(value)) }
73
+ end
74
+
75
+ def wait_until_changed(key, expected, **)
76
+ super(check_key(key), check_value(expected), **)
77
+ end
78
+
79
+ def normalize_external_key(key) = check_key(key)
80
+
81
+ private
82
+
83
+ def check_pair(key, value)
84
+ check_key(key)
85
+ check_value(value)
86
+ end
87
+
88
+ def check_key(key)
89
+ key = String.instance_method(:-@).bind_call(key) if String === key && !key.frozen? && !compare_keys_by_identity?
90
+ return key if Ractor.shareable?(key)
91
+ raise Ractor::IsolationError, "key must be Ractor-shareable"
92
+ end
93
+
94
+ def check_value(value)
95
+ return value if Ractor.shareable?(value)
96
+ raise Ractor::IsolationError, "value must be Ractor-shareable"
97
+ end
98
+ end
99
+ private_constant :StrictMapValues
100
+
101
+ class StrictMap < Map
102
+ include StrictMapValues
103
+ end
104
+
105
+ class StrictWeakKeyMap < WeakKeyMap
106
+ include StrictMapValues
107
+ end
108
+
109
+ class StrictWeakValueMap < WeakValueMap
110
+ include StrictMapValues
111
+ end
112
+
113
+ class StrictWeakMap < WeakMap
114
+ include StrictMapValues
115
+ end
116
+ end
117
+ 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 Internal # :nodoc: all
7
+ module StrictQueueValues
8
+ def push(value, *arguments, **options)
9
+ check_queue_value(value)
10
+ check_queue_value(options[:priority]) if options.key?(:priority)
11
+ super
12
+ end
13
+
14
+ def try_push(value, **options, &)
15
+ check_queue_value(value)
16
+ check_queue_value(options[:priority]) if options.key?(:priority)
17
+ super
18
+ end
19
+
20
+ private
21
+
22
+ def check_queue_value(value)
23
+ raise Ractor::IsolationError, "value is not Ractor-shareable" unless Ractor.shareable?(value)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ module Farce
6
+ # @!visibility private
7
+ module Internal # :nodoc: all
8
+ module StrictTreeMapValues
9
+ def initialize(entries = nil)
10
+ unless entries.nil? || entries.is_a?(Hash)
11
+ entries = entries.to_hash if entries.respond_to?(:to_hash)
12
+ raise TypeError, "entries must be a Hash or respond to #to_hash" unless entries.is_a?(Hash)
13
+ end
14
+ entries&.each { |key, value| check_tree_pair(key, value) }
15
+ super
16
+ end
17
+
18
+ def [](key) = super(check_tree_key(key))
19
+
20
+ def []=(key, value)
21
+ super(check_tree_key(key), check_tree_value(value))
22
+ end
23
+
24
+ def delete(key) = super(check_tree_key(key))
25
+ def getkey(key) = super(check_tree_key(key))
26
+ def key?(key) = super(check_tree_key(key))
27
+
28
+ def fetch(*arguments, &)
29
+ check_tree_key(arguments.first) unless arguments.empty?
30
+ super
31
+ end
32
+
33
+ private
34
+
35
+ def check_tree_pair(key, value)
36
+ check_tree_key(key)
37
+ check_tree_value(value)
38
+ end
39
+
40
+ def check_tree_key(key)
41
+ return key if String === key || Ractor.shareable?(key)
42
+ raise Ractor::IsolationError, "key must be Ractor-shareable"
43
+ end
44
+
45
+ def check_tree_value(value)
46
+ return value if Ractor.shareable?(value)
47
+ raise Ractor::IsolationError, "value must be Ractor-shareable"
48
+ end
49
+ end
50
+ private_constant :StrictTreeMapValues
51
+
52
+ class StrictTreeMap < ShareableTreeMap
53
+ include StrictTreeMapValues
54
+ end
55
+ end
56
+ 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 Internal # :nodoc: all
7
+ # Transaction hooks for the JRuby and TruffleRuby map backends.
8
+ module TransactionMapBackend
9
+ def transaction_snapshot = PortableTransaction.snapshot(self, :map)
10
+ def transaction_size_snapshot(size) = PortableTransaction::MapSizeEntry.new(self, size)
11
+ def transaction_pairs = entries_snapshot
12
+
13
+ # Whether no native operations, key reservations, or clear are active.
14
+ # Commit calls this with the reservation and state mutexes already held.
15
+ def transaction_idle?
16
+ !@active_owner_fiber && !@active_owners && !@clearing_reservations && @reservations.empty?
17
+ end
18
+ end
19
+ end
20
+ end