farce 0.0.1.alpha2-x86-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,350 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/truffleruby/native/ordered_array_support"
6
+
7
+ module Farce
8
+ # @!visibility private
9
+ module Internal # :nodoc: all
10
+ # Unsynchronized ordered map for callers that provide their own ownership.
11
+ # Entries live in one sorted Array and are located by binary search.
12
+ class UnsafeTreeMap
13
+ include TruffleOrderedArraySupport
14
+
15
+ INITIALIZATION_LOCK = Mutex.new
16
+ private_constant :INITIALIZATION_LOCK
17
+
18
+ Entry = Struct.new(:key, :value)
19
+ private_constant :Entry
20
+
21
+ class State
22
+ attr_accessor :operation_owner, :revision
23
+ attr_reader :entries, :lock
24
+
25
+ def initialize(lock:)
26
+ @entries = []
27
+ @lock = lock
28
+ @operation_owner = nil
29
+ @revision = 0
30
+ end
31
+ end
32
+ private_constant :State
33
+
34
+ def initialize(entries = nil)
35
+ ensure_initializable!
36
+ entries = normalize_entries(entries)
37
+ prepared = State.new(lock: operation_lock)
38
+ entries&.each { |key, value| stage_store(prepared, key, value) }
39
+ commit_initialization(prepared)
40
+ end
41
+
42
+ def initialize_copy(_other)
43
+ raise TypeError, "tree maps cannot be copied"
44
+ end
45
+
46
+ def freeze
47
+ state = @freeze_state
48
+ return primitive_freeze(self) unless synchronized? && state
49
+
50
+ state.set
51
+ self
52
+ end
53
+
54
+ def frozen?
55
+ state = @freeze_state
56
+ synchronized? && state ? state.value : primitive_frozen?(self)
57
+ end
58
+
59
+ def prepare_key(key) = canonical_ordered_key(key)
60
+
61
+ def [](key)
62
+ key = canonical_ordered_key(key)
63
+ state = initialized_state
64
+ with_map_operation(state, mutation: false) do
65
+ index, found = locate_key(state.entries, key)
66
+ state.entries[index].value if found
67
+ end
68
+ end
69
+
70
+ def fetch(*arguments)
71
+ unless arguments.length.between?(1, 2)
72
+ raise ArgumentError, "wrong number of arguments (given #{arguments.length}, expected 1..2)"
73
+ end
74
+
75
+ original_key, default = arguments
76
+ key = canonical_ordered_key(original_key)
77
+ default_given = arguments.length == 2
78
+ warn "block supersedes default value argument", uplevel: 1 if block_given? && default_given
79
+ state = initialized_state
80
+ entry = with_map_operation(state, mutation: false) do
81
+ index, found = locate_key(state.entries, key)
82
+ state.entries[index] if found
83
+ end
84
+ return entry.value if entry
85
+ return yield(original_key) if block_given?
86
+ return default if default_given
87
+
88
+ raise KeyError.new(
89
+ "key not found: #{original_key.inspect}",
90
+ receiver: self,
91
+ key: original_key,
92
+ )
93
+ end
94
+
95
+ def key?(key)
96
+ key = canonical_ordered_key(key)
97
+ state = initialized_state
98
+ with_map_operation(state, mutation: false) do
99
+ _, found = locate_key(state.entries, key)
100
+ found
101
+ end
102
+ end
103
+
104
+ def getkey(key)
105
+ key = canonical_ordered_key(key)
106
+ state = initialized_state
107
+ with_map_operation(state, mutation: false) do
108
+ index, found = locate_key(state.entries, key)
109
+ state.entries[index].key if found
110
+ end
111
+ end
112
+
113
+ def each
114
+ return enum_for(__method__) { size } unless block_given?
115
+
116
+ state = initialized_state
117
+ entries = with_map_operation(state, mutation: false) do
118
+ state.entries.map { [it.key, it.value] }
119
+ end
120
+ entries.each { yield it }
121
+ self
122
+ end
123
+
124
+ def each_live
125
+ return enum_for(__method__) { size } unless block_given?
126
+
127
+ state = initialized_state
128
+ index = 0
129
+ last_key = nil
130
+ revision = nil
131
+ started = false
132
+
133
+ loop do
134
+ pair = with_map_operation(state, mutation: false) do
135
+ if started && revision != state.revision
136
+ index, found = locate_key(state.entries, last_key)
137
+ index += 1 if found
138
+ end
139
+ entry = state.entries[index]
140
+ next unless entry
141
+
142
+ index += 1
143
+ last_key = entry.key
144
+ revision = state.revision
145
+ [entry.key, entry.value]
146
+ end
147
+ break unless pair
148
+ started = true
149
+ yield pair
150
+ end
151
+ self
152
+ end
153
+
154
+ def []=(key, value)
155
+ key = canonical_ordered_key(key)
156
+ state = initialized_state
157
+ with_map_operation(state, mutation: true) do
158
+ index, found = locate_key(state.entries, key)
159
+ if found
160
+ ensure_mutation_still_allowed!
161
+ without_async_interrupts do
162
+ state.entries[index].value = value
163
+ state.revision += 1
164
+ end
165
+ else
166
+ pending = Entry.new(key, value)
167
+ without_async_interrupts do
168
+ index, duplicate = with_interruptible_callbacks do
169
+ locate_key(state.entries, key)
170
+ end
171
+ raise "key comparator changed during insertion" if duplicate
172
+ ensure_mutation_still_allowed!
173
+ state.entries.insert(index, pending)
174
+ state.revision += 1
175
+ end
176
+ end
177
+ value
178
+ end
179
+ end
180
+
181
+ def delete(key)
182
+ key = canonical_ordered_key(key)
183
+ state = initialized_state
184
+ with_map_operation(state, mutation: true) do
185
+ index, found = locate_key(state.entries, key)
186
+ next unless found
187
+
188
+ ensure_mutation_still_allowed!
189
+ without_async_interrupts do
190
+ state.revision += 1
191
+ state.entries.delete_at(index).value
192
+ end
193
+ end
194
+ end
195
+
196
+ def first_key
197
+ state = initialized_state
198
+ with_map_operation(state, mutation: false) { state.entries.first&.key }
199
+ end
200
+
201
+ def last_key
202
+ state = initialized_state
203
+ with_map_operation(state, mutation: false) { state.entries.last&.key }
204
+ end
205
+
206
+ def shift
207
+ state = initialized_state
208
+ with_map_operation(state, mutation: true) do
209
+ entry = state.entries.first
210
+ next unless entry
211
+
212
+ pair = [entry.key, entry.value]
213
+ without_async_interrupts do
214
+ state.entries.shift
215
+ state.revision += 1
216
+ end
217
+ pair
218
+ end
219
+ end
220
+
221
+ def pop
222
+ state = initialized_state
223
+ with_map_operation(state, mutation: true) do
224
+ entry = state.entries.last
225
+ next unless entry
226
+
227
+ pair = [entry.key, entry.value]
228
+ without_async_interrupts do
229
+ state.entries.pop
230
+ state.revision += 1
231
+ end
232
+ pair
233
+ end
234
+ end
235
+
236
+ def size
237
+ state = initialized_state
238
+ with_map_operation(state, mutation: false) { state.entries.length }
239
+ end
240
+ alias length size
241
+
242
+ def empty?
243
+ state = initialized_state
244
+ with_map_operation(state, mutation: false) { state.entries.empty? }
245
+ end
246
+
247
+ def clear
248
+ state = initialized_state
249
+ with_map_operation(state, mutation: true) do
250
+ without_async_interrupts do
251
+ unless state.entries.empty?
252
+ state.entries.clear
253
+ state.revision += 1
254
+ end
255
+ end
256
+ self
257
+ end
258
+ end
259
+
260
+ private
261
+
262
+ def synchronized? = false
263
+ def operation_lock = nil
264
+
265
+ def with_map_operation(state, mutation:)
266
+ ensure_mutation_still_allowed! if mutation
267
+ current = Fiber.current
268
+ raise "container cannot be modified during comparison" if state.operation_owner
269
+
270
+ begin
271
+ without_async_interrupts { state.operation_owner = current }
272
+ yield
273
+ ensure
274
+ without_async_interrupts { state.operation_owner = nil }
275
+ end
276
+ end
277
+
278
+ def ensure_mutation_still_allowed!
279
+ raise FrozenError, "can't modify frozen tree map" if primitive_frozen?(self)
280
+ end
281
+
282
+ def ensure_initializable!
283
+ raise "tree map is already initialized" if @state
284
+ raise FrozenError, "can't modify frozen tree map" if primitive_frozen?(self)
285
+ end
286
+
287
+ def commit_initialization(prepared)
288
+ INITIALIZATION_LOCK.synchronize do
289
+ raise "tree map is already initialized" if @state
290
+ raise FrozenError, "can't modify frozen tree map" if primitive_frozen?(self)
291
+
292
+ without_async_interrupts do
293
+ @state = prepared
294
+ @freeze_state = Flag.new(false) if synchronized?
295
+ primitive_freeze(self) if synchronized?
296
+ end
297
+ end
298
+ self
299
+ end
300
+
301
+ def initialized_state
302
+ @state || raise("uninitialized tree map")
303
+ end
304
+
305
+ def normalize_entries(entries)
306
+ return if entries.nil?
307
+ entries = Hash.try_convert(entries)
308
+ return entries if entries
309
+ raise TypeError, "entries must be a Hash or respond to #to_hash"
310
+ end
311
+
312
+ def stage_store(state, key, value)
313
+ key = canonical_ordered_key(key)
314
+ index, found = locate_key(state.entries, key)
315
+ if found
316
+ ensure_initializable!
317
+ state.entries[index].value = value
318
+ return
319
+ end
320
+
321
+ pending = Entry.new(key, value)
322
+ index, duplicate = locate_key(state.entries, key)
323
+ raise "key comparator changed during insertion" if duplicate
324
+ ensure_initializable!
325
+ state.entries.insert(index, pending)
326
+ end
327
+
328
+ def locate_key(entries, key)
329
+ low = 0
330
+ high = entries.length
331
+ while low < high
332
+ middle = (low + high) / 2
333
+ order = compare_keys(key, entries[middle].key)
334
+ return [middle, true] if order.zero?
335
+ order.negative? ? high = middle : low = middle + 1
336
+ end
337
+ [low, false]
338
+ end
339
+
340
+ def compare_keys(left, right)
341
+ result = left <=> right
342
+ raise ArgumentError, "key comparison failed" if result.nil?
343
+ # rb_cmpint calls #> and #< when <=> returns a non-Integer object.
344
+ return 1 if result > 0 # rubocop:disable Style/NumericPredicate
345
+ return -1 if result < 0 # rubocop:disable Style/NumericPredicate
346
+ 0
347
+ end
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,77 @@
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 Signal
9
+ include Freeze::Unfreezable
10
+
11
+ TIMED_OUT = Object.new.freeze
12
+ private_constant :TIMED_OUT
13
+
14
+ def initialize
15
+ @generation = TruffleRuby::AtomicReference.new(0)
16
+ @num_waiting = TruffleRuby::AtomicReference.new(0)
17
+ @condition = ConditionVariable.new
18
+ @broadcast_lock = Mutex.new
19
+ Freeze.publish(self)
20
+ end
21
+
22
+ def generation = @generation.get
23
+ def num_waiting = @num_waiting.get
24
+
25
+ def broadcast
26
+ @broadcast_lock.synchronize do
27
+ generation = @generation.get + 1
28
+ @generation.set(generation)
29
+ @condition.broadcast
30
+ generation
31
+ end
32
+ end
33
+
34
+ def wait(observed = nil, timeout: nil, &fallback)
35
+ validate_generation(observed) unless observed.nil?
36
+ deadline = timeout_deadline(timeout)
37
+
38
+ result = @broadcast_lock.synchronize do
39
+ observed ||= generation
40
+ waiting = false
41
+ begin
42
+ loop do
43
+ current = generation
44
+ break current unless current == observed
45
+
46
+ remaining = deadline - Clock.now if deadline
47
+ break TIMED_OUT if remaining && !remaining.positive?
48
+ @num_waiting.set(@num_waiting.get + 1) unless waiting
49
+ waiting = true
50
+ @condition.wait(@broadcast_lock, remaining)
51
+ end
52
+ ensure
53
+ @num_waiting.set(@num_waiting.get - 1) if waiting
54
+ end
55
+ end
56
+
57
+ TIMED_OUT.equal?(result) ? fallback&.call : result
58
+ end
59
+
60
+ private
61
+
62
+ def validate_generation(generation)
63
+ raise TypeError, "generation must be an Integer" unless generation.is_a?(::Integer)
64
+ end
65
+
66
+ def timeout_deadline(timeout)
67
+ return if timeout.nil?
68
+
69
+ timeout = Float(timeout)
70
+ if !timeout.finite? || timeout.negative?
71
+ raise ArgumentError, "timeout must be a finite, non-negative number or nil"
72
+ end
73
+ Clock.now + timeout
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/shared"
6
+
7
+ # Concurrent lexical lookup can expose this module before its methods are defined.
8
+ # Load it before reservation or lease waits can first run on competing threads.
9
+ require "farce/internal/lease_waiting"
10
+
11
+ require "farce/engine/jvm" unless TruffleRuby.native?
12
+
13
+ module Farce
14
+ # @!visibility private
15
+ module Internal # :nodoc: all
16
+ include Autoloads["#{__dir__}/truffleruby"]
17
+
18
+ require "farce/engine/shared/portable_bounded_map"
19
+
20
+ autoload :WeakMap, "farce/engine/shared/unshared_weak_map"
21
+ autoload :WeakKeyMap, "farce/engine/shared/unshared_weak_map"
22
+ autoload :WeakValueMap, "farce/engine/shared/unshared_weak_map"
23
+
24
+ LFUMap = PortableLFUMap
25
+ LRUMap = PortableLRUMap
26
+ ShareableLFUMap = StrictLFUMap = PortableStrictLFUMap
27
+ ShareableLRUMap = StrictLRUMap = PortableStrictLRUMap
28
+
29
+ if TruffleRuby.native?
30
+ path = "farce/engine/truffleruby/native"
31
+ autoload :UnsafeTreeMap, "#{path}/unsafe_tree_map"
32
+ autoload :PriorityQueue, "#{path}/priority_queue"
33
+ autoload :ShareableTreeMap, "#{path}/tree_map"
34
+ autoload :TreeMap, "#{path}/tree_map"
35
+ autoload :MutableTreeMap, "#{path}/tree_map"
36
+ autoload :Counter, "#{path}/counter"
37
+ autoload :Flag, "#{path}/flag"
38
+ end
39
+
40
+ def native_ractors? = false
41
+
42
+ # @api private
43
+ # TruffleRuby probes this additional hook before using _dump.
44
+ def marshal_protocol_method?(name)
45
+ name == :__custom_marshal__ || MarshalSupport.protocol_method?(name)
46
+ end
47
+
48
+ # Autoload on TruffleRuby is not thread-safe: A thread can see the module before its methods are defined.
49
+ # So lets eager load all autoloaded constants, except the ones that would trigger a configuration freeze.
50
+ # These use constant assignment anyway, so they are safe to load lazily.
51
+ def finalize_engine
52
+ skip = %i[FROZEN_CONFIG MainScheduler ParallelScheduler]
53
+ seen = ::Set.new.compare_by_identity
54
+ autoload = lambda do |namespace|
55
+ namespace.constants(false).each do |const|
56
+ next if skip.include?(const)
57
+ result = namespace.const_get(const, false)
58
+ next unless Module === result && !seen.include?(result)
59
+ seen << result
60
+ autoload[result]
61
+ end
62
+ end
63
+
64
+ autoload[Farce]
65
+ autoload[Internal]
66
+ end
67
+
68
+ def rebind(proc, new_self, lambda)
69
+ binding = new_self.instance_eval { binding() }
70
+ prefix = "__rebind_#{proc.object_id}"
71
+ signature = Array.new(proc.parameters.size)
72
+ call_signature = []
73
+ optional = []
74
+ after_optional = []
75
+ keyword_args = []
76
+ keyword_optional = []
77
+ extra_lines = []
78
+ keyword_rest = nil
79
+ rest = nil
80
+ block = nil
81
+
82
+ proc.parameters(lambda: true).each_with_index do |(type, name), index|
83
+ # simplecov:disable
84
+ if name.nil? || name == :_ || name == :* || name == :** || name == "&" || name =~ /^_\d+$/
85
+ name = :"#{prefix}_#{index}"
86
+ end
87
+ case type
88
+ when :req
89
+ signature[index] = name
90
+ required = optional.any? ? after_optional : call_signature
91
+ required << name
92
+ when :opt
93
+ signature[index] = "#{name} = UNDEFINED"
94
+ optional << name
95
+ when :rest
96
+ rest = signature[index] = "*#{name}"
97
+ when :key
98
+ signature[index] = "#{name}: UNDEFINED"
99
+ keyword_optional << name
100
+ when :keyreq
101
+ keyword_args << signature[index] = "#{name}:"
102
+ when :keyrest
103
+ keyword_rest = signature[index] = "**#{name}"
104
+ when :block
105
+ block = signature[index] = "&#{name}"
106
+ else
107
+ raise "unexpected parameter type: #{type}"
108
+ end
109
+ end
110
+ # simplecov:enable
111
+
112
+ if optional.any?
113
+ extra_lines << "#{prefix}_args = []"
114
+ call_signature << "*#{prefix}_args"
115
+ optional.each { extra_lines << "#{prefix}_args << #{it} unless UNDEFINED.equal?(#{it})" }
116
+ end
117
+
118
+ call_signature << rest if rest
119
+ call_signature += keyword_args if keyword_args.any?
120
+
121
+ if keyword_optional.any?
122
+ extra_lines << "#{prefix}_kwargs = {}"
123
+ call_signature << "**#{prefix}_kwargs"
124
+ keyword_optional.each do |arg|
125
+ extra_lines << "#{prefix}_kwargs[#{arg.inspect}] = #{arg} unless UNDEFINED.equal?(#{arg})"
126
+ end
127
+ end
128
+
129
+ call_signature << keyword_rest if keyword_rest
130
+ call_signature << block if block
131
+
132
+ Module.new do
133
+ method_name = proc.inspect
134
+ define_method(method_name, proc)
135
+ binding.local_variable_set(:"#{prefix}_unbound", instance_method(method_name))
136
+ end
137
+
138
+ lambda = proc.lambda? if lambda.nil?
139
+
140
+ binding.eval <<~RUBY
141
+ #{lambda ? "lambda" : "proc "} do #{"|#{signature.join(", ")}|" unless signature.empty?}
142
+ #{extra_lines.join("\n ")}
143
+ #{prefix}_unbound.bind_call(self, #{call_signature.join(", ")})
144
+ end
145
+ RUBY
146
+ end
147
+ end
148
+ end