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,314 @@
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
+ module JVMBoundedMapBackend
12
+ Box = Struct.new(:value)
13
+ State = Data.define(:core)
14
+ INITIALIZATION_LOCK = Mutex.new
15
+ JAVA_CAPACITY_MAX = (1 << 63) - 1
16
+ INTEGER_XOR_METHOD = Integer.instance_method(:^)
17
+ INTEGER_SHIFT_METHOD = Integer.instance_method(:>>)
18
+ INTEGER_AND_METHOD = Integer.instance_method(:&)
19
+ INTEGER_SUBTRACT_METHOD = Integer.instance_method(:-)
20
+ IDENTITY = lambda do |stored, requested|
21
+ JVMContainers.identical?(stored.value, requested.value)
22
+ end
23
+
24
+ EQUALITY = lambda do |stored, requested|
25
+ left = stored.value
26
+ right = requested.value
27
+ next true if JVMContainers.identical?(left, right)
28
+ next false unless left.eql?(right)
29
+
30
+ true
31
+ end
32
+ private_constant :Box, :State, :INITIALIZATION_LOCK,
33
+ :JAVA_CAPACITY_MAX, :INTEGER_XOR_METHOD, :INTEGER_SHIFT_METHOD,
34
+ :INTEGER_AND_METHOD, :INTEGER_SUBTRACT_METHOD, :IDENTITY, :EQUALITY
35
+
36
+ def initialize(
37
+ entries = nil,
38
+ max_size:,
39
+ compare_by_identity: false,
40
+ compare_keys_by_identity: compare_by_identity,
41
+ compare_values_by_identity: compare_by_identity
42
+ )
43
+ check_initializable
44
+ strict_boolean(compare_by_identity, "compare_by_identity")
45
+ compare_keys_by_identity = strict_boolean(compare_keys_by_identity, "compare_keys_by_identity")
46
+ compare_values_by_identity = strict_boolean(compare_values_by_identity, "compare_values_by_identity")
47
+
48
+ limit = normalize_limit(max_size, "max_size")
49
+ entries = coerce_entries(entries)
50
+ check_initializable
51
+
52
+ guard = JVMOperationGuard.new(synchronized: true, label: "bounded map")
53
+ equal = compare_keys_by_identity ? IDENTITY : EQUALITY
54
+ core = JVMExtension::BoundedMap.new(lfu_policy?, limit, equal)
55
+
56
+ entries&.each do |key, value|
57
+ check_initializable
58
+ key = canonical_key(key, compare_keys_by_identity)
59
+ hash = key_hash(key, compare_keys_by_identity)
60
+ core.put(Box.new(key), Box.new(value), hash)
61
+ check_initializable
62
+ end
63
+
64
+ state = State.new(core)
65
+
66
+ INITIALIZATION_LOCK.synchronize do
67
+ Thread.handle_interrupt(INTERRUPT_MASK) do
68
+ check_initializable
69
+ @compare_keys_by_identity = compare_keys_by_identity
70
+ @compare_values_by_identity = compare_values_by_identity
71
+ @guard = guard
72
+ @state = state
73
+ @freeze_state = Flag.new(false)
74
+ JVMContainers.freeze_object(self)
75
+ end
76
+ end
77
+ end
78
+
79
+ def [](key)
80
+ key = canonical_key(key)
81
+ wrapped = access do
82
+ frozen? ? core.observe(Box.new(key), key_hash(key)) : core.get(Box.new(key), key_hash(key))
83
+ end
84
+ JVMContainers.nullable(wrapped)&.value
85
+ end
86
+
87
+ def freeze
88
+ state = @freeze_state
89
+ return super unless state
90
+
91
+ state.set
92
+ self
93
+ end
94
+
95
+ def frozen?
96
+ state = @freeze_state
97
+ state ? state.value : super
98
+ end
99
+
100
+ def []=(key, value)
101
+ check_frozen!
102
+ key = canonical_key(key)
103
+ access do
104
+ check_frozen!
105
+ core.put(Box.new(key), Box.new(value), key_hash(key))
106
+ end
107
+ value
108
+ end
109
+
110
+ def fetch(*arguments)
111
+ unless arguments.length.between?(1, 2)
112
+ raise ArgumentError, "wrong number of arguments (given #{arguments.length}, expected 1..2)"
113
+ end
114
+
115
+ original_key, default = arguments
116
+ key = canonical_key(original_key)
117
+ default_given = arguments.length == 2
118
+
119
+ warn "block supersedes default value argument", uplevel: 1 if block_given? && default_given
120
+
121
+ wrapped = access do
122
+ frozen? ? core.observe(Box.new(key), key_hash(key)) : core.get(Box.new(key), key_hash(key))
123
+ end
124
+ wrapped = JVMContainers.nullable(wrapped)
125
+
126
+ return wrapped.value if wrapped
127
+ return yield(original_key) if block_given?
128
+ return default if default_given
129
+
130
+ raise KeyError.new(
131
+ "key not found: #{original_key.inspect}",
132
+ receiver: self,
133
+ key: original_key,
134
+ )
135
+ end
136
+
137
+ def prepare_key(key)
138
+ key = canonical_key(key)
139
+ access { core.observeKey(Box.new(key), key_hash(key)) }
140
+ key
141
+ end
142
+
143
+ def key?(key)
144
+ key = canonical_key(key)
145
+ !JVMContainers.nullable(access { core.observeKey(Box.new(key), key_hash(key)) }).nil?
146
+ end
147
+
148
+ def getkey(key)
149
+ key = canonical_key(key)
150
+ wrapped = access { core.observeKey(Box.new(key), key_hash(key)) }
151
+ JVMContainers.nullable(wrapped)&.value
152
+ end
153
+
154
+ def delete(key)
155
+ check_frozen!
156
+ key = canonical_key(key)
157
+ wrapped = access do
158
+ check_frozen!
159
+ core.delete(Box.new(key), key_hash(key))
160
+ end
161
+ JVMContainers.nullable(wrapped)&.value
162
+ end
163
+
164
+ def clear
165
+ check_frozen!
166
+ access { check_frozen!.then { core.clear } }
167
+ self
168
+ end
169
+
170
+ def max_size = access { core.getMaxSize }
171
+
172
+ def max_size=(limit)
173
+ check_frozen!
174
+ limit = normalize_limit(limit, "max_size")
175
+ access { check_frozen!.then { core.setMaxSize(limit) } }
176
+ limit
177
+ end
178
+
179
+ def prune(to:)
180
+ check_frozen!
181
+ limit = normalize_limit(to, "to")
182
+ access { check_frozen!.then { core.prune(limit) } }
183
+ end
184
+
185
+ def shift
186
+ check_frozen!
187
+ pair = JVMContainers.nullable(access { check_frozen!.then { core.shift } })
188
+ [pair[0].value, pair[1].value] if pair
189
+ end
190
+
191
+ def empty? = access { core.isEmpty }
192
+ def size = access { core.size }
193
+ alias length size
194
+
195
+ def compare_keys_by_identity? = @compare_keys_by_identity
196
+ def compare_values_by_identity? = @compare_values_by_identity
197
+
198
+ def each
199
+ return enum_for(__method__) { size } unless block_given?
200
+
201
+ snapshot = access { core.snapshot }
202
+ index = 0
203
+
204
+ while index < snapshot.length
205
+ yield snapshot[index].value, snapshot[index + 1].value
206
+ index += 2
207
+ end
208
+
209
+ self
210
+ end
211
+
212
+ def each_key
213
+ return enum_for(__method__) { size } unless block_given?
214
+ each { |key, _value| yield key }
215
+ self
216
+ end
217
+
218
+ def each_value
219
+ return enum_for(__method__) { size } unless block_given?
220
+ each { |_key, value| yield value }
221
+ self
222
+ end
223
+
224
+ def initialize_copy(other)
225
+ super
226
+ other.send(:access) do
227
+ @compare_keys_by_identity = other.compare_keys_by_identity?
228
+ @compare_values_by_identity = other.compare_values_by_identity?
229
+ @guard = JVMOperationGuard.new(synchronized: true, label: "bounded map")
230
+ @state = State.new(other.send(:core).copy)
231
+ @freeze_state = Flag.new(false)
232
+ JVMContainers.freeze_object(self)
233
+ end
234
+ end
235
+
236
+ private
237
+
238
+ def check_frozen! = Internal::Freeze.check(self)
239
+
240
+ def access(&)
241
+ raise "bounded map is not initialized" unless defined?(@guard) && @guard
242
+ @guard.synchronize(&)
243
+ end
244
+
245
+ def core = @state.core
246
+
247
+ def check_initializable
248
+ raise "bounded map is already initialized" if defined?(@state)
249
+ raise FrozenError, "can't modify frozen #{self.class}" if JVMContainers.frozen_object?(self)
250
+ end
251
+
252
+ def strict_boolean(value, name)
253
+ return value if JVMContainers.identical?(value, true) || JVMContainers.identical?(value, false)
254
+ raise ArgumentError, "#{name} must be a boolean"
255
+ end
256
+
257
+ def normalize_limit(value, name)
258
+ raise TypeError, "#{name} must be an Integer" unless JVMContainers.is_a?(value, Integer)
259
+ raise ArgumentError, "#{name} must be non-negative" if value.negative?
260
+ raise RangeError, "#{name} exceeds the JVM backend limit" if value > JAVA_CAPACITY_MAX
261
+
262
+ value
263
+ end
264
+
265
+ def canonical_key(key, identity = compare_keys_by_identity?)
266
+ !identity && JVMContainers.string?(key) ? JVMContainers.canonical_string(key) : key
267
+ end
268
+
269
+ def key_hash(key, identity = compare_keys_by_identity?)
270
+ value = identity ? JVMContainers.identity_token(key) : key.hash
271
+ value = Integer.try_convert(value) unless JVMContainers.is_a?(value, Integer)
272
+ raise TypeError, "hash value must be an Integer" unless value
273
+
274
+ shifted = INTEGER_SHIFT_METHOD.bind_call(value, 32)
275
+ folded = INTEGER_XOR_METHOD.bind_call(value, shifted)
276
+ folded = INTEGER_AND_METHOD.bind_call(folded, 0xffff_ffff)
277
+ return folded if folded < 0x8000_0000
278
+
279
+ INTEGER_SUBTRACT_METHOD.bind_call(folded, 0x1_0000_0000)
280
+ end
281
+
282
+ def coerce_entries(entries)
283
+ return if entries.nil?
284
+ return entries if JVMContainers.is_a?(entries, Hash)
285
+
286
+ hash = Hash.try_convert(entries)
287
+ return hash if JVMContainers.is_a?(hash, Hash)
288
+
289
+ raise TypeError, "entries must be a Hash or respond to #to_hash"
290
+ end
291
+
292
+ # simplecov:disable
293
+ def lfu_policy? = raise "subclass failed to implement #lfu_policy?"
294
+ # simplecov:enable
295
+ end
296
+
297
+ class LRUMap
298
+ include JVMBoundedMapBackend
299
+
300
+ private def lfu_policy? = false
301
+ end
302
+
303
+ class LFUMap
304
+ include JVMBoundedMapBackend
305
+
306
+ private def lfu_policy? = true
307
+ end
308
+
309
+ ShareableLRUMap = StrictLRUMap = LRUMap
310
+ ShareableLFUMap = StrictLFUMap = LFUMap
311
+
312
+ private_constant :JVMBoundedMapBackend
313
+ end
314
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Farce
4
+ module Internal
5
+ case FROZEN_CONFIG.fiber_scheduler_implementation
6
+ when :jvm
7
+ # Load the JVM implementation below.
8
+ when :native
9
+ raise LoadError, "the native fiber scheduler requires CRuby"
10
+ when :select
11
+ raise LoadError, "the select scheduler currently requires CRuby"
12
+ end
13
+
14
+ require "farce/engine/jruby/fiber_scheduler.jar"
15
+ Java::OrgFarce::FiberScheduler.load(JRuby.runtime)
16
+
17
+ class FiberScheduler
18
+ include SelectScheduler
19
+ prepend SchedulerLifecycle
20
+
21
+ def initialize(backend: :auto)
22
+ raise ArgumentError, "unavailable JVM driver: #{backend}" unless %i[auto nio].include?(backend)
23
+ super(backend: :select)
24
+ @backend = :nio
25
+ nio_initialize
26
+ end
27
+
28
+ def io_read(io, buffer, minimum, offset = 0)
29
+ buffer = nio_hook_buffer(buffer)
30
+ super
31
+ end
32
+
33
+ def io_write(io, buffer, minimum, offset = 0)
34
+ buffer = nio_hook_buffer(buffer)
35
+ super
36
+ end
37
+
38
+ private :nio_initialize, :nio_select, :nio_destroy, :nio_wakeup, :nio_hook_buffer
39
+
40
+ private
41
+
42
+ def locked_buffer(buffer)
43
+ return yield if buffer.locked?
44
+ native = JRuby.reference(buffer)
45
+ native.lock(JRuby.runtime.current_context)
46
+ begin
47
+ yield
48
+ ensure
49
+ native.unlock(JRuby.runtime.current_context)
50
+ end
51
+ end
52
+
53
+ def owner_thread = JRuby.reference(Thread.current).getFiberCurrentThread
54
+
55
+ def select_snapshot(groups, timeout)
56
+ found = nio_select(groups, timeout)
57
+ return unless found
58
+ # JRuby's combined-set select can drop READABLE. Probe each set as well.
59
+ groups.each_with_index do |list, index|
60
+ next if list.empty?
61
+ isolated = [[], [], []]
62
+ isolated[index] = list
63
+ extra = nio_select(isolated, 0)
64
+ found[index] |= extra[index] if extra
65
+ end
66
+ found
67
+ end
68
+
69
+ def write_wakeup
70
+ buffer = IO::Buffer.for(".")
71
+ transfer_nonblock(true, @wake_writer, buffer, 0, 1)
72
+ end
73
+
74
+ def read_wakeup
75
+ transfer_nonblock(false, @wake_reader, nil, 0, 4096)
76
+ end
77
+
78
+ def wakeup
79
+ super
80
+ nio_wakeup
81
+ end
82
+
83
+ def destroy
84
+ nio_destroy
85
+ super if @wake_reader
86
+ end
87
+
88
+ def transfer_nonblock(writing, io, buffer, offset, capacity)
89
+ file = JRuby.reference(io).getOpenFileChecked
90
+ file.setNonblock(JRuby.runtime)
91
+ # Duplicated JRuby channels cache blocking state separately from fd flags.
92
+ posix = JRuby.runtime.posix
93
+ fd = file.fd.realFileno
94
+ if fd >= 0 && posix.isNative
95
+ flags = posix.fcntl(fd, Java::JnrConstantsPlatform::Fcntl::F_GETFL)
96
+ raise SystemCallError.new("scheduler IO flags", posix.errno) if flags.negative?
97
+ nonblock = Java::JnrConstantsPlatform::OpenFlags::O_NONBLOCK.intValue
98
+ if flags.nobits?(nonblock) && posix.fcntlInt(fd, Java::JnrConstantsPlatform::Fcntl::F_SETFL,
99
+ flags | nonblock).negative?
100
+ raise SystemCallError.new("scheduler IO flags", posix.errno)
101
+ end
102
+ end
103
+ bytes = writing ? buffer.get_string(offset, capacity).to_java_bytes : Java.byte[capacity].new
104
+ shim = file.posix
105
+ count = writing ? shim.write(file.fd, bytes, 0, capacity, true) : shim.read(file.fd, bytes, 0, capacity, true)
106
+ if count.negative?
107
+ errno = shim.getErrno&.intValue || posix.errno
108
+ if [Errno::EAGAIN::Errno, Errno::EWOULDBLOCK::Errno].include?(errno)
109
+ return writing ? :wait_writable : :wait_readable
110
+ end
111
+ raise SystemCallError.new("scheduler IO", errno.zero? ? Errno::EIO::Errno : errno)
112
+ end
113
+ return count if writing
114
+ return if count.zero?
115
+ String.from_java_bytes(java.util.Arrays.copyOf(bytes, count))
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,19 @@
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 LeaseWaiting
9
+ MIN = 0.05
10
+
11
+ # JRuby delivers Thread#raise after its Java Phaser wait returns.
12
+ # Bound each wait so cancellation remains responsive.
13
+ def self.wait_interval(remaining)
14
+ return MIN if !remaining || remaining > MIN
15
+ remaining
16
+ end
17
+ end
18
+ end
19
+ end