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,63 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "jruby"
6
+ require "java"
7
+
8
+ # Load wait helpers before worker threads can contend or be canceled.
9
+ require "farce/internal/reservation_waiting"
10
+ require "farce/engine/jruby/lease_waiting"
11
+ require "farce/engine/shared"
12
+ require "farce/engine/jvm"
13
+
14
+ module Farce
15
+ # @!visibility private
16
+ module Internal # :nodoc: all
17
+ include Autoloads["#{__dir__}/jruby"]
18
+
19
+ Lock = Mutex
20
+
21
+ autoload :WeakMap, "farce/engine/shared/unshared_weak_map"
22
+ autoload :WeakKeyMap, "farce/engine/shared/unshared_weak_map"
23
+ autoload :WeakValueMap, "farce/engine/shared/unshared_weak_map"
24
+ autoload :LFUMap, "farce/engine/jruby/bounded_map"
25
+ autoload :LRUMap, "farce/engine/jruby/bounded_map"
26
+ autoload :ShareableLFUMap, "farce/engine/jruby/bounded_map"
27
+ autoload :ShareableLRUMap, "farce/engine/jruby/bounded_map"
28
+ autoload :StrictLFUMap, "farce/engine/jruby/bounded_map"
29
+ autoload :StrictLRUMap, "farce/engine/jruby/bounded_map"
30
+
31
+ java_import org.jruby.RubyProc
32
+ java_import org.jruby.runtime.Block
33
+
34
+ def native_ractors? = false
35
+
36
+ def prepare_mutable_numeric(klass) = klass.include MutableNumericCopy
37
+
38
+ # Fibers expose their backing thread through Thread.current.
39
+ def storage_thread(thread) = JRuby.reference(thread).getFiberCurrentThread
40
+
41
+ def rebind(proc, new_self, lambda)
42
+ # Proc#dup shares its binding. Copy the frame before changing the receiver,
43
+ # while retaining the dynamic scope that owns captured local variables.
44
+ jproc = ref(proc)
45
+ block = jproc.get_block.clone_block_and_frame
46
+ self_ref = ref(new_self)
47
+ binding = block.get_binding
48
+
49
+ binding.set_self(self_ref)
50
+ binding.get_frame.set_self(self_ref)
51
+
52
+ lambda = proc.lambda? if lambda.nil?
53
+ type = lambda ? Block::Type::LAMBDA : Block::Type::PROC
54
+ rebound = RubyProc.new_proc(jproc.get_runtime, jproc.get_type, block, type, nil, -1)
55
+ jproc.copy_instance_variables_into(ref(rebound).get_instance_variables)
56
+ rebound
57
+ end
58
+
59
+ private
60
+
61
+ def ref(obj) = JRuby.reference(obj)
62
+ end
63
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/jvm/types"
6
+ require "farce/engine/shared/weak_map/reference"
7
+
8
+ module Farce
9
+ module Internal
10
+ # Weak cell references in a registry whose iterator permits removal.
11
+ # JRuby's ObjectSpace::WeakMap iterator fails when its registry changes.
12
+ class ConcurrentWeakRegistry
13
+ Holder = Data.define(:reference)
14
+ private_constant :Holder
15
+
16
+ def initialize
17
+ @entries = JVMContainers::ConcurrentHashMap.new
18
+ @sweep = nil
19
+ end
20
+
21
+ def []=(token, entry)
22
+ @entries.put(token, Holder.new(UnsharedWeakMapWeakReference.for(entry)))
23
+ sweep_one
24
+ entry
25
+ end
26
+
27
+ def delete(token) = @entries.remove(token)
28
+
29
+ def each_value
30
+ return enum_for(__method__) unless block_given?
31
+ iterator = @entries.entrySet.iterator
32
+ while iterator.hasNext
33
+ entry = iterator.next
34
+ alive, cell = entry.getValue.reference.read
35
+ if alive
36
+ yield cell
37
+ else
38
+ @entries.remove(entry.getKey, entry.getValue)
39
+ end
40
+ end
41
+ self
42
+ end
43
+
44
+ def values = each_value.to_a
45
+
46
+ def sweep_one
47
+ @sweep = @entries.entrySet.iterator unless @sweep&.hasNext
48
+ return unless @sweep.hasNext
49
+ entry = @sweep.next
50
+ return if entry.getValue.reference.read.first
51
+ @entries.remove(entry.getKey, entry.getValue)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/jvm/types"
6
+
7
+ module Farce
8
+ # @!visibility private
9
+ module Internal # :nodoc: all
10
+ class Counter < Numeric
11
+ attr_reader :initial
12
+
13
+ def initialize(value = 0)
14
+ raise "Counter is already initialized" if defined?(@counter)
15
+ check_frozen!
16
+ raise TypeError, "initial value must be an Integer" unless value.is_a?(Integer)
17
+
18
+ @signal = Signal.new
19
+ @initial = value
20
+ @counter = JVMContainers::AtomicLong.new(value)
21
+ super()
22
+ end
23
+
24
+ def get = @counter.get
25
+
26
+ def store(value)
27
+ check_frozen!
28
+ raise TypeError, "value must be an Integer" unless value.is_a?(Integer)
29
+
30
+ @counter.set(value)
31
+ @signal.broadcast
32
+ value
33
+ end
34
+
35
+ def swap(value)
36
+ check_frozen!
37
+ raise TypeError, "value must be an Integer" unless value.is_a?(Integer)
38
+
39
+ @counter.getAndSet(value).tap { @signal.broadcast }
40
+ end
41
+
42
+ def add(delta = 1)
43
+ check_frozen!
44
+ raise TypeError, "delta must be an Integer" unless delta.is_a?(Integer)
45
+
46
+ @counter.addAndGet(delta).tap { @signal.broadcast }
47
+ end
48
+
49
+ def compare_and_set(expected_value, new_value)
50
+ check_frozen!
51
+ raise TypeError, "expected value must be an Integer" unless expected_value.is_a?(Integer)
52
+ raise TypeError, "replacement value must be an Integer" unless new_value.is_a?(Integer)
53
+
54
+ @counter.compareAndSet(expected_value, new_value).tap { @signal.broadcast }
55
+ end
56
+
57
+ def subtract(delta = 1)
58
+ check_frozen!
59
+ raise TypeError, "delta must be an Integer" unless delta.is_a?(Integer)
60
+
61
+ @counter.addAndGet(-delta).tap { @signal.broadcast }
62
+ end
63
+
64
+ def increment(delta = 1)
65
+ check_frozen!
66
+ unless delta.is_a?(Integer)
67
+ delta = Integer(delta)
68
+ check_frozen!
69
+ end
70
+ @counter.addAndGet(delta).tap { @signal.broadcast }
71
+ self
72
+ end
73
+
74
+ def decrement(delta = 1)
75
+ check_frozen!
76
+ unless delta.is_a?(Integer)
77
+ delta = Integer(delta)
78
+ check_frozen!
79
+ end
80
+ @counter.addAndGet(-delta).tap { @signal.broadcast }
81
+ self
82
+ end
83
+
84
+ alias value get
85
+ alias value= store
86
+
87
+ def change_signal = @signal
88
+
89
+ private
90
+
91
+ def check_frozen!
92
+ raise FrozenError.new("can't modify frozen #{self.class}", receiver: self) if frozen?
93
+ end
94
+
95
+ def initialize_copy(other)
96
+ @signal = Signal.new
97
+ @initial = other.initial
98
+ @counter = JVMContainers::AtomicLong.new(other.value)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,32 @@
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 JVMExtension
9
+ jar = File.expand_path("farce.jar", __dir__)
10
+ unless File.file?(jar)
11
+ raise LoadError, "Farce's Java extension is missing; run rake java:compile in the source checkout"
12
+ end
13
+
14
+ if RUBY_ENGINE == "jruby"
15
+ require "java"
16
+ require jar
17
+ BoundedMap = Java::OrgFarce::BoundedMap
18
+ PriorityKey = Java::OrgFarce::PriorityKey
19
+ PriorityQueue = Java::OrgFarce::PriorityQueue
20
+ QueueFailure = Java::OrgFarce::PriorityQueue::Failure
21
+ QueueSignal = Java::OrgFarce::QueueSignal
22
+ else
23
+ Java.add_to_classpath(jar)
24
+ BoundedMap = Java.type("org.farce.BoundedMap")
25
+ PriorityKey = Java.type("org.farce.PriorityKey")
26
+ PriorityQueue = Java.type("org.farce.PriorityQueue")
27
+ QueueFailure = Java.type("org.farce.PriorityQueue$Failure")
28
+ QueueSignal = Java.type("org.farce.QueueSignal")
29
+ end
30
+ end
31
+ end
32
+ end
Binary file
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/jvm/types"
6
+
7
+ module Farce
8
+ # @!visibility private
9
+ module Internal # :nodoc: all
10
+ class Flag
11
+ def initialize(value = false) # rubocop:disable Style/OptionalBooleanParameter
12
+ raise "Flag is already initialized" if defined?(@reference)
13
+ check_frozen!
14
+ @reference = JVMContainers::AtomicBoolean.new(validate_boolean(value, "initial value"))
15
+ end
16
+
17
+ def value = @reference.get
18
+
19
+ def set # rubocop:disable Naming/PredicateMethod
20
+ check_frozen!
21
+ @reference.set(true)
22
+ true
23
+ end
24
+
25
+ def unset # rubocop:disable Naming/PredicateMethod
26
+ check_frozen!
27
+ @reference.set(false)
28
+ false
29
+ end
30
+
31
+ def store(value)
32
+ check_frozen!
33
+ value = validate_boolean(value, "value")
34
+ @reference.set(value)
35
+ value
36
+ end
37
+
38
+ def swap(value)
39
+ check_frozen!
40
+ value = validate_boolean(value, "value")
41
+ @reference.getAndSet(value)
42
+ end
43
+
44
+ def compare_and_set(expected_value, replacement_value)
45
+ check_frozen!
46
+ expected_value = validate_boolean(expected_value, "expected value")
47
+ replacement_value = validate_boolean(replacement_value, "replacement value")
48
+ @reference.compareAndSet(expected_value, replacement_value)
49
+ end
50
+
51
+ def toggle
52
+ check_frozen!
53
+ loop do
54
+ current = @reference.get
55
+ replacement = !current
56
+ return replacement if @reference.compareAndSet(current, replacement)
57
+ end
58
+ end
59
+
60
+ alias get value
61
+ alias value= store
62
+
63
+ private
64
+
65
+ def check_frozen!
66
+ raise FrozenError.new("can't modify frozen #{self.class}", receiver: self) if frozen?
67
+ end
68
+
69
+ def validate_boolean(value, name)
70
+ return value if value.equal?(true) || value.equal?(false)
71
+ raise ArgumentError, "#{name} must be true or false"
72
+ end
73
+
74
+ def initialize_copy(other)
75
+ @reference = JVMContainers::AtomicBoolean.new(other.value)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+ # shareable_constant_value: literal
3
+ # warn_indent: true
4
+
5
+ require "farce/engine/jvm/types"
6
+ require "farce/engine/jvm/extension"
7
+
8
+ module Farce
9
+ # @!visibility private
10
+ module Internal # :nodoc: all
11
+ # Java owns the lock, ordered buckets, FIFO links, and cancellation index.
12
+ # Ruby callbacks retain Ruby comparison, identity, and notification semantics.
13
+ class PriorityQueue
14
+ include Freeze::Unfreezable
15
+
16
+ Box = Struct.new(:value)
17
+ INITIALIZATION_LOCK = Mutex.new
18
+ JAVA_CAPACITY_MAX = (1 << 63) - 1
19
+ IDENTITY = ->(box) { JVMContainers.identity_token(box.value).to_s }
20
+ EQUAL = ->(stored, requested) { stored.value == requested.value }
21
+ IDENTICAL = ->(stored, requested) { JVMContainers.identical?(stored.value, requested.value) }
22
+ MATCH = ->(stored, requested) { requested.value === stored.value } # rubocop:disable Style/CaseEquality
23
+
24
+ COMPARATOR = JVMExtension::PriorityKey.comparator(JVMContainers.comparator do |left, right|
25
+ JVMContainers.compare(left.value, right.value)
26
+ end)
27
+
28
+ SNAPSHOT = lambda do |key|
29
+ value = JVMContainers.copy_frozen_string(key.getRubyKey.value)
30
+ JVMExtension::PriorityKey.new(Box.new(value), false, 0.0)
31
+ end
32
+
33
+ SCHEDULED = lambda do
34
+ next false unless Fiber.respond_to?(:scheduler)
35
+ next false if Fiber.current.respond_to?(:blocking?) && Fiber.current.blocking?
36
+
37
+ scheduler = Fiber.current_scheduler if Fiber.respond_to?(:current_scheduler)
38
+ scheduler ||= Fiber.scheduler
39
+ !scheduler.nil?
40
+ end
41
+
42
+ private_constant :Box, :INITIALIZATION_LOCK, :JAVA_CAPACITY_MAX,
43
+ :COMPARATOR, :SNAPSHOT, :IDENTITY, :EQUAL, :IDENTICAL, :MATCH, :SCHEDULED
44
+
45
+ def initialize(capacity: nil, signal: nil, track_age: false)
46
+ check_initialization
47
+ parsed_capacity = normalize_capacity(capacity)
48
+ raise TypeError, "signal must respond to #broadcast" unless signal.nil? || signal.respond_to?(:broadcast)
49
+ # A failed notification leaves storage unchanged. Defer asynchronous
50
+ # cancellation through notification and the Java commit it announces.
51
+ unless signal.nil?
52
+ committer = lambda do |operation|
53
+ Thread.handle_interrupt(INTERRUPT_MASK) do
54
+ signal.broadcast
55
+ operation.run
56
+ end
57
+ end
58
+ end
59
+ java_capacity = parsed_capacity ? [parsed_capacity, JAVA_CAPACITY_MAX].min : 0
60
+ # Subclasses may override broadcast and must retain callback semantics.
61
+ native_signal = signal if RUBY_ENGINE == "jruby" &&
62
+ JVMContainers.identical?(JVMContainers::OBJECT_CLASS_METHOD.bind_call(signal), Signal)
63
+ core = JVMExtension::PriorityQueue.new(COMPARATOR, SNAPSHOT, IDENTITY, EQUAL,
64
+ IDENTICAL, MATCH, committer, SCHEDULED, java_capacity, native_signal, track_age ? true : false)
65
+ INITIALIZATION_LOCK.synchronize do
66
+ Thread.handle_interrupt(INTERRUPT_MASK) do
67
+ check_initialization
68
+ @capacity = parsed_capacity
69
+ @core = core
70
+ JVMContainers.freeze_object(self)
71
+ end
72
+ end
73
+ end
74
+
75
+ def push(priority, value)
76
+ core = storage
77
+ if Float === priority
78
+ core.pushFloat(priority, Box.new(priority), Box.new(value))
79
+ else
80
+ core.push(key(priority), Box.new(value))
81
+ end
82
+ rescue JVMExtension::QueueFailure => e
83
+ raise_failure(e)
84
+ end
85
+
86
+ def pop(&fallback) = read(0, false, nil, fallback)
87
+ def pop_last(&fallback) = read(0, true, nil, fallback)
88
+
89
+ def pop_before(latest_priority, &fallback)
90
+ return read(0, false, key(latest_priority), fallback) unless Float === latest_priority
91
+
92
+ result = storage.readBefore(latest_priority, Box.new(latest_priority))
93
+ result.nil? ? fallback&.call : result.value
94
+ rescue JVMExtension::QueueFailure => e
95
+ raise_failure(e)
96
+ end
97
+
98
+ def peek(&fallback) = read(1, false, nil, fallback)
99
+ def peek_last(&fallback) = read(1, true, nil, fallback)
100
+ def peek_priority(&fallback) = read(2, false, nil, fallback)
101
+ def peek_last_priority(&fallback) = read(2, true, nil, fallback)
102
+ def delete(priority, value) = remove(priority, value, 0)
103
+ def delete_identity(priority, value) = remove(priority, value, 1)
104
+ def delete_match(priority, pattern) = remove(priority, pattern, 2)
105
+
106
+ def size
107
+ storage.size
108
+ rescue JVMExtension::QueueFailure => e
109
+ raise_failure(e)
110
+ end
111
+
112
+ def empty? = size.zero?
113
+
114
+ def capacity
115
+ storage
116
+ @capacity
117
+ end
118
+
119
+ def closed?
120
+ storage.isClosed
121
+ rescue JVMExtension::QueueFailure => e
122
+ raise_failure(e)
123
+ end
124
+
125
+ def sealed?
126
+ storage.isSealed
127
+ rescue JVMExtension::QueueFailure => e
128
+ raise_failure(e)
129
+ end
130
+
131
+ def age_tracking? = storage.isAgeTracking
132
+ def generation = JVMContainers.nullable(storage.generation)
133
+ def oldest_enqueued_at = JVMContainers.nullable(storage.oldestEnqueuedAt)
134
+ def oldest_age = JVMContainers.nullable(storage.oldestAge)
135
+
136
+ def clear
137
+ storage.clear
138
+ self
139
+ rescue JVMExtension::QueueFailure => e
140
+ raise_failure(e)
141
+ end
142
+
143
+ def close
144
+ storage.close
145
+ self
146
+ rescue JVMExtension::QueueFailure => e
147
+ raise_failure(e)
148
+ end
149
+
150
+ def seal
151
+ storage.seal
152
+ self
153
+ rescue JVMExtension::QueueFailure => e
154
+ raise_failure(e)
155
+ end
156
+
157
+ def initialize_copy(_other)
158
+ raise TypeError, "priority queues cannot be copied"
159
+ end
160
+
161
+ private
162
+
163
+ def check_initialization
164
+ raise "priority queue is already initialized" if defined?(@core)
165
+ raise FrozenError, "can't modify frozen #{self.class}" if JVMContainers.frozen_object?(self)
166
+ end
167
+
168
+ def storage
169
+ raise "priority queue is not initialized" unless defined?(@core) && @core
170
+
171
+ @core
172
+ end
173
+
174
+ def key(priority)
175
+ floating = Float === priority
176
+ JVMExtension::PriorityKey.new(Box.new(priority), floating, floating ? priority : 0.0,
177
+ String === priority)
178
+ end
179
+
180
+ def read(kind, last, cutoff, fallback)
181
+ result = storage.read(kind, last, cutoff)
182
+ result.nil? ? fallback&.call : result.value
183
+ rescue JVMExtension::QueueFailure => e
184
+ raise_failure(e)
185
+ end
186
+
187
+ def remove(priority, value, kind)
188
+ storage.removeValue(key(priority), Box.new(value), kind)
189
+ rescue JVMExtension::QueueFailure => e
190
+ raise_failure(e)
191
+ end
192
+
193
+ def raise_failure(error)
194
+ klass = case error.getCode
195
+ when 2 then ::Farce::ClosedQueueError
196
+ when 4 then ::Farce::SealedQueueError
197
+ else ThreadError
198
+ end
199
+ raise klass, error.getMessage
200
+ end
201
+
202
+ def normalize_capacity(value)
203
+ return nil if value.nil?
204
+
205
+ unless JVMContainers.is_a?(value, Integer)
206
+ raise TypeError, "capacity must be an Integer or nil" unless value.respond_to?(:to_int)
207
+
208
+ value = value.to_int
209
+ end
210
+ raise TypeError, "capacity must be an Integer or nil" unless JVMContainers.is_a?(value, Integer)
211
+ raise ArgumentError, "capacity must be positive or nil" unless value.positive?
212
+
213
+ value
214
+ end
215
+ end
216
+ end
217
+ end