automerge-rb 0.1.1

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 (481) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +175 -0
  4. data/ext/automerge_ext/automerge_ext.c +1805 -0
  5. data/ext/automerge_ext/extconf.rb +132 -0
  6. data/lib/automerge/version.rb +6 -0
  7. data/lib/automerge.rb +110 -0
  8. data/rust-toolchain.toml +4 -0
  9. data/vendor/automerge-rust/Cargo.lock +1909 -0
  10. data/vendor/automerge-rust/Cargo.toml +15 -0
  11. data/vendor/automerge-rust/automerge/Cargo.toml +78 -0
  12. data/vendor/automerge-rust/automerge/README.md +5 -0
  13. data/vendor/automerge-rust/automerge/benches/load_save.rs +102 -0
  14. data/vendor/automerge-rust/automerge/benches/map.rs +260 -0
  15. data/vendor/automerge-rust/automerge/benches/range.rs +37 -0
  16. data/vendor/automerge-rust/automerge/benches/sync.rs +95 -0
  17. data/vendor/automerge-rust/automerge/examples/README.md +7 -0
  18. data/vendor/automerge-rust/automerge/examples/quickstart.rs +57 -0
  19. data/vendor/automerge-rust/automerge/examples/watch.rs +94 -0
  20. data/vendor/automerge-rust/automerge/fuzz/Cargo.toml +29 -0
  21. data/vendor/automerge-rust/automerge/fuzz/fuzz_targets/load.rs +37 -0
  22. data/vendor/automerge-rust/automerge/src/autocommit.rs +1286 -0
  23. data/vendor/automerge-rust/automerge/src/automerge/current_state.rs +546 -0
  24. data/vendor/automerge-rust/automerge/src/automerge/tests.rs +2023 -0
  25. data/vendor/automerge-rust/automerge/src/automerge.rs +2071 -0
  26. data/vendor/automerge-rust/automerge/src/autoserde.rs +128 -0
  27. data/vendor/automerge-rust/automerge/src/change.rs +357 -0
  28. data/vendor/automerge-rust/automerge/src/change_graph.rs +1215 -0
  29. data/vendor/automerge-rust/automerge/src/change_queue.rs +46 -0
  30. data/vendor/automerge-rust/automerge/src/clock.rs +206 -0
  31. data/vendor/automerge-rust/automerge/src/columnar/column_range/boolean.rs +83 -0
  32. data/vendor/automerge-rust/automerge/src/columnar/column_range/delta.rs +148 -0
  33. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/group.rs +138 -0
  34. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/simple.rs +76 -0
  35. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic.rs +93 -0
  36. data/vendor/automerge-rust/automerge/src/columnar/column_range/key.rs +272 -0
  37. data/vendor/automerge-rust/automerge/src/columnar/column_range/obj_id.rs +202 -0
  38. data/vendor/automerge-rust/automerge/src/columnar/column_range/opid_list.rs +329 -0
  39. data/vendor/automerge-rust/automerge/src/columnar/column_range/raw.rs +38 -0
  40. data/vendor/automerge-rust/automerge/src/columnar/column_range/rle.rs +216 -0
  41. data/vendor/automerge-rust/automerge/src/columnar/column_range/value.rs +547 -0
  42. data/vendor/automerge-rust/automerge/src/columnar/column_range.rs +17 -0
  43. data/vendor/automerge-rust/automerge/src/columnar/encoding/boolean.rs +197 -0
  44. data/vendor/automerge-rust/automerge/src/columnar/encoding/col_error.rs +88 -0
  45. data/vendor/automerge-rust/automerge/src/columnar/encoding/column_decoder.rs +133 -0
  46. data/vendor/automerge-rust/automerge/src/columnar/encoding/decodable_impls.rs +175 -0
  47. data/vendor/automerge-rust/automerge/src/columnar/encoding/delta.rs +96 -0
  48. data/vendor/automerge-rust/automerge/src/columnar/encoding/encodable_impls.rs +200 -0
  49. data/vendor/automerge-rust/automerge/src/columnar/encoding/leb128.rs +82 -0
  50. data/vendor/automerge-rust/automerge/src/columnar/encoding/properties.rs +178 -0
  51. data/vendor/automerge-rust/automerge/src/columnar/encoding/raw.rs +101 -0
  52. data/vendor/automerge-rust/automerge/src/columnar/encoding/rle.rs +239 -0
  53. data/vendor/automerge-rust/automerge/src/columnar/encoding.rs +67 -0
  54. data/vendor/automerge-rust/automerge/src/columnar/splice_error.rs +47 -0
  55. data/vendor/automerge-rust/automerge/src/columnar.rs +14 -0
  56. data/vendor/automerge-rust/automerge/src/convert.rs +112 -0
  57. data/vendor/automerge-rust/automerge/src/cursor.rs +296 -0
  58. data/vendor/automerge-rust/automerge/src/decoding.rs +475 -0
  59. data/vendor/automerge-rust/automerge/src/error.rs +159 -0
  60. data/vendor/automerge-rust/automerge/src/exid.rs +238 -0
  61. data/vendor/automerge-rust/automerge/src/hydrate/list.rs +140 -0
  62. data/vendor/automerge-rust/automerge/src/hydrate/map.rs +132 -0
  63. data/vendor/automerge-rust/automerge/src/hydrate/tests.rs +40 -0
  64. data/vendor/automerge-rust/automerge/src/hydrate/text.rs +89 -0
  65. data/vendor/automerge-rust/automerge/src/hydrate.rs +368 -0
  66. data/vendor/automerge-rust/automerge/src/indexed_cache.rs +113 -0
  67. data/vendor/automerge-rust/automerge/src/iter/doc.rs +603 -0
  68. data/vendor/automerge-rust/automerge/src/iter/keys.rs +93 -0
  69. data/vendor/automerge-rust/automerge/src/iter/list_range.rs +433 -0
  70. data/vendor/automerge-rust/automerge/src/iter/map_range.rs +316 -0
  71. data/vendor/automerge-rust/automerge/src/iter/spans.rs +601 -0
  72. data/vendor/automerge-rust/automerge/src/iter/tools.rs +427 -0
  73. data/vendor/automerge-rust/automerge/src/iter/values.rs +36 -0
  74. data/vendor/automerge-rust/automerge/src/iter.rs +25 -0
  75. data/vendor/automerge-rust/automerge/src/legacy/mod.rs +364 -0
  76. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/actor_id.rs +25 -0
  77. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/change_hash.rs +29 -0
  78. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/element_id.rs +27 -0
  79. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/mod.rs +31 -0
  80. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/object_id.rs +36 -0
  81. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op.rs +668 -0
  82. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op_type.rs +26 -0
  83. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/opid.rs +25 -0
  84. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/scalar_value.rs +63 -0
  85. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/element_id.rs +66 -0
  86. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/key.rs +49 -0
  87. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/mod.rs +4 -0
  88. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/object_id.rs +74 -0
  89. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/opid.rs +68 -0
  90. data/vendor/automerge-rust/automerge/src/lib.rs +315 -0
  91. data/vendor/automerge-rust/automerge/src/marks.rs +478 -0
  92. data/vendor/automerge-rust/automerge/src/op_set2/change/batch.rs +2002 -0
  93. data/vendor/automerge-rust/automerge/src/op_set2/change/collector.rs +974 -0
  94. data/vendor/automerge-rust/automerge/src/op_set2/change.rs +332 -0
  95. data/vendor/automerge-rust/automerge/src/op_set2/columns.rs +714 -0
  96. data/vendor/automerge-rust/automerge/src/op_set2/meta.rs +174 -0
  97. data/vendor/automerge-rust/automerge/src/op_set2/op.rs +1363 -0
  98. data/vendor/automerge-rust/automerge/src/op_set2/op_set/elems.rs +43 -0
  99. data/vendor/automerge-rust/automerge/src/op_set2/op_set/found_op.rs +60 -0
  100. data/vendor/automerge-rust/automerge/src/op_set2/op_set/index.rs +197 -0
  101. data/vendor/automerge-rust/automerge/src/op_set2/op_set/insert.rs +179 -0
  102. data/vendor/automerge-rust/automerge/src/op_set2/op_set/mark_index.rs +292 -0
  103. data/vendor/automerge-rust/automerge/src/op_set2/op_set/marks.rs +86 -0
  104. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_iter.rs +1295 -0
  105. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_query.rs +82 -0
  106. data/vendor/automerge-rust/automerge/src/op_set2/op_set/top_op.rs +50 -0
  107. data/vendor/automerge-rust/automerge/src/op_set2/op_set/visible.rs +290 -0
  108. data/vendor/automerge-rust/automerge/src/op_set2/op_set.rs +1793 -0
  109. data/vendor/automerge-rust/automerge/src/op_set2/parents.rs +133 -0
  110. data/vendor/automerge-rust/automerge/src/op_set2/skip_list.rs +714 -0
  111. data/vendor/automerge-rust/automerge/src/op_set2/types.rs +769 -0
  112. data/vendor/automerge-rust/automerge/src/op_set2.rs +18 -0
  113. data/vendor/automerge-rust/automerge/src/patches/patch.rs +95 -0
  114. data/vendor/automerge-rust/automerge/src/patches/patch_builder.rs +382 -0
  115. data/vendor/automerge-rust/automerge/src/patches/patch_log.rs +584 -0
  116. data/vendor/automerge-rust/automerge/src/patches.rs +7 -0
  117. data/vendor/automerge-rust/automerge/src/query/list_state.rs +230 -0
  118. data/vendor/automerge-rust/automerge/src/query/seek_mark.rs +142 -0
  119. data/vendor/automerge-rust/automerge/src/read.rs +326 -0
  120. data/vendor/automerge-rust/automerge/src/sequence_tree.rs +662 -0
  121. data/vendor/automerge-rust/automerge/src/storage/bundle/builder.rs +942 -0
  122. data/vendor/automerge-rust/automerge/src/storage/bundle/error.rs +42 -0
  123. data/vendor/automerge-rust/automerge/src/storage/bundle/meta.rs +23 -0
  124. data/vendor/automerge-rust/automerge/src/storage/bundle/storage.rs +146 -0
  125. data/vendor/automerge-rust/automerge/src/storage/bundle.rs +210 -0
  126. data/vendor/automerge-rust/automerge/src/storage/change/change_actors.rs +311 -0
  127. data/vendor/automerge-rust/automerge/src/storage/change/change_op_columns.rs +621 -0
  128. data/vendor/automerge-rust/automerge/src/storage/change/compressed.rs +51 -0
  129. data/vendor/automerge-rust/automerge/src/storage/change/op_with_change_actors.rs +1 -0
  130. data/vendor/automerge-rust/automerge/src/storage/change.rs +523 -0
  131. data/vendor/automerge-rust/automerge/src/storage/chunk.rs +312 -0
  132. data/vendor/automerge-rust/automerge/src/storage/columns/column.rs +42 -0
  133. data/vendor/automerge-rust/automerge/src/storage/columns/column_builder.rs +199 -0
  134. data/vendor/automerge-rust/automerge/src/storage/columns/column_specification.rs +340 -0
  135. data/vendor/automerge-rust/automerge/src/storage/columns/raw_column.rs +286 -0
  136. data/vendor/automerge-rust/automerge/src/storage/columns.rs +355 -0
  137. data/vendor/automerge-rust/automerge/src/storage/document/compression.rs +362 -0
  138. data/vendor/automerge-rust/automerge/src/storage/document.rs +411 -0
  139. data/vendor/automerge-rust/automerge/src/storage/load/change_collector.rs +15 -0
  140. data/vendor/automerge-rust/automerge/src/storage/load.rs +136 -0
  141. data/vendor/automerge-rust/automerge/src/storage/parse/leb128.rs +302 -0
  142. data/vendor/automerge-rust/automerge/src/storage/parse.rs +619 -0
  143. data/vendor/automerge-rust/automerge/src/storage/save/document.rs +27 -0
  144. data/vendor/automerge-rust/automerge/src/storage.rs +26 -0
  145. data/vendor/automerge-rust/automerge/src/sync/bloom.rs +161 -0
  146. data/vendor/automerge-rust/automerge/src/sync/message_builder.rs +118 -0
  147. data/vendor/automerge-rust/automerge/src/sync/state.rs +214 -0
  148. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/bloom.rs +162 -0
  149. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/mod.rs +625 -0
  150. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/state.rs +120 -0
  151. data/vendor/automerge-rust/automerge/src/sync.rs +2482 -0
  152. data/vendor/automerge-rust/automerge/src/text_diff/LICENSE +201 -0
  153. data/vendor/automerge-rust/automerge/src/text_diff/myers.rs +332 -0
  154. data/vendor/automerge-rust/automerge/src/text_diff/replace.rs +139 -0
  155. data/vendor/automerge-rust/automerge/src/text_diff/utils.rs +119 -0
  156. data/vendor/automerge-rust/automerge/src/text_diff.rs +515 -0
  157. data/vendor/automerge-rust/automerge/src/text_value.rs +276 -0
  158. data/vendor/automerge-rust/automerge/src/transaction/commit.rs +34 -0
  159. data/vendor/automerge-rust/automerge/src/transaction/inner.rs +1403 -0
  160. data/vendor/automerge-rust/automerge/src/transaction/manual_transaction.rs +147 -0
  161. data/vendor/automerge-rust/automerge/src/transaction/owned_transaction.rs +266 -0
  162. data/vendor/automerge-rust/automerge/src/transaction/result.rs +21 -0
  163. data/vendor/automerge-rust/automerge/src/transaction/transactable.rs +203 -0
  164. data/vendor/automerge-rust/automerge/src/transaction.rs +513 -0
  165. data/vendor/automerge-rust/automerge/src/types.rs +749 -0
  166. data/vendor/automerge-rust/automerge/src/validation.rs +29 -0
  167. data/vendor/automerge-rust/automerge/src/value.rs +763 -0
  168. data/vendor/automerge-rust/automerge/tests/batch_insert.rs +1034 -0
  169. data/vendor/automerge-rust/automerge/tests/block_tests.rs +887 -0
  170. data/vendor/automerge-rust/automerge/tests/convert_string_to_text.rs +72 -0
  171. data/vendor/automerge-rust/automerge/tests/diff_marks.rs +1508 -0
  172. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_change.automerge +0 -0
  173. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_doc.automerge +0 -0
  174. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_has_incorrect_meta.automerge +0 -0
  175. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_ok.automerge +0 -0
  176. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_overlong.automerge +0 -0
  177. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks.automerge +0 -0
  178. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_compressed.automerge +0 -0
  179. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_out_of_order.automerge +0 -0
  180. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/action-is-48.automerge +0 -0
  181. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709 +0 -0
  182. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/incorrect_max_op.automerge +0 -0
  183. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/invalid_deflate_stream.automerge +0 -0
  184. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/missing_actor.automerge +0 -0
  185. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/overflow_in_length.automerge +0 -0
  186. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_deps.automerge +0 -0
  187. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_ops.automerge +0 -0
  188. data/vendor/automerge-rust/automerge/tests/test.rs +2668 -0
  189. data/vendor/automerge-rust/automerge/tests/test_mark_patches.rs +41 -0
  190. data/vendor/automerge-rust/automerge/tests/test_save_load_orphans.rs +84 -0
  191. data/vendor/automerge-rust/automerge/tests/text.rs +1098 -0
  192. data/vendor/automerge-rust/automerge/tests/text_encoding.rs +640 -0
  193. data/vendor/automerge-rust/automerge-c/CMakeLists.txt +439 -0
  194. data/vendor/automerge-rust/automerge-c/Cargo.toml +22 -0
  195. data/vendor/automerge-rust/automerge-c/README.md +233 -0
  196. data/vendor/automerge-rust/automerge-c/build.rs +21 -0
  197. data/vendor/automerge-rust/automerge-c/cbindgen.toml +48 -0
  198. data/vendor/automerge-rust/automerge-c/cmake/Cargo.toml.in +22 -0
  199. data/vendor/automerge-rust/automerge-c/cmake/automerge-c-config.cmake.in +99 -0
  200. data/vendor/automerge-rust/automerge-c/cmake/cbindgen.toml.in +48 -0
  201. data/vendor/automerge-rust/automerge-c/cmake/config.h.in +58 -0
  202. data/vendor/automerge-rust/automerge-c/cmake/enum-string-functions-gen.cmake +183 -0
  203. data/vendor/automerge-rust/automerge-c/cmake/file-regex-replace.cmake +33 -0
  204. data/vendor/automerge-rust/automerge-c/cmake/file-touch.cmake +35 -0
  205. data/vendor/automerge-rust/automerge-c/docs/CMakeLists.txt +39 -0
  206. data/vendor/automerge-rust/automerge-c/docs/img/brandmark.png +0 -0
  207. data/vendor/automerge-rust/automerge-c/examples/CMakeLists.txt +42 -0
  208. data/vendor/automerge-rust/automerge-c/examples/README.md +9 -0
  209. data/vendor/automerge-rust/automerge-c/examples/quickstart.c +131 -0
  210. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/result.h +30 -0
  211. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack.h +130 -0
  212. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack_callback_data.h +53 -0
  213. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/string.h +29 -0
  214. data/vendor/automerge-rust/automerge-c/src/actor_id.rs +193 -0
  215. data/vendor/automerge-rust/automerge-c/src/byte_span.rs +227 -0
  216. data/vendor/automerge-rust/automerge-c/src/change.rs +356 -0
  217. data/vendor/automerge-rust/automerge-c/src/cursor.rs +168 -0
  218. data/vendor/automerge-rust/automerge-c/src/doc/list.rs +636 -0
  219. data/vendor/automerge-rust/automerge-c/src/doc/map.rs +556 -0
  220. data/vendor/automerge-rust/automerge-c/src/doc/mark.rs +296 -0
  221. data/vendor/automerge-rust/automerge-c/src/doc/utils.rs +46 -0
  222. data/vendor/automerge-rust/automerge-c/src/doc.rs +1009 -0
  223. data/vendor/automerge-rust/automerge-c/src/index.rs +84 -0
  224. data/vendor/automerge-rust/automerge-c/src/item.rs +2177 -0
  225. data/vendor/automerge-rust/automerge-c/src/items.rs +401 -0
  226. data/vendor/automerge-rust/automerge-c/src/lib.rs +11 -0
  227. data/vendor/automerge-rust/automerge-c/src/obj.rs +216 -0
  228. data/vendor/automerge-rust/automerge-c/src/result.rs +653 -0
  229. data/vendor/automerge-rust/automerge-c/src/sync/have.rs +42 -0
  230. data/vendor/automerge-rust/automerge-c/src/sync/message.rs +146 -0
  231. data/vendor/automerge-rust/automerge-c/src/sync/state.rs +262 -0
  232. data/vendor/automerge-rust/automerge-c/src/sync.rs +7 -0
  233. data/vendor/automerge-rust/automerge-c/src/utils/result.c +33 -0
  234. data/vendor/automerge-rust/automerge-c/src/utils/stack.c +106 -0
  235. data/vendor/automerge-rust/automerge-c/src/utils/stack_callback_data.c +9 -0
  236. data/vendor/automerge-rust/automerge-c/src/utils/string.c +46 -0
  237. data/vendor/automerge-rust/automerge-c/test/CMakeLists.txt +67 -0
  238. data/vendor/automerge-rust/automerge-c/test/actor_id_tests.c +140 -0
  239. data/vendor/automerge-rust/automerge-c/test/base_state.c +17 -0
  240. data/vendor/automerge-rust/automerge-c/test/base_state.h +39 -0
  241. data/vendor/automerge-rust/automerge-c/test/byte_span_tests.c +119 -0
  242. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.c +91 -0
  243. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.h +42 -0
  244. data/vendor/automerge-rust/automerge-c/test/cursor_tests.c +263 -0
  245. data/vendor/automerge-rust/automerge-c/test/doc_state.c +27 -0
  246. data/vendor/automerge-rust/automerge-c/test/doc_state.h +17 -0
  247. data/vendor/automerge-rust/automerge-c/test/doc_tests.c +335 -0
  248. data/vendor/automerge-rust/automerge-c/test/enum_string_tests.c +148 -0
  249. data/vendor/automerge-rust/automerge-c/test/files/brave-ape-49.automerge +0 -0
  250. data/vendor/automerge-rust/automerge-c/test/item_tests.c +313 -0
  251. data/vendor/automerge-rust/automerge-c/test/list_tests.c +544 -0
  252. data/vendor/automerge-rust/automerge-c/test/macro_utils.c +38 -0
  253. data/vendor/automerge-rust/automerge-c/test/macro_utils.h +23 -0
  254. data/vendor/automerge-rust/automerge-c/test/main.c +33 -0
  255. data/vendor/automerge-rust/automerge-c/test/map_tests.c +1610 -0
  256. data/vendor/automerge-rust/automerge-c/test/mark_tests.c +124 -0
  257. data/vendor/automerge-rust/automerge-c/test/ported_wasm/basic_tests.c +1642 -0
  258. data/vendor/automerge-rust/automerge-c/test/ported_wasm/cursor_tests.c +108 -0
  259. data/vendor/automerge-rust/automerge-c/test/ported_wasm/suite.c +17 -0
  260. data/vendor/automerge-rust/automerge-c/test/ported_wasm/sync_tests.c +1280 -0
  261. data/vendor/automerge-rust/automerge-c/test/str_utils.c +15 -0
  262. data/vendor/automerge-rust/automerge-c/test/str_utils.h +17 -0
  263. data/vendor/automerge-rust/automerge-test/Cargo.toml +17 -0
  264. data/vendor/automerge-rust/automerge-test/README.md +3 -0
  265. data/vendor/automerge-rust/automerge-test/src/lib.rs +487 -0
  266. data/vendor/automerge-rust/hexane/CHANGELOG.md +34 -0
  267. data/vendor/automerge-rust/hexane/Cargo.toml +47 -0
  268. data/vendor/automerge-rust/hexane/README.md +292 -0
  269. data/vendor/automerge-rust/hexane/RESULTS.txt +20 -0
  270. data/vendor/automerge-rust/hexane/TODO +18 -0
  271. data/vendor/automerge-rust/hexane/benches/insert.rs +82 -0
  272. data/vendor/automerge-rust/hexane/benches/seek.rs +77 -0
  273. data/vendor/automerge-rust/hexane/benches/splice.rs +82 -0
  274. data/vendor/automerge-rust/hexane/src/aggregate.rs +288 -0
  275. data/vendor/automerge-rust/hexane/src/boolean.rs +478 -0
  276. data/vendor/automerge-rust/hexane/src/columndata.rs +2540 -0
  277. data/vendor/automerge-rust/hexane/src/cursor.rs +756 -0
  278. data/vendor/automerge-rust/hexane/src/delta.rs +793 -0
  279. data/vendor/automerge-rust/hexane/src/encoder.rs +639 -0
  280. data/vendor/automerge-rust/hexane/src/leb128.rs +82 -0
  281. data/vendor/automerge-rust/hexane/src/lib.rs +95 -0
  282. data/vendor/automerge-rust/hexane/src/pack.rs +325 -0
  283. data/vendor/automerge-rust/hexane/src/raw.rs +314 -0
  284. data/vendor/automerge-rust/hexane/src/rle.rs +928 -0
  285. data/vendor/automerge-rust/hexane/src/slab/tree.rs +1373 -0
  286. data/vendor/automerge-rust/hexane/src/slab/writer.rs +535 -0
  287. data/vendor/automerge-rust/hexane/src/slab.rs +224 -0
  288. data/vendor/automerge-rust/hexane/src/test.rs +108 -0
  289. data/vendor/bundle/ruby/3.3.0/bin/rake +29 -0
  290. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler +29 -0
  291. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler-dock +29 -0
  292. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/History.rdoc +1732 -0
  293. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Manifest.txt +32 -0
  294. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/README.rdoc +845 -0
  295. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Rakefile +97 -0
  296. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/design_rationale.rb +54 -0
  297. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/hoe/minitest.rb +30 -0
  298. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/assertions.rb +850 -0
  299. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/autorun.rb +6 -0
  300. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/benchmark.rb +452 -0
  301. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/compress.rb +94 -0
  302. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/error_on_warning.rb +11 -0
  303. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/expectations.rb +321 -0
  304. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/hell.rb +11 -0
  305. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/manual_plugins.rb +16 -0
  306. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/mock.rb +327 -0
  307. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/parallel.rb +72 -0
  308. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride.rb +4 -0
  309. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride_plugin.rb +135 -0
  310. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/spec.rb +353 -0
  311. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test.rb +238 -0
  312. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test_task.rb +324 -0
  313. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/unit.rb +42 -0
  314. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest.rb +1250 -0
  315. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/metametameta.rb +150 -0
  316. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_assertions.rb +1677 -0
  317. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_benchmark.rb +137 -0
  318. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_mock.rb +1213 -0
  319. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_reporter.rb +437 -0
  320. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_spec.rb +1159 -0
  321. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test.rb +1374 -0
  322. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test_task.rb +57 -0
  323. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/History.rdoc +2454 -0
  324. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
  325. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/README.rdoc +155 -0
  326. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/command_line_usage.rdoc +171 -0
  327. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile1 +38 -0
  328. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile2 +35 -0
  329. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/a.c +6 -0
  330. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/b.c +6 -0
  331. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/main.c +11 -0
  332. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/glossary.rdoc +42 -0
  333. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/jamis.rb +592 -0
  334. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/proto_rake.rdoc +127 -0
  335. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rake.1 +156 -0
  336. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rakefile.rdoc +635 -0
  337. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rational.rdoc +151 -0
  338. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/exe/rake +27 -0
  339. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/application.rb +847 -0
  340. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/backtrace.rb +25 -0
  341. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/clean.rb +78 -0
  342. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cloneable.rb +17 -0
  343. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb +122 -0
  344. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/default_loader.rb +15 -0
  345. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb +196 -0
  346. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/early_time.rb +22 -0
  347. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/core.rb +26 -0
  348. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/string.rb +176 -0
  349. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb +25 -0
  350. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_list.rb +435 -0
  351. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_task.rb +58 -0
  352. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils.rb +137 -0
  353. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb +135 -0
  354. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb +57 -0
  355. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb +17 -0
  356. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/late_time.rb +18 -0
  357. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/linked_list.rb +112 -0
  358. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb +54 -0
  359. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/multi_task.rb +14 -0
  360. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/name_space.rb +38 -0
  361. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/options.rb +31 -0
  362. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/packagetask.rb +222 -0
  363. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/phony.rb +16 -0
  364. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/private_reader.rb +21 -0
  365. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/promise.rb +100 -0
  366. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb +30 -0
  367. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_module.rb +67 -0
  368. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb +27 -0
  369. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  370. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/scope.rb +43 -0
  371. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task.rb +434 -0
  372. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb +8 -0
  373. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_arguments.rb +113 -0
  374. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_manager.rb +333 -0
  375. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/tasklib.rb +12 -0
  376. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/testtask.rb +192 -0
  377. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb +49 -0
  378. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_pool.rb +157 -0
  379. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/trace_output.rb +23 -0
  380. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/version.rb +10 -0
  381. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/win32.rb +17 -0
  382. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake.rb +69 -0
  383. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/rake.gemspec +102 -0
  384. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Gemfile +8 -0
  385. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/History.md +695 -0
  386. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/LICENSE.txt +20 -0
  387. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/README.md +476 -0
  388. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Rakefile +15 -0
  389. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/appveyor.yml +22 -0
  390. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/bin/rake-compiler +24 -0
  391. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/cucumber.yml +4 -0
  392. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/compile.feature +79 -0
  393. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-compile.feature +23 -0
  394. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package-multi.feature +15 -0
  395. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package.feature +14 -0
  396. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-compile.feature +22 -0
  397. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-no-native-compile.feature +33 -0
  398. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-package.feature +24 -0
  399. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/package.feature +40 -0
  400. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/compilation.rb +70 -0
  401. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/cross_compilation.rb +27 -0
  402. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/execution.rb +52 -0
  403. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/folders.rb +32 -0
  404. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/gem.rb +46 -0
  405. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/java_compilation.rb +7 -0
  406. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/env.rb +10 -0
  407. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/file_template_helpers.rb +137 -0
  408. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/generator_helpers.rb +123 -0
  409. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/platform_extension_helpers.rb +27 -0
  410. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/baseextensiontask.rb +90 -0
  411. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/compiler_config.rb +38 -0
  412. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensioncompiler.rb +51 -0
  413. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensiontask.rb +589 -0
  414. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/javaextensiontask.rb +321 -0
  415. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bin/cross-ruby.rake +189 -0
  416. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bootstrap.rake +11 -0
  417. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/common.rake +10 -0
  418. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/cucumber.rake +23 -0
  419. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/gem.rake +15 -0
  420. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/rspec.rake +9 -0
  421. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CHANGELOG.md +446 -0
  422. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CONTRIBUTING.md +109 -0
  423. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.jruby +79 -0
  424. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.mri.erb +282 -0
  425. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Gemfile +8 -0
  426. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/LICENSE.txt +22 -0
  427. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/README.md +447 -0
  428. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Rakefile +246 -0
  429. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/bin/rake-compiler-dock +18 -0
  430. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/buildkitd.toml +2 -0
  431. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/gem_helper.rb +54 -0
  432. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_i686.rb +18 -0
  433. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_musl_cross.sh +37 -0
  434. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_osxcross.sh +45 -0
  435. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_pkg_config.sh +24 -0
  436. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/parallel_docker_build.rb +169 -0
  437. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0004-Enable-build-of-static-libruby.patch +38 -0
  438. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0005-build-miniruby-first.patch +16 -0
  439. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0006-ruby-4-rubyspec-capiext.patch +16 -0
  440. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/rcd-env.sh +6 -0
  441. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/runas +7 -0
  442. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sigfw.c +45 -0
  443. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_codesign +17 -0
  444. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_vbox +30 -0
  445. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sudoers +1 -0
  446. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/colors.rb +43 -0
  447. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/docker_check.rb +356 -0
  448. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
  449. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/starter.rb +206 -0
  450. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/version.rb +4 -0
  451. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock.rb +151 -0
  452. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/Dockerfile +66 -0
  453. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/README.md +14 -0
  454. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/binutils-mingw-w64-ignore-check-errors.patch +13 -0
  455. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/gcc-mingw-w64-only-c-c++.patch +13 -0
  456. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/mingw-w64-enable-ucrt.patch +22 -0
  457. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/rake-compiler-dock.gemspec +34 -0
  458. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.alpine +17 -0
  459. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.debian +24 -0
  460. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/fixtures/mig_test_rpc.defs +8 -0
  461. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Gemfile +11 -0
  462. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Rakefile +97 -0
  463. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RcdTestExtService.java +19 -0
  464. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RubyRcdTest.java +16 -0
  465. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/extconf.rb +111 -0
  466. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.c +65 -0
  467. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.h +11 -0
  468. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/lib/rcd_test.rb +6 -0
  469. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/rcd_test.gemspec +28 -0
  470. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/test/test_basic.rb +49 -0
  471. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_environment_variables.rb +108 -0
  472. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_mig.rb +18 -0
  473. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_parallel_docker_build.rb +95 -0
  474. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_rubygems_plugins.rb +12 -0
  475. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_starter.rb +158 -0
  476. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_versions.rb +82 -0
  477. data/vendor/bundle/ruby/3.3.0/specifications/minitest-5.27.0.gemspec +32 -0
  478. data/vendor/bundle/ruby/3.3.0/specifications/rake-13.4.2.gemspec +26 -0
  479. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-1.3.1.gemspec +33 -0
  480. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-dock-1.12.0.gemspec +28 -0
  481. metadata +584 -0
@@ -0,0 +1,2002 @@
1
+ use crate::hydrate::Value;
2
+ use crate::iter::RichTextDiff;
3
+ use crate::op_set2::types::{Action, KeyRef, MarkData, PropRef};
4
+ use crate::op_set2::SuccInsert;
5
+ use crate::types::{
6
+ ActorId, ElemId, ObjId, ObjType, OpId, Prop, ScalarValue, SequenceType, SmallHashMap,
7
+ };
8
+ use crate::{Automerge, Change, ChangeHash, PatchLog, PatchLogMismatch};
9
+ use crate::{AutomergeError, TextEncoding};
10
+
11
+ use super::super::op::{ChangeOp, Op, OpBuilder};
12
+ use super::super::op_set::{ObjIdIter, ObjIndex, OpIter, OpSet};
13
+
14
+ use std::borrow::Cow;
15
+ use std::cmp::Ordering;
16
+ use std::collections::{HashMap, HashSet, VecDeque};
17
+ use std::ops::Range;
18
+
19
+ type PredCache = SmallHashMap<OpId, Vec<(OpId, Option<i64>)>>;
20
+
21
+ #[derive(Debug, Clone, Default)]
22
+ struct BatchApply {
23
+ ops: Vec<ChangeOp>,
24
+ changes: Vec<Change>,
25
+ actor_seq: HashMap<ActorId, HashSet<u64>>,
26
+ hashes: HashSet<ChangeHash>,
27
+ pred: PredCache,
28
+ obj_spans: Vec<ObjSpan>,
29
+ }
30
+
31
+ struct Untangler<'a> {
32
+ // the tangle of change ops we need to navigate
33
+ change_ops: &'a mut [ChangeOp],
34
+ // these are entry points into the change_op tangle
35
+ // when we see a doc_op.id equal to key, put this vec onto the stack
36
+ // ops inserted after HEAD are put onto the stack immidately
37
+ entry: SmallHashMap<OpId, Vec<usize>>,
38
+ // same concept as entry but internal to the change_ops array
39
+ gosub: SmallHashMap<usize, Vec<usize>>,
40
+ // stack of change ops ready to be processed
41
+ stack: Vec<usize>,
42
+ // these are change ops updating a pre-existing doc op elemid's
43
+ // and are handled differently than inserts
44
+ updates: SmallHashMap<ElemId, Vec<usize>>,
45
+ updates_stack: Vec<usize>,
46
+ pred: &'a mut PredCache,
47
+ // Top and Conflicts keep track of changes that need to
48
+ // be made to the index.top and index.visible columns
49
+ top: Top,
50
+ conflicts: &'a mut Vec<Adjust>,
51
+ value: ValueState<'a>,
52
+ seq_type: SequenceType,
53
+ text_encoding: TextEncoding,
54
+ count: usize,
55
+ index: usize,
56
+ max: usize,
57
+ width: usize,
58
+ }
59
+
60
+ impl<'a> Untangler<'a> {
61
+ fn flush(&mut self, log: &mut PatchLog) {
62
+ self.value.list_flush(self.index, log);
63
+ self.top.reset(self.conflicts);
64
+ self.index += self.width;
65
+ self.width = 0;
66
+ }
67
+
68
+ fn handle_doc_op(&mut self, doc_op: &Op<'a>, succ: &mut Vec<SuccInsert>, log: &mut PatchLog) {
69
+ let mut deleted = false;
70
+ if let Some(v) = self.pred.remove(&doc_op.id) {
71
+ for (id, inc) in v {
72
+ deleted |= inc.is_none();
73
+ succ.push(doc_op.add_succ(id, inc));
74
+ }
75
+ }
76
+
77
+ if doc_op.insert {
78
+ self.flush(log);
79
+ self.value.key = Some(PropRef::Seq(self.index));
80
+ }
81
+
82
+ if doc_op.visible() && !deleted {
83
+ self.width = doc_op.width(self.seq_type, self.text_encoding);
84
+ }
85
+ self.value.process_doc_op(doc_op, deleted);
86
+ self.top.process_doc_op(self.change_ops, doc_op, deleted);
87
+ }
88
+
89
+ fn element_update(&mut self, doc_op: &Op<'_>) {
90
+ while let Some(last) = self.updates_stack.last().copied() {
91
+ if doc_op.insert || doc_op.id > self.change_ops[last].id() {
92
+ self.updates_stack.pop();
93
+ self.change_ops[last].pos = Some(doc_op.pos);
94
+ self.change_ops[last].subsort = self.count;
95
+ if self.change_ops[last].visible() {
96
+ self.width = self.change_ops[last].width(self.seq_type, self.text_encoding);
97
+ }
98
+ self.value.process_change_op(&self.change_ops[last]);
99
+ self.count += 1;
100
+ self.top
101
+ .process_change_op(self.conflicts, self.change_ops, last);
102
+ } else {
103
+ break;
104
+ }
105
+ }
106
+ }
107
+
108
+ fn finish_updates(&mut self) {
109
+ for i in self.updates_stack.iter().rev() {
110
+ self.change_ops[*i].pos = Some(self.max);
111
+ self.change_ops[*i].subsort = self.count;
112
+ self.width = 0;
113
+ if self.change_ops[*i].visible() {
114
+ self.width = self.change_ops[*i].width(self.seq_type, self.text_encoding);
115
+ }
116
+ self.value.process_change_op(&self.change_ops[*i]);
117
+
118
+ self.top
119
+ .process_change_op(self.conflicts, self.change_ops, *i);
120
+
121
+ self.count += 1;
122
+ }
123
+ }
124
+
125
+ fn finish_inserts(&mut self, log: &mut PatchLog) {
126
+ while !self.stack.is_empty() {
127
+ self.untangle_inner(self.max, log);
128
+ }
129
+ }
130
+
131
+ fn finish(mut self, log: &mut PatchLog) {
132
+ self.finish_updates();
133
+
134
+ self.flush(log);
135
+
136
+ assert!(self.entry.is_empty());
137
+
138
+ self.finish_inserts(log);
139
+
140
+ self.flush(log);
141
+
142
+ assert_eq!(self.top, Top::Nothing);
143
+
144
+ self.change_ops.sort_by(|a, b| {
145
+ a.pos
146
+ .unwrap()
147
+ .cmp(&b.pos.unwrap())
148
+ .then_with(|| a.subsort.cmp(&b.subsort))
149
+ });
150
+ }
151
+
152
+ fn untangle_inserts(&mut self, id: OpId, insert_pos: usize, log: &mut PatchLog) {
153
+ self.flush(log);
154
+
155
+ if let Err(n) = self
156
+ .stack
157
+ .binary_search_by(|n| self.change_ops[*n].id().cmp(&id))
158
+ {
159
+ while self.stack.len() > n {
160
+ self.untangle_inner(insert_pos, log);
161
+ }
162
+ }
163
+ if let Some(v) = self.entry.remove(&id) {
164
+ self.stack.extend(v);
165
+ }
166
+ if let Some(u) = self.updates.get(&ElemId(id)) {
167
+ self.updates_stack.extend(u.iter().rev());
168
+ }
169
+ }
170
+
171
+ fn untangle_inner(&mut self, insert_pos: usize, log: &mut PatchLog) -> Option<()> {
172
+ let mut pos = self.stack.pop()?;
173
+ let op = self.change_ops.get_mut(pos)?;
174
+
175
+ let mut conflict = false;
176
+ let mut vis = None;
177
+
178
+ let key = KeyRef::Seq(ElemId(op.id()));
179
+
180
+ assert!(op.pos.is_none());
181
+ op.pos = Some(insert_pos);
182
+ op.subsort = self.count;
183
+ self.count += 1;
184
+
185
+ if op.is_set_or_make() && !op.has_succ() {
186
+ vis = Some(pos);
187
+ } else if op.action() == Action::Mark {
188
+ self.value.process_mark(op.id(), op.mark_data());
189
+ }
190
+
191
+ if let Some(v) = self.gosub.get(&pos) {
192
+ self.stack.extend(v);
193
+ }
194
+
195
+ for i in (pos + 1)..self.change_ops.len() {
196
+ let next_vis = {
197
+ let next_op = &mut self.change_ops[i];
198
+
199
+ pos += 1;
200
+
201
+ if next_op.insert() || next_op.key() != &key {
202
+ break;
203
+ }
204
+
205
+ next_op.pos = Some(insert_pos);
206
+ next_op.subsort = self.count;
207
+ self.count += 1;
208
+
209
+ next_op.is_set_or_make() && !next_op.has_succ()
210
+ };
211
+
212
+ if next_vis {
213
+ // borrow checker stuff
214
+ if let Some(conflict_pos) = vis {
215
+ self.change_ops[conflict_pos].conflicted = true;
216
+ conflict = true;
217
+ }
218
+ vis = Some(pos);
219
+ }
220
+ }
221
+
222
+ if let Some(p) = vis {
223
+ let op = &mut self.change_ops[p];
224
+ if self.seq_type == SequenceType::List {
225
+ let value = op.hydrate_value_and_fix_counters(self.text_encoding);
226
+ log.insert(op.bld.obj, self.index, value, op.id(), conflict);
227
+ self.index += 1;
228
+ } else {
229
+ let marks = self.value.marks.after.current().cloned();
230
+ match op.bld.action {
231
+ Action::MakeMap => {
232
+ // Block markers
233
+ log.insert(
234
+ op.bld.obj,
235
+ self.index,
236
+ Value::map(),
237
+ op.bld.id,
238
+ op.conflicted,
239
+ );
240
+ }
241
+ _ => {
242
+ log.splice(op.bld.obj, self.index, op.bld.as_str(), marks);
243
+ }
244
+ }
245
+ self.index += op.width(self.seq_type, self.text_encoding);
246
+ }
247
+ }
248
+
249
+ Some(())
250
+ }
251
+
252
+ fn new(
253
+ obj: ObjId,
254
+ encoding: SequenceType,
255
+ text_encoding: TextEncoding,
256
+ conflicts: &'a mut Vec<Adjust>,
257
+ change_ops: &'a mut [ChangeOp],
258
+ pred: &'a mut PredCache,
259
+ max: usize,
260
+ ) -> Self {
261
+ let mut e_to_i = SmallHashMap::default();
262
+ let mut gosub: SmallHashMap<usize, Vec<usize>> = HashMap::default();
263
+ let mut entry: SmallHashMap<OpId, Vec<usize>> = HashMap::default();
264
+ let mut stack: Vec<usize> = Vec::with_capacity(change_ops.len());
265
+ let mut updates: SmallHashMap<ElemId, Vec<usize>> = HashMap::default();
266
+ let mut last_e = None;
267
+ let value = ValueState::new(obj, encoding, text_encoding);
268
+ for (i, op) in change_ops.iter_mut().enumerate() {
269
+ if let Some(v) = pred.remove(&op.id()) {
270
+ op.succ = v;
271
+ }
272
+ if let KeyRef::Seq(e) = op.key() {
273
+ if op.insert() {
274
+ if let Some(j) = e_to_i.get(e) {
275
+ gosub.entry(*j).or_default().push(i);
276
+ } else if e.is_head() {
277
+ stack.push(i);
278
+ } else {
279
+ entry.entry(e.0).or_default().push(i);
280
+ }
281
+ } else if last_e != Some(*e) {
282
+ updates.entry(*e).or_default().push(i);
283
+ }
284
+ if op.insert() {
285
+ let this_e = ElemId(op.id());
286
+ e_to_i.insert(this_e, i);
287
+ last_e = Some(this_e);
288
+ }
289
+ }
290
+ }
291
+ let updates_stack = Vec::with_capacity(change_ops.len());
292
+ Self {
293
+ gosub,
294
+ entry,
295
+ stack,
296
+ pred,
297
+ change_ops,
298
+ updates,
299
+ seq_type: encoding,
300
+ text_encoding,
301
+ conflicts,
302
+ updates_stack,
303
+ top: Top::Nothing,
304
+ count: 0,
305
+ index: 0,
306
+ width: 0,
307
+ value,
308
+ max,
309
+ }
310
+ }
311
+ }
312
+
313
+ fn walk_list<'a>(
314
+ mut ut: Untangler<'a>,
315
+ doc_ops: OpIter<'a>,
316
+ succ: &mut Vec<SuccInsert>,
317
+ log: &mut PatchLog,
318
+ ) {
319
+ for op in doc_ops {
320
+ ut.element_update(&op);
321
+
322
+ if op.insert {
323
+ ut.untangle_inserts(op.id, op.pos, log);
324
+ }
325
+
326
+ ut.handle_doc_op(&op, succ, log);
327
+ }
328
+
329
+ ut.finish(log);
330
+ }
331
+
332
+ struct MapWalker<'a, 'b> {
333
+ ops: OpIter<'a>,
334
+ log: &'b mut PatchLog,
335
+ pred: &'b mut PredCache,
336
+ succ: &'b mut Vec<SuccInsert>,
337
+ value: ValueState<'a>,
338
+ pos: usize,
339
+ doc_op: Option<Op<'a>>,
340
+ conflicts: &'b mut Vec<Adjust>,
341
+ top: Top,
342
+ }
343
+
344
+ #[derive(Debug, Clone)]
345
+ enum Adjust {
346
+ Conflict(usize),
347
+ Expose(usize),
348
+ }
349
+
350
+ #[derive(PartialEq, Debug)]
351
+ enum Top {
352
+ Nothing,
353
+ ChangeIndex(usize),
354
+ Doc(usize),
355
+ Expose(usize),
356
+ }
357
+
358
+ impl Top {
359
+ fn reset(&mut self, conflicts: &mut Vec<Adjust>) {
360
+ if let Top::Expose(i) = self {
361
+ conflicts.push(Adjust::Expose(*i));
362
+ }
363
+ *self = Top::Nothing;
364
+ }
365
+
366
+ fn process_doc_op(&mut self, ops: &mut [ChangeOp], d: &Op<'_>, deleted: bool) {
367
+ if d.visible() {
368
+ if deleted {
369
+ if let Top::Doc(i) = self {
370
+ *self = Top::Expose(*i)
371
+ }
372
+ } else {
373
+ if let Top::ChangeIndex(i) = self {
374
+ ops[*i].conflicted = true
375
+ }
376
+ *self = Top::Doc(d.pos);
377
+ }
378
+ }
379
+ }
380
+
381
+ fn process_change_op(&mut self, conflicts: &mut Vec<Adjust>, ops: &mut [ChangeOp], pos: usize) {
382
+ if ops[pos].visible() {
383
+ match self {
384
+ Top::ChangeIndex(i) => ops[*i].conflicted = true,
385
+ Top::Doc(i) => conflicts.push(Adjust::Conflict(*i)),
386
+ _ => {}
387
+ }
388
+ *self = Top::ChangeIndex(pos);
389
+ }
390
+ }
391
+ }
392
+
393
+ impl<'a, 'b> MapWalker<'a, 'b> {
394
+ fn new(
395
+ obj: ObjId,
396
+ mut ops: OpIter<'a>,
397
+ text_encoding: TextEncoding,
398
+ pred: &'b mut PredCache,
399
+ succ: &'b mut Vec<SuccInsert>,
400
+ log: &'b mut PatchLog,
401
+ conflicts: &'b mut Vec<Adjust>,
402
+ ) -> Self {
403
+ let pos = ops.pos();
404
+ let doc_op = ops.next();
405
+ let value = ValueState::new(obj, SequenceType::List, text_encoding);
406
+ let top = Top::Nothing;
407
+ MapWalker {
408
+ ops,
409
+ log,
410
+ pos,
411
+ doc_op,
412
+ pred,
413
+ succ,
414
+ value,
415
+ conflicts,
416
+ top,
417
+ }
418
+ }
419
+
420
+ fn next_doc_op(&mut self) {
421
+ self.pos = self.ops.pos();
422
+ self.doc_op = self.ops.next();
423
+ }
424
+
425
+ fn change_op(&mut self, ops: &mut [ChangeOp], pos: usize) {
426
+ if let Some(v) = self.pred.remove(&ops[pos].id()) {
427
+ ops[pos].succ = v
428
+ }
429
+
430
+ self.advance_doc_op(pos, ops);
431
+
432
+ if ops[pos].prop() != self.value.key {
433
+ self.value.map_flush(self.log);
434
+ self.value.key = ops[pos].prop_static();
435
+ self.top.reset(self.conflicts);
436
+ }
437
+ self.value.process_change_op(&ops[pos]);
438
+
439
+ ops[pos].pos = Some(self.pos);
440
+
441
+ self.top.process_change_op(self.conflicts, ops, pos);
442
+ }
443
+
444
+ fn advance_doc_op(&mut self, pos: usize, ops: &mut [ChangeOp]) {
445
+ while let Some(d) = self.doc_op.as_ref() {
446
+ // TODO - sometimes we can fast forward to the next property
447
+ match d.key.partial_cmp(ops[pos].key()) {
448
+ Some(Ordering::Greater) => break,
449
+ Some(Ordering::Equal) if d.id > ops[pos].id() => break,
450
+ _ => {
451
+ let deleted = process_pred(self.doc_op.as_ref(), self.pred, self.succ);
452
+ if d.prop() != self.value.key {
453
+ self.value.map_flush(self.log);
454
+ self.value.key = d.prop();
455
+ self.top.reset(self.conflicts);
456
+ }
457
+ self.value.process_doc_op(d, deleted);
458
+ self.top.process_doc_op(ops, d, deleted);
459
+ }
460
+ }
461
+ self.next_doc_op();
462
+ }
463
+ }
464
+
465
+ fn finish(&mut self, ops: &mut [ChangeOp]) {
466
+ while let Some(d) = self.doc_op.as_ref() {
467
+ let deleted = process_pred(self.doc_op.as_ref(), self.pred, self.succ);
468
+ if d.prop() == self.value.key {
469
+ self.top.process_doc_op(ops, d, deleted);
470
+ self.value.process_doc_op(d, deleted);
471
+ self.next_doc_op();
472
+ } else {
473
+ break;
474
+ }
475
+ }
476
+ self.value.map_flush(self.log);
477
+ self.top.reset(self.conflicts);
478
+ }
479
+ }
480
+
481
+ fn process_pred(doc_op: Option<&Op<'_>>, pred: &mut PredCache, succ: &mut Vec<SuccInsert>) -> bool {
482
+ if let Some(d) = doc_op {
483
+ let mut deleted = false;
484
+ if let Some(v) = pred.remove(&d.id) {
485
+ for (id, inc) in v {
486
+ deleted |= inc.is_none();
487
+ succ.push(d.add_succ(id, inc));
488
+ }
489
+ }
490
+ deleted
491
+ } else {
492
+ false
493
+ }
494
+ }
495
+
496
+ #[derive(Debug, Clone)]
497
+ struct ValueState<'a> {
498
+ obj: ObjId,
499
+ seq_type: SequenceType,
500
+ text_encoding: TextEncoding,
501
+ key: Option<PropRef<'a>>,
502
+ doc: OpValueOption,
503
+ change: OpValueOption,
504
+ marks: RichTextDiff<'a>,
505
+ }
506
+
507
+ #[derive(Debug, Clone)]
508
+ struct OpValue {
509
+ id: OpId,
510
+ value: Value,
511
+ deleted: bool,
512
+ conflict: bool,
513
+ expose: bool,
514
+ }
515
+
516
+ #[derive(Debug, Default, Clone)]
517
+ struct OpValueOption(Option<OpValue>);
518
+
519
+ impl OpValueOption {
520
+ fn id(&self) -> Option<OpId> {
521
+ self.value().map(|o| o.id)
522
+ }
523
+
524
+ fn increment(&mut self, n: i64) {
525
+ if let Self(Some(ov)) = self {
526
+ if let Value::Scalar(ScalarValue::Counter(c)) = &mut ov.value {
527
+ c.increment(n);
528
+ }
529
+ }
530
+ }
531
+
532
+ fn expose(&mut self) {
533
+ if let Self(Some(ov)) = self {
534
+ ov.expose = true;
535
+ }
536
+ }
537
+
538
+ fn set(&mut self, value: Value, id: OpId, deleted: bool) {
539
+ if deleted && self.is_visible() {
540
+ self.expose();
541
+ } else {
542
+ let conflict = self.is_visible();
543
+ *self = Self(Some(OpValue {
544
+ value,
545
+ id,
546
+ conflict,
547
+ deleted,
548
+ expose: false,
549
+ }));
550
+ }
551
+ }
552
+
553
+ fn is_none(&self) -> bool {
554
+ self.value().is_none()
555
+ }
556
+
557
+ fn value(&self) -> Option<&OpValue> {
558
+ self.0.as_ref()
559
+ }
560
+
561
+ fn is_visible(&self) -> bool {
562
+ self.value().map(|o| !o.deleted).unwrap_or(false)
563
+ }
564
+
565
+ fn is_deleted(&self) -> bool {
566
+ self.value().map(|o| o.deleted).unwrap_or(false)
567
+ }
568
+
569
+ fn take(&mut self) -> Self {
570
+ Self(self.0.take())
571
+ }
572
+
573
+ fn into_value(self) -> Option<OpValue> {
574
+ self.0
575
+ }
576
+ }
577
+
578
+ impl<'a> ValueState<'a> {
579
+ fn new(obj: ObjId, encoding: SequenceType, text_encoding: TextEncoding) -> Self {
580
+ Self {
581
+ obj,
582
+ seq_type: encoding,
583
+ text_encoding,
584
+ key: None,
585
+ doc: OpValueOption(None),
586
+ change: OpValueOption(None),
587
+ marks: RichTextDiff::default(),
588
+ }
589
+ }
590
+
591
+ fn process_doc_op(&mut self, doc_op: &Op<'a>, deleted: bool) {
592
+ match doc_op.action {
593
+ Action::Increment => {}
594
+ Action::Mark => {
595
+ self.marks.before.process(doc_op.id, doc_op.action());
596
+ self.marks.after.process(doc_op.id, doc_op.action());
597
+ }
598
+ _ => {
599
+ if doc_op.visible() {
600
+ self.doc
601
+ .set(doc_op.hydrate_value(self.text_encoding), doc_op.id, deleted);
602
+ }
603
+ }
604
+ }
605
+ }
606
+
607
+ fn do_increment(&mut self, op: &ChangeOp) {
608
+ if self.change.is_none() {
609
+ if let Some(id) = self.doc.id() {
610
+ if op.pred().contains(&id) && !self.doc.is_deleted() {
611
+ self.change = self.doc.clone();
612
+ }
613
+ }
614
+ }
615
+ if let Some(id) = self.change.id() {
616
+ if op.pred().contains(&id) {
617
+ self.change.increment(op.value().as_i64());
618
+ }
619
+ }
620
+ }
621
+
622
+ fn process_mark(&mut self, id: OpId, data: Option<MarkData<'static>>) {
623
+ if let Some(data) = data {
624
+ self.marks.after.mark_begin(id, data);
625
+ } else {
626
+ self.marks.after.mark_end(id);
627
+ }
628
+ }
629
+
630
+ fn process_change_op(&mut self, op: &ChangeOp) {
631
+ match op.action() {
632
+ Action::Delete => {}
633
+ Action::Increment => self.do_increment(op),
634
+ Action::Mark => self.process_mark(op.id(), op.mark_data()),
635
+ _ => {
636
+ if op.visible() {
637
+ self.change
638
+ .set(op.hydrate_value(self.text_encoding), op.id(), false);
639
+ }
640
+ }
641
+ }
642
+ }
643
+
644
+ fn map_flush(&mut self, log: &mut PatchLog) {
645
+ let obj = self.obj;
646
+ let change = self.change.take();
647
+ let doc = self.doc.take();
648
+ if let Some(PropRef::Map(key)) = self.key.take() {
649
+ Self::map_process(obj, &key, doc, change, log);
650
+ }
651
+ }
652
+
653
+ fn list_flush(&mut self, index: usize, log: &mut PatchLog) {
654
+ if self.key.take().is_none() {
655
+ return;
656
+ }
657
+ let obj = self.obj;
658
+ let encoding = self.seq_type;
659
+ if encoding == SequenceType::List {
660
+ match (self.doc.0.take(), self.change.0.take()) {
661
+ (None, Some(c)) => log.insert(obj, index, c.value, c.id, c.conflict),
662
+ (Some(d), Some(c)) if d.id == c.id => {
663
+ let n = c.value.as_i64() - d.value.as_i64();
664
+ if n != 0 {
665
+ log.increment_seq(obj, index, n, c.id);
666
+ }
667
+ }
668
+ (Some(d), Some(c)) if c.id < d.id => {
669
+ log.flag_conflict(obj, &Prop::from(index));
670
+ }
671
+ (Some(d), Some(c)) => {
672
+ let conflict = !d.deleted || c.conflict;
673
+ log.put_seq(obj, index, c.value, c.id, conflict, false)
674
+ }
675
+ (Some(d), None) => {
676
+ if d.expose {
677
+ log.put_seq(obj, index, d.value, d.id, d.conflict, true);
678
+ } else if d.deleted {
679
+ log.delete_seq(obj, index, 1);
680
+ }
681
+ }
682
+ _ => {}
683
+ }
684
+ } else {
685
+ match (self.doc.0.take(), self.change.0.take()) {
686
+ (None, Some(c)) => {
687
+ match c.value {
688
+ Value::Scalar(_) => {
689
+ // I don't think this branch can ever actually happen in practice. If we
690
+ // reach here it's because there is a non-inserting operation (i.e. an
691
+ // update) to the operation at `index`, but we only allow insertions
692
+ // into text objects. Regardless, we handle this is a splice just in
693
+ // case
694
+ log.splice(obj, index, c.value.as_str(), self.marks.current().export());
695
+ }
696
+ _ => log.insert(obj, index, c.value, c.id, c.conflict),
697
+ }
698
+ }
699
+ (Some(d), None) if d.deleted => {
700
+ let w = d.value.width(self.seq_type, self.text_encoding);
701
+ log.delete_seq(obj, index, w);
702
+ }
703
+ (Some(d), None) => {
704
+ if let Some(m) = self.marks.current().export() {
705
+ log.mark(
706
+ obj,
707
+ index,
708
+ d.value.width(self.seq_type, self.text_encoding),
709
+ &m,
710
+ );
711
+ }
712
+ }
713
+ _ => {}
714
+ }
715
+ }
716
+ }
717
+
718
+ fn map_process(
719
+ obj: ObjId,
720
+ key: &str,
721
+ doc: OpValueOption,
722
+ change: OpValueOption,
723
+ log: &mut PatchLog,
724
+ ) {
725
+ match (doc.into_value(), change.into_value()) {
726
+ (None, Some(c)) => {
727
+ log.put_map(obj, key, c.value, c.id, c.conflict, false);
728
+ }
729
+ (Some(d), None) => {
730
+ if d.expose {
731
+ log.put_map(obj, key, d.value, d.id, d.conflict, true);
732
+ } else if d.deleted {
733
+ log.delete_map(obj, key);
734
+ }
735
+ }
736
+ (Some(d), Some(c)) if c.id > d.id => {
737
+ let conflict = (c.conflict && !d.conflict) || !d.deleted;
738
+ log.put_map(obj, key, c.value, c.id, conflict, false);
739
+ }
740
+ (Some(d), Some(c)) if c.id < d.id => {
741
+ if !d.conflict {
742
+ log.flag_conflict(obj, &Prop::from(key));
743
+ }
744
+ }
745
+ (Some(d), Some(c)) if d.id == c.id => {
746
+ let n = c.value.as_i64() - d.value.as_i64();
747
+ if n != 0 {
748
+ log.increment_map(obj, key, n, c.id);
749
+ }
750
+ }
751
+ _ => {}
752
+ }
753
+ }
754
+ }
755
+
756
+ fn walk_map(mw: &mut MapWalker<'_, '_>, change_ops: &mut [ChangeOp]) {
757
+ for pos in 0..change_ops.len() {
758
+ mw.change_op(change_ops, pos);
759
+ }
760
+ mw.finish(change_ops);
761
+ }
762
+
763
+ impl BatchApply {
764
+ fn push(&mut self, c: Change) {
765
+ assert!(!self.has_actor_seq(&c));
766
+ self.record_actor_seq(&c);
767
+
768
+ assert!(!self.hashes.contains(&c.hash()));
769
+ self.hashes.insert(c.hash());
770
+
771
+ self.changes.push(c);
772
+ }
773
+
774
+ fn record_actor_seq(&mut self, c: &Change) {
775
+ if let Some(set) = self.actor_seq.get_mut(c.actor_id()) {
776
+ set.insert(c.seq());
777
+ } else {
778
+ self.actor_seq
779
+ .insert(c.actor_id().clone(), HashSet::from([c.seq()]));
780
+ }
781
+ }
782
+
783
+ fn has_actor_seq(&self, c: &Change) -> bool {
784
+ self.actor_seq
785
+ .get(c.actor_id())
786
+ .map(|set| set.contains(&c.seq()))
787
+ .unwrap_or(false)
788
+ }
789
+
790
+ fn insert_new_actors(&mut self, doc: &mut Automerge) {
791
+ for c in self.changes.iter().filter(|c| c.seq() == 1) {
792
+ doc.put_actor_ref(c.actor_id());
793
+ }
794
+ }
795
+
796
+ fn import_ops(&mut self, doc: &mut Automerge) {
797
+ for c in &self.changes {
798
+ doc.import_ops_to(c, &mut self.ops).unwrap();
799
+ doc.update_history(c);
800
+ }
801
+ doc.remove_unused_actors(true);
802
+ }
803
+
804
+ pub(crate) fn apply(
805
+ &mut self,
806
+ doc: &mut Automerge,
807
+ log: &mut PatchLog,
808
+ ) -> Result<(), PatchLogMismatch> {
809
+ self.insert_new_actors(doc);
810
+
811
+ log.migrate_actors(&doc.ops().actors)?;
812
+
813
+ self.import_ops(doc);
814
+
815
+ let mut obj_info = doc.ops().obj_info.clone();
816
+
817
+ self.order_ops_for_doc(&mut obj_info);
818
+
819
+ let mut succ = vec![];
820
+
821
+ let mut walker = ObjWalker::new(doc.ops());
822
+
823
+ let mut conflicts = vec![];
824
+
825
+ for os in &self.obj_spans {
826
+ let obj_range = walker.seek_to_obj(os.obj);
827
+ let doc_ops = doc.ops().iter_range(&obj_range);
828
+ match obj_info.object_type(&os.obj) {
829
+ Some(ObjType::Map) => {
830
+ let mut walker = MapWalker::new(
831
+ os.obj,
832
+ doc_ops,
833
+ doc.text_encoding(),
834
+ &mut self.pred,
835
+ &mut succ,
836
+ log,
837
+ &mut conflicts,
838
+ );
839
+ let change_ops = &mut self.ops[os.span.clone()];
840
+ walk_map(&mut walker, change_ops);
841
+ }
842
+ Some(otype) if otype.is_sequence() => {
843
+ let sequence_type = match otype {
844
+ ObjType::Text => SequenceType::Text,
845
+ ObjType::List => SequenceType::List,
846
+ _ => unreachable!(),
847
+ };
848
+ let ut = Untangler::new(
849
+ os.obj,
850
+ sequence_type,
851
+ doc.text_encoding(),
852
+ &mut conflicts,
853
+ &mut self.ops[os.span.clone()],
854
+ &mut self.pred,
855
+ doc_ops.end_pos(),
856
+ );
857
+ walk_list(ut, doc_ops, &mut succ, log);
858
+ }
859
+ _ => panic!("Obj {:?} Missing from Index", os.obj),
860
+ }
861
+ }
862
+
863
+ #[cfg(feature = "slow_path_assertions")]
864
+ {
865
+ // should always be ordered correctly - just double checking
866
+ let mut tmp_succ = succ.clone();
867
+ tmp_succ.sort_by(|a, b| {
868
+ a.pos
869
+ .cmp(&b.pos)
870
+ .then_with(|| a.sub_pos.cmp(&b.sub_pos))
871
+ .then_with(|| a.id.counter().cmp(&b.id.counter()))
872
+ .then_with(|| a.id.actor().cmp(&b.id.actor()))
873
+ });
874
+ debug_assert_eq!(succ, tmp_succ);
875
+ }
876
+
877
+ for a in conflicts {
878
+ match a {
879
+ Adjust::Conflict(index) => doc.ops.conflict(index),
880
+ Adjust::Expose(index) => doc.ops.expose(index),
881
+ }
882
+ }
883
+
884
+ doc.ops.add_succ(&succ);
885
+
886
+ self.insert_runs_of_ops(doc);
887
+
888
+ debug_assert!(doc.ops.validate_op_order());
889
+ Ok(())
890
+ }
891
+
892
+ fn insert_runs_of_ops(&mut self, doc: &mut Automerge) {
893
+ let mut last_pos = None;
894
+ let mut start = 0;
895
+ let mut shift = 0;
896
+ for (i, op) in self.ops.iter().enumerate() {
897
+ if op.pos != last_pos {
898
+ if let Some(pos) = last_pos {
899
+ let end = i;
900
+ shift += self.insert_ops(doc, pos + shift, start..end);
901
+ start = end;
902
+ }
903
+ last_pos = op.pos;
904
+ }
905
+ }
906
+ if let Some(pos) = last_pos {
907
+ self.insert_ops(doc, pos + shift, start..self.ops.len());
908
+ }
909
+ }
910
+
911
+ pub(crate) fn insert_ops(&self, doc: &mut Automerge, pos: usize, range: Range<usize>) -> usize {
912
+ let batch = &self.ops[range];
913
+ let start = doc.ops().len();
914
+ doc.ops_mut().splice(pos, batch);
915
+ doc.ops().len() - start
916
+ }
917
+
918
+ pub(crate) fn order_ops_for_doc(&mut self, obj_info: &mut ObjIndex) {
919
+ self.ops.sort_by(|a, b| {
920
+ a.bld.obj.cmp(&b.bld.obj).then_with(|| {
921
+ match a.elemid_or_key().partial_cmp(&b.elemid_or_key()) {
922
+ Some(Ordering::Equal) | None => a.bld.id.cmp(&b.bld.id),
923
+ Some(order) => order,
924
+ }
925
+ })
926
+ });
927
+ let mut start = 0;
928
+ let mut last_obj = None;
929
+ for (i, o) in self.ops.iter().enumerate() {
930
+ for p in o.pred().iter() {
931
+ self.pred
932
+ .entry(*p)
933
+ .or_default()
934
+ .push((o.id(), o.get_increment_value()));
935
+ }
936
+ if let Some(info) = o.obj_info() {
937
+ obj_info.insert(o.id(), info)
938
+ }
939
+ if Some(o.bld.obj) != last_obj {
940
+ if let Some(obj) = last_obj {
941
+ self.obj_spans.push(ObjSpan {
942
+ obj,
943
+ span: start..i,
944
+ });
945
+ }
946
+ start = i;
947
+ last_obj = Some(o.bld.obj);
948
+ }
949
+ }
950
+ if let Some(obj) = last_obj {
951
+ let span = start..self.ops.len();
952
+ self.obj_spans.push(ObjSpan { obj, span });
953
+ }
954
+ }
955
+ }
956
+
957
+ #[derive(Debug, Clone)]
958
+ struct ObjWalker<'a> {
959
+ iter: ObjIdIter<'a>,
960
+ }
961
+
962
+ impl<'a> ObjWalker<'a> {
963
+ fn new(ops: &'a OpSet) -> Self {
964
+ let iter = ops.obj_id_iter();
965
+ Self { iter }
966
+ }
967
+
968
+ fn seek_to_obj(&mut self, obj: ObjId) -> Range<usize> {
969
+ self.iter.seek_to_value(obj)
970
+ }
971
+ }
972
+
973
+ #[derive(Debug, Clone, Default)]
974
+ struct ObjSpan {
975
+ obj: ObjId,
976
+ span: Range<usize>,
977
+ }
978
+
979
+ impl Automerge {
980
+ pub fn apply_changes_batch(
981
+ &mut self,
982
+ changes: impl IntoIterator<Item = Change> + Clone,
983
+ ) -> Result<(), AutomergeError> {
984
+ self.apply_changes_batch_log_patches(changes, &mut PatchLog::inactive())
985
+ }
986
+
987
+ pub fn apply_changes_batch_log_patches<I: IntoIterator<Item = Change>>(
988
+ &mut self,
989
+ changes: I,
990
+ log: &mut PatchLog,
991
+ ) -> Result<(), AutomergeError> {
992
+ // Pool all incoming changes together with any previously queued orphans.
993
+ let mut pool: Vec<Change> = self.queue.take();
994
+ let mut seen: HashSet<ChangeHash> = pool.iter().map(|c| c.hash()).collect();
995
+ let mut actor_seqs: HashMap<ActorId, HashSet<u64>> = HashMap::new();
996
+ for c in &pool {
997
+ actor_seqs
998
+ .entry(c.actor_id().clone())
999
+ .or_default()
1000
+ .insert(c.seq());
1001
+ }
1002
+
1003
+ // Add new changes, deduplicating and checking for duplicate seq numbers.
1004
+ for c in changes {
1005
+ let hash = c.hash();
1006
+ if self.change_graph.has_change(&hash) || seen.contains(&hash) {
1007
+ continue;
1008
+ }
1009
+ if self.has_actor_seq(&c)
1010
+ || actor_seqs
1011
+ .get(c.actor_id())
1012
+ .is_some_and(|s| s.contains(&c.seq()))
1013
+ {
1014
+ // Put pool back as queue before returning error
1015
+ for pc in pool {
1016
+ self.queue.push(pc);
1017
+ }
1018
+ return Err(AutomergeError::DuplicateSeqNumber(
1019
+ c.seq(),
1020
+ c.actor_id().clone(),
1021
+ ));
1022
+ }
1023
+ seen.insert(hash);
1024
+ actor_seqs
1025
+ .entry(c.actor_id().clone())
1026
+ .or_default()
1027
+ .insert(c.seq());
1028
+ pool.push(c);
1029
+ }
1030
+
1031
+ if pool.is_empty() {
1032
+ return Ok(());
1033
+ }
1034
+
1035
+ // Kahn's algorithm: topological sort of the pool.
1036
+ let n = pool.len();
1037
+ let mut unsatisfied = vec![0u32; n];
1038
+ let mut waiting_on: HashMap<ChangeHash, Vec<usize>> = HashMap::new();
1039
+
1040
+ for (i, c) in pool.iter().enumerate() {
1041
+ for dep in c.deps() {
1042
+ if !self.change_graph.has_change(dep) {
1043
+ unsatisfied[i] += 1;
1044
+ waiting_on.entry(*dep).or_default().push(i);
1045
+ }
1046
+ }
1047
+ }
1048
+
1049
+ let mut ready: VecDeque<usize> = VecDeque::new();
1050
+ for (i, &count) in unsatisfied.iter().enumerate() {
1051
+ if count == 0 {
1052
+ ready.push_back(i);
1053
+ }
1054
+ }
1055
+
1056
+ let mut topo_order: Vec<usize> = Vec::new();
1057
+ while let Some(idx) = ready.pop_front() {
1058
+ let hash = pool[idx].hash();
1059
+ topo_order.push(idx);
1060
+ if let Some(dependents) = waiting_on.remove(&hash) {
1061
+ for dep_idx in dependents {
1062
+ unsatisfied[dep_idx] -= 1;
1063
+ if unsatisfied[dep_idx] == 0 {
1064
+ ready.push_back(dep_idx);
1065
+ }
1066
+ }
1067
+ }
1068
+ }
1069
+
1070
+ // Split pool into ready (topo-sorted) and orphaned.
1071
+ let mut consumed = vec![false; n];
1072
+ for &idx in &topo_order {
1073
+ consumed[idx] = true;
1074
+ }
1075
+ let mut slots: Vec<Option<Change>> = pool.into_iter().map(Some).collect();
1076
+
1077
+ let mut chap = BatchApply::default();
1078
+ for idx in topo_order {
1079
+ if let Some(c) = slots[idx].take() {
1080
+ chap.push(c);
1081
+ }
1082
+ }
1083
+
1084
+ for c in slots.into_iter().flatten() {
1085
+ self.queue.push(c);
1086
+ }
1087
+
1088
+ Ok(chap.apply(self, log)?)
1089
+ }
1090
+
1091
+ fn import_ops_to(
1092
+ &mut self,
1093
+ change: &Change,
1094
+ ops: &mut Vec<ChangeOp>,
1095
+ ) -> Result<(), AutomergeError> {
1096
+ let new_ops = self.import_ops(change)?;
1097
+ ops.extend(new_ops);
1098
+ Ok(())
1099
+ }
1100
+
1101
+ fn import_ops(&mut self, change: &Change) -> Result<Vec<ChangeOp>, AutomergeError> {
1102
+ let actors: Vec<_> = change
1103
+ .actors()
1104
+ .map(|a| self.ops.lookup_actor(a).unwrap())
1105
+ .collect();
1106
+
1107
+ change
1108
+ .iter_ops()
1109
+ .enumerate()
1110
+ .map(|(i, c)| {
1111
+ let id = OpId::new(change.start_op().get() + i as u64, 0).map(&actors)?;
1112
+ let key = c.key.map(&actors)?;
1113
+ let obj = c.obj.map(&actors)?;
1114
+ let pred = c
1115
+ .pred
1116
+ .into_iter()
1117
+ .map(|id| id.map(&actors))
1118
+ .collect::<Result<Vec<_>, _>>()?;
1119
+ let bld = OpBuilder {
1120
+ id,
1121
+ obj,
1122
+ key,
1123
+ action: c.action.try_into()?,
1124
+ value: c.val.into_ref(),
1125
+ mark_name: c.mark_name.map(String::from).map(Cow::Owned),
1126
+ expand: c.expand,
1127
+ insert: c.insert,
1128
+ pred,
1129
+ };
1130
+ let change = ChangeOp {
1131
+ pos: None,
1132
+ subsort: 0,
1133
+ conflicted: false,
1134
+ succ: vec![],
1135
+ bld,
1136
+ };
1137
+ Ok(change)
1138
+ })
1139
+ .collect()
1140
+ }
1141
+ }
1142
+
1143
+ #[cfg(test)]
1144
+ mod tests {
1145
+ use super::*;
1146
+ use crate::marks::{ExpandMark, Mark};
1147
+ use crate::read::ReadDoc;
1148
+ use crate::transaction::Transactable;
1149
+ use crate::types;
1150
+ use crate::{ActorId, AutoCommit, ROOT};
1151
+ use rand::prelude::*;
1152
+
1153
+ impl AutoCommit {
1154
+ fn apply_changes_iter(
1155
+ &mut self,
1156
+ changes: impl IntoIterator<Item = Change> + Clone,
1157
+ ) -> Result<(), AutomergeError> {
1158
+ let changes = changes.into_iter().collect::<Vec<_>>();
1159
+ for c in changes {
1160
+ self.apply_changes([c])?;
1161
+ }
1162
+ self.validate_top_index();
1163
+ Ok(())
1164
+ }
1165
+ }
1166
+
1167
+ #[test]
1168
+ fn map_batch_apply() {
1169
+ let actor3 = ActorId::try_from("aaaaaa").unwrap();
1170
+ let actor2 = ActorId::try_from("bbbbbb").unwrap();
1171
+ let actor1 = ActorId::try_from("cccccc").unwrap();
1172
+
1173
+ let mut doc1 = AutoCommit::new().with_actor(actor1);
1174
+ let map1 = doc1.put_object(&ROOT, "map", ObjType::Map).unwrap();
1175
+ doc1.put(&map1, "key1", "val1").unwrap();
1176
+ doc1.put(&map1, "key2", "val2").unwrap();
1177
+
1178
+ let heads1 = doc1.get_heads();
1179
+
1180
+ let mut doc2 = doc1.fork().with_actor(actor2);
1181
+ doc2.put(&map1, "key1", "val3a").unwrap();
1182
+ doc2.put(&map1, "key1", "val3a.1").unwrap();
1183
+ doc2.put(&map1, "key1", "val3a.2").unwrap();
1184
+ doc2.delete(&map1, "key2").unwrap();
1185
+ doc2.put(&map1, "key3", "val4a").unwrap();
1186
+ let map2 = doc2.put_object(&map1, "map2", ObjType::Map).unwrap();
1187
+ doc2.put(&map2, "key1", "val5a").unwrap();
1188
+
1189
+ let map3 = doc1.put_object(&map1, "map3", ObjType::Map).unwrap();
1190
+ doc1.put(&map1, "key1", "val6a").unwrap();
1191
+ doc1.put(&map3, "key1", "val7a").unwrap();
1192
+
1193
+ let mut doc3 = doc1.fork().with_actor(actor3);
1194
+ doc3.put(&map1, "key1", "val3b").unwrap();
1195
+ doc3.put(&map1, "key3", "val4b").unwrap();
1196
+
1197
+ let mut doc1_test = doc1.fork();
1198
+ let mut changes2 = doc2.get_changes(&heads1);
1199
+
1200
+ let changes3 = doc3.get_changes(&heads1);
1201
+ changes2.extend(changes3);
1202
+
1203
+ doc1.apply_changes_iter(changes2.clone()).unwrap();
1204
+ doc1_test.doc.apply_changes_batch(changes2.clone()).unwrap();
1205
+ doc1_test.validate_top_index();
1206
+
1207
+ doc1.dump();
1208
+ doc1_test.dump();
1209
+ doc1.doc.debug_cmp(&doc1_test.doc);
1210
+ }
1211
+
1212
+ #[test]
1213
+ fn list_batch_apply() {
1214
+ let actor3 = ActorId::try_from("aaaaaa").unwrap();
1215
+ let actor2 = ActorId::try_from("bbbbbb").unwrap();
1216
+ let actor1 = ActorId::try_from("cccccc").unwrap();
1217
+
1218
+ let mut doc1 = AutoCommit::new().with_actor(actor1);
1219
+ let list = doc1.put_object(&ROOT, "list", ObjType::List).unwrap();
1220
+ doc1.insert(&list, 0, "val1").unwrap();
1221
+ doc1.insert(&list, 1, "val2").unwrap();
1222
+ doc1.insert(&list, 2, "val3").unwrap();
1223
+
1224
+ let heads1 = doc1.get_heads();
1225
+
1226
+ let mut doc2 = doc1.fork().with_actor(actor2);
1227
+ doc2.insert(&list, 1, "val4a").unwrap();
1228
+ doc2.insert(&list, 1, "val4b").unwrap();
1229
+ doc2.insert(&list, 2, "val4c").unwrap();
1230
+ doc2.insert(&list, 0, "val4d").unwrap();
1231
+ doc2.insert(&list, 0, "val4e").unwrap();
1232
+ doc2.insert(&list, 0, "val4f").unwrap();
1233
+
1234
+ let mut doc3 = doc1.fork().with_actor(actor3);
1235
+ doc3.insert(&list, 1, "val5a").unwrap();
1236
+ doc3.insert(&list, 1, "val5b").unwrap();
1237
+ doc3.insert(&list, 2, "val5c").unwrap();
1238
+ doc3.insert(&list, 3, "val5d").unwrap();
1239
+ doc3.insert(&list, 1, "val5e").unwrap();
1240
+ doc3.insert(&list, 1, "val5f").unwrap();
1241
+ doc3.insert(&list, 0, "val5g").unwrap();
1242
+ doc3.insert(&list, 0, "val5h").unwrap();
1243
+
1244
+ let mut doc1_test = doc1.fork();
1245
+ let mut changes2 = doc2.get_changes(&heads1);
1246
+ let changes3 = doc3.get_changes(&heads1);
1247
+ changes2.extend(changes3);
1248
+
1249
+ doc1.apply_changes_iter(changes2.clone()).unwrap();
1250
+ doc1_test.doc.apply_changes_batch(changes2.clone()).unwrap();
1251
+ doc1_test.validate_top_index();
1252
+
1253
+ doc1.dump();
1254
+ doc1_test.dump();
1255
+
1256
+ doc1.doc.debug_cmp(&doc1_test.doc);
1257
+ }
1258
+
1259
+ #[test]
1260
+ fn text_batch_apply() {
1261
+ let actor3 = ActorId::try_from("aaaaaa").unwrap();
1262
+ let actor2 = ActorId::try_from("bbbbbb").unwrap();
1263
+ let actor1 = ActorId::try_from("cccccc").unwrap();
1264
+
1265
+ let mut doc1 = AutoCommit::new().with_actor(actor1);
1266
+ let text = doc1.put_object(&ROOT, "text", ObjType::Text).unwrap();
1267
+ doc1.splice_text(&text, 0, 0, "the quick fox jumped over the lazy dog")
1268
+ .unwrap();
1269
+
1270
+ let heads1 = doc1.get_heads();
1271
+
1272
+ let mut doc2 = doc1.fork().with_actor(actor2);
1273
+ doc2.splice_text(&text, 0, 0, "abc").unwrap();
1274
+
1275
+ let mut doc3 = doc1.fork().with_actor(actor3);
1276
+ doc3.splice_text(&text, 3, 1, "aalks").unwrap();
1277
+
1278
+ let mut doc1_test = doc1.fork();
1279
+ let mut changes2 = doc2.get_changes(&heads1);
1280
+ let changes3 = doc3.get_changes(&heads1);
1281
+ changes2.extend(changes3);
1282
+
1283
+ doc1.apply_changes_iter(changes2.clone()).unwrap();
1284
+ doc1_test.apply_changes_batch(changes2.clone()).unwrap();
1285
+ doc1_test.validate_top_index();
1286
+
1287
+ doc1.dump();
1288
+ doc1_test.dump();
1289
+
1290
+ doc1.doc.debug_cmp(&doc1_test.doc);
1291
+ //assert_eq!(doc1.save(), doc1_test.save());
1292
+ }
1293
+
1294
+ #[test]
1295
+ fn multi_put_batch_apply() {
1296
+ let mut rng = make_rng();
1297
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1298
+ let list = doc1.put_object(&ROOT, "list", ObjType::List).unwrap();
1299
+ doc1.insert(&list, 0, "a").unwrap();
1300
+ doc1.insert(&list, 1, "b").unwrap();
1301
+ doc1.insert(&list, 2, "c").unwrap();
1302
+ let heads = doc1.get_heads();
1303
+
1304
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1305
+ for i in 0..10 {
1306
+ let mut tmp = doc1.fork().with_actor(rng.random());
1307
+ tmp.put(&list, 0, i).unwrap();
1308
+ doc2.merge(&mut tmp).unwrap();
1309
+ }
1310
+ let changes = doc2.get_changes(&heads);
1311
+ doc1.apply_changes_batch(changes).unwrap();
1312
+ doc1.validate_top_index();
1313
+ assert_eq!(doc1.save(), doc2.save());
1314
+ }
1315
+
1316
+ #[test]
1317
+ fn multi_insert_batch_apply() {
1318
+ let mut rng = make_rng();
1319
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1320
+ let list = doc1.put_object(&ROOT, "list", ObjType::List).unwrap();
1321
+ doc1.insert(&list, 0, "a").unwrap();
1322
+ doc1.insert(&list, 1, "b").unwrap();
1323
+ doc1.insert(&list, 2, "c").unwrap();
1324
+ let heads = doc1.get_heads();
1325
+
1326
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1327
+
1328
+ for i in 0..10 {
1329
+ let mut tmp = doc1.fork().with_actor(rng.random());
1330
+ tmp.insert(&list, 1, i).unwrap();
1331
+ //let change = tmp.get_last_local_change().unwrap();
1332
+ doc2.merge(&mut tmp).unwrap();
1333
+ }
1334
+
1335
+ let changes = doc2.get_changes(&heads);
1336
+ doc1.apply_changes_batch(changes).unwrap();
1337
+ doc1.validate_top_index();
1338
+ assert_eq!(doc1.save(), doc2.save());
1339
+ }
1340
+
1341
+ #[test]
1342
+ fn multi_update_batch_apply() {
1343
+ let mut rng = make_rng();
1344
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1345
+ let list = doc1.put_object(&ROOT, "list", ObjType::List).unwrap();
1346
+ doc1.insert(&list, 0, "a").unwrap();
1347
+ doc1.insert(&list, 1, "b").unwrap();
1348
+ doc1.insert(&list, 2, "c").unwrap();
1349
+ let heads = doc1.get_heads();
1350
+
1351
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1352
+
1353
+ for i in 0..3 {
1354
+ let mut tmp = doc1.fork().with_actor(rng.random());
1355
+ tmp.put(&list, 2, i).unwrap();
1356
+ doc2.merge(&mut tmp).unwrap();
1357
+ }
1358
+
1359
+ let changes = doc2.get_changes(&heads);
1360
+ doc1.apply_changes_batch(changes).unwrap();
1361
+ doc1.validate_top_index();
1362
+ assert_eq!(doc1.save(), doc2.save());
1363
+ }
1364
+
1365
+ fn make_rng() -> SmallRng {
1366
+ let seed = std::env::var("AUTOMERGE_TEST_SEED")
1367
+ .ok()
1368
+ .and_then(|s| s.parse::<u64>().ok())
1369
+ .unwrap_or_else(rand::random::<u64>);
1370
+ log!("SEED: {}", seed);
1371
+ SmallRng::seed_from_u64(seed)
1372
+ }
1373
+
1374
+ #[test]
1375
+ fn fuzz_batch_list_apply() {
1376
+ let mut rng = make_rng();
1377
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1378
+ let list = doc1.put_object(&ROOT, "list", ObjType::List).unwrap();
1379
+ doc1.insert(&list, 0, "a").unwrap();
1380
+ doc1.insert(&list, 1, "b").unwrap();
1381
+ doc1.insert(&list, 2, "c").unwrap();
1382
+ let mut value = 0;
1383
+ let mut val = move || {
1384
+ value += 1;
1385
+ value
1386
+ };
1387
+ let heads = doc1.get_heads();
1388
+
1389
+ let mut doc1_tmp = doc1.fork().with_actor(rng.random());
1390
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1391
+
1392
+ for _ in 0..3 {
1393
+ for _ in 0..30 {
1394
+ let mut tmp = doc1_tmp.fork().with_actor(rng.random());
1395
+ let num_inserts = rng.random::<u32>() % 10 + 1;
1396
+ let num_updates = rng.random::<u32>() % 10 + 1;
1397
+ let num_deletes = rng.random::<u32>() % 2;
1398
+ for _ in 0..num_inserts {
1399
+ let len = tmp.length(&list) as u32;
1400
+ let pos = rng.random::<u32>() % len;
1401
+ tmp.insert(&list, pos as usize, val()).unwrap();
1402
+ }
1403
+ for _ in 0..num_updates {
1404
+ let len = tmp.length(&list) as u32;
1405
+ let pos = rng.random::<u32>() % len;
1406
+ tmp.put(&list, pos as usize, val()).unwrap();
1407
+ }
1408
+ for _ in 0..num_deletes {
1409
+ let len = tmp.length(&list) as u32;
1410
+ let pos = rng.random::<u32>() % len;
1411
+ tmp.delete(&list, pos as usize).unwrap();
1412
+ }
1413
+ doc2.merge(&mut tmp).unwrap();
1414
+ }
1415
+ doc1_tmp.merge(&mut doc2).unwrap();
1416
+ }
1417
+
1418
+ let changes = doc2.get_changes(&heads);
1419
+ doc1.apply_changes_batch(changes).unwrap();
1420
+ doc1.validate_top_index();
1421
+ assert_eq!(doc1.save(), doc2.save());
1422
+ }
1423
+
1424
+ #[test]
1425
+ fn fuzz_batch_map1_apply() {
1426
+ let mut rng = make_rng();
1427
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1428
+ let map1 = doc1.put_object(&ROOT, "map1", ObjType::Map).unwrap();
1429
+ let map2 = doc1.put_object(&map1, "map2", ObjType::Map).unwrap();
1430
+ let map3 = doc1.put_object(&map2, "map3", ObjType::Map).unwrap();
1431
+ let maps = [map1, map2, map3];
1432
+ let mut value = 0;
1433
+ let mut val = move || {
1434
+ value += 1;
1435
+ value
1436
+ };
1437
+ let heads = doc1.get_heads();
1438
+
1439
+ let mut doc1_tmp = doc1.fork().with_actor(rng.random());
1440
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1441
+
1442
+ for _ in 0..3 {
1443
+ for _ in 0..30 {
1444
+ let mut tmp = doc1_tmp.fork().with_actor(rng.random());
1445
+ let num_updates = rng.random::<u32>() % 10 + 1;
1446
+ let num_deletes = rng.random::<u32>() % 2;
1447
+ for _ in 0..num_updates {
1448
+ let key = format!("key{}", rng.random::<u32>() % 20);
1449
+ let map = rng.random::<u32>() % (maps.len() as u32);
1450
+ tmp.put(&maps[map as usize], key, val()).unwrap();
1451
+ }
1452
+ for _ in 0..num_deletes {
1453
+ let key = format!("key{}", rng.random::<u32>() % 20);
1454
+ let map = rng.random::<u32>() % (maps.len() as u32);
1455
+ tmp.delete(&maps[map as usize], key).unwrap();
1456
+ }
1457
+ doc2.merge(&mut tmp).unwrap();
1458
+ }
1459
+ doc1_tmp.merge(&mut doc2).unwrap();
1460
+ }
1461
+
1462
+ let changes = doc2.get_changes(&heads);
1463
+ doc1.apply_changes_batch(changes).unwrap();
1464
+ doc1.validate_top_index();
1465
+ assert_eq!(doc1.save(), doc2.save());
1466
+ }
1467
+
1468
+ #[test]
1469
+ fn fuzz_batch_map2_apply() {
1470
+ let mut rng = make_rng();
1471
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1472
+ let map1 = doc1.put_object(&ROOT, "map1", ObjType::Map).unwrap();
1473
+ let map2 = doc1.put_object(&map1, "map2", ObjType::Map).unwrap();
1474
+ let map3 = doc1.put_object(&map2, "map3", ObjType::Map).unwrap();
1475
+ let maps = [map1, map2, map3];
1476
+ let mut value = 0;
1477
+ let mut val = move || {
1478
+ value += 1;
1479
+ value
1480
+ };
1481
+ let heads = doc1.get_heads();
1482
+
1483
+ let mut doc1_tmp = doc1.fork().with_actor(rng.random());
1484
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1485
+
1486
+ for _ in 0..3 {
1487
+ for _ in 0..30 {
1488
+ let mut tmp = doc1_tmp.fork().with_actor(rng.random());
1489
+ let num_updates = rng.random::<u32>() % 10 + 1;
1490
+ let num_deletes = rng.random::<u32>() % 2;
1491
+ for _ in 0..num_updates {
1492
+ let key = format!("key{}", rng.random::<u32>() % 1000);
1493
+ let map = rng.random::<u32>() % (maps.len() as u32);
1494
+ tmp.put(&maps[map as usize], key, val()).unwrap();
1495
+ }
1496
+ for _ in 0..num_deletes {
1497
+ let key = format!("key{}", rng.random::<u32>() % 1000);
1498
+ let map = rng.random::<u32>() % (maps.len() as u32);
1499
+ tmp.delete(&maps[map as usize], key).unwrap();
1500
+ }
1501
+ doc2.merge(&mut tmp).unwrap();
1502
+ }
1503
+ doc1_tmp.merge(&mut doc2).unwrap();
1504
+ }
1505
+
1506
+ let changes = doc2.get_changes(&heads);
1507
+
1508
+ let mut doc_a = doc1;
1509
+ let mut doc_b = doc_a.clone();
1510
+
1511
+ doc_a.update_diff_cursor();
1512
+ doc_a.apply_changes_batch(changes.clone()).unwrap();
1513
+ doc_a.validate_top_index();
1514
+ doc_b.apply_changes_iter(changes).unwrap();
1515
+
1516
+ let final_heads = doc_a.get_heads();
1517
+
1518
+ assert_eq!(doc_a.save(), doc_b.save());
1519
+
1520
+ let pa = doc_a.diff_incremental();
1521
+ let pb = doc_b.diff(&heads, &final_heads);
1522
+
1523
+ let len = std::cmp::max(pa.len(), pb.len());
1524
+
1525
+ for i in 0..len {
1526
+ if pa.get(i) != pb.get(i) {
1527
+ log!(" i={} ", i);
1528
+ log!(" pa={:?}", pa.get(i));
1529
+ log!(" pb={:?}", pb.get(i));
1530
+ }
1531
+ }
1532
+
1533
+ if pa != pb {
1534
+ panic!()
1535
+ }
1536
+ }
1537
+
1538
+ #[test]
1539
+ fn fuzz_batch_map_counter_apply() {
1540
+ let mut rng = make_rng();
1541
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1542
+ let map1 = doc1.put_object(&ROOT, "map1", ObjType::Map).unwrap();
1543
+ doc1.put(&map1, "key1", ScalarValue::counter(10)).unwrap();
1544
+ doc1.increment(&map1, "key1", 15).unwrap();
1545
+ doc1.increment(&map1, "key1", 10).unwrap();
1546
+ let map2 = doc1.put_object(&map1, "map2", ObjType::Map).unwrap();
1547
+ doc1.put(&map2, "key1", ScalarValue::counter(100)).unwrap();
1548
+ doc1.increment(&map2, "key1", 20).unwrap();
1549
+ doc1.increment(&map2, "key1", 1).unwrap();
1550
+ doc1.delete(&map2, "key1").unwrap();
1551
+ doc1.put(&map2, "key1", ScalarValue::counter(101)).unwrap();
1552
+ doc1.increment(&map2, "key1", 1).unwrap();
1553
+ let map3 = doc1.put_object(&map2, "map3", ObjType::Map).unwrap();
1554
+ doc1.put(&map3, "key1", ScalarValue::counter(1000)).unwrap();
1555
+ doc1.increment(&map3, "key1", 30).unwrap();
1556
+ let maps = [map1, map2, map3];
1557
+ let mut value = 0;
1558
+ let mut val = move || {
1559
+ value += 1;
1560
+ value
1561
+ };
1562
+ let heads = doc1.get_heads();
1563
+
1564
+ let mut doc1_tmp = doc1.fork().with_actor(rng.random());
1565
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1566
+
1567
+ for _ in 0..4 {
1568
+ for _ in 0..30 {
1569
+ let mut tmp = doc1_tmp.fork().with_actor(rng.random());
1570
+ let num_updates = rng.random::<u32>() % 10 + 1;
1571
+ let num_deletes = rng.random::<u32>() % 2;
1572
+ for _ in 0..num_updates {
1573
+ let key = format!("key{}", rng.random::<u32>() % 30);
1574
+ let map = rng.random::<u32>() % (maps.len() as u32);
1575
+ if let Ok(Some((
1576
+ types::Value::Scalar(Cow::Owned(ScalarValue::Counter(_))),
1577
+ _,
1578
+ ))) = tmp.get(&maps[map as usize], &key)
1579
+ {
1580
+ tmp.increment(&maps[map as usize], key, val()).unwrap();
1581
+ } else {
1582
+ tmp.put(&maps[map as usize], key, ScalarValue::counter(val()))
1583
+ .unwrap();
1584
+ }
1585
+ }
1586
+ for _ in 0..num_deletes {
1587
+ let key = format!("key{}", rng.random::<u32>() % 30);
1588
+ let map = rng.random::<u32>() % (maps.len() as u32);
1589
+ tmp.delete(&maps[map as usize], key).unwrap();
1590
+ }
1591
+ doc2.merge(&mut tmp).unwrap();
1592
+ }
1593
+ doc1_tmp.merge(&mut doc2).unwrap();
1594
+ }
1595
+
1596
+ let changes = doc2.get_changes(&heads);
1597
+
1598
+ let mut doc_a = doc1;
1599
+ let mut doc_b = doc_a.clone();
1600
+
1601
+ doc_a.update_diff_cursor();
1602
+ doc_a.apply_changes_batch(changes.clone()).unwrap();
1603
+ doc_a.validate_top_index();
1604
+
1605
+ doc_b.apply_changes_iter(changes).unwrap();
1606
+
1607
+ let final_heads = doc_a.get_heads();
1608
+
1609
+ assert_eq!(doc_a.save(), doc_b.save());
1610
+
1611
+ let pa = doc_a.diff_incremental();
1612
+ let pb = doc_b.diff(&heads, &final_heads);
1613
+
1614
+ let len = std::cmp::max(pa.len(), pb.len());
1615
+
1616
+ for i in 0..len {
1617
+ if pa.get(i) != pb.get(i) {
1618
+ log!(" i={} ", i);
1619
+ log!(" pa={:?}", pa.get(i));
1620
+ log!(" pb={:?}", pb.get(i));
1621
+ }
1622
+ }
1623
+
1624
+ if pa != pb {
1625
+ panic!()
1626
+ }
1627
+ }
1628
+
1629
+ #[test]
1630
+ fn batch_counter_list_patch() {
1631
+ let mut rng = make_rng();
1632
+ let mut value = 0;
1633
+ let mut val = move || {
1634
+ value += 1;
1635
+ value
1636
+ };
1637
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1638
+ let list1 = doc1.put_object(&ROOT, "list1", ObjType::List).unwrap();
1639
+ doc1.insert(&list1, 0, ScalarValue::counter(val())).unwrap();
1640
+ doc1.insert(&list1, 1, ScalarValue::counter(val())).unwrap();
1641
+ doc1.insert(&list1, 2, ScalarValue::counter(val())).unwrap();
1642
+
1643
+ let mut doc1_copy = doc1.fork().with_actor(rng.random());
1644
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1645
+ let mut doc2_copy = doc1.fork().with_actor(rng.random());
1646
+
1647
+ let mut changes = vec![];
1648
+ //for _ in 0..3 {
1649
+ for _ in 0..2 {
1650
+ //for _ in 0..10 {
1651
+ for _ in 0..2 {
1652
+ let mut tmp = doc2.fork().with_actor(rng.random());
1653
+ //let num_updates = rng.gen::<usize>() % 10 + 1;
1654
+ let num_updates = 2;
1655
+ //let num_inserts = rng.gen::<usize>() % 10 + 1;
1656
+ let num_inserts = 2;
1657
+ //let num_deletes = rng.gen::<usize>() % 2;
1658
+ let num_deletes = 1;
1659
+ for _ in 0..num_updates {
1660
+ let len = tmp.length(&list1);
1661
+ let index = rng.random::<u32>() % (len as u32);
1662
+ tmp.increment(&list1, index as usize, val()).unwrap();
1663
+ }
1664
+ for _ in 0..num_inserts {
1665
+ let len = tmp.length(&list1);
1666
+ let index = rng.random::<u32>() % (len as u32);
1667
+ tmp.insert(&list1, index as usize, ScalarValue::counter(val()))
1668
+ .unwrap();
1669
+ }
1670
+ for _ in 0..num_deletes {
1671
+ let len = tmp.length(&list1);
1672
+ let index = rng.random::<u32>() % (len as u32);
1673
+ tmp.delete(&list1, index as usize).unwrap();
1674
+ }
1675
+ let change = tmp.get_last_local_change().unwrap();
1676
+ changes.push(change);
1677
+ }
1678
+ merge_and_diff(&mut doc2, &mut doc2_copy, &changes);
1679
+ }
1680
+ merge_and_diff(&mut doc1, &mut doc1_copy, &changes);
1681
+ }
1682
+
1683
+ #[test]
1684
+ fn batch_list_patch() {
1685
+ let mut rng = make_rng();
1686
+ let mut value = 0;
1687
+ let mut val = move || {
1688
+ value += 1;
1689
+ value
1690
+ };
1691
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1692
+ let list1 = doc1.put_object(&ROOT, "list1", ObjType::List).unwrap();
1693
+ doc1.insert(&list1, 0, val()).unwrap();
1694
+ doc1.insert(&list1, 1, val()).unwrap();
1695
+ doc1.insert(&list1, 2, val()).unwrap();
1696
+
1697
+ let mut doc1_copy = doc1.fork().with_actor(rng.random());
1698
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1699
+ let mut doc2_copy = doc1.fork().with_actor(rng.random());
1700
+
1701
+ let mut changes = vec![];
1702
+ for _ in 0..3 {
1703
+ for _ in 0..30 {
1704
+ let mut tmp = doc2.fork().with_actor(rng.random());
1705
+ let num_updates = rng.random::<u32>() % 10 + 1;
1706
+ let num_inserts = rng.random::<u32>() % 10 + 1;
1707
+ let num_deletes = rng.random::<u32>() % 2;
1708
+ for _ in 0..num_updates {
1709
+ let len = tmp.length(&list1);
1710
+ let index = rng.random::<u32>() % (len as u32);
1711
+ tmp.put(&list1, index as usize, val()).unwrap();
1712
+ }
1713
+ for _ in 0..num_inserts {
1714
+ let len = tmp.length(&list1);
1715
+ let index = rng.random::<u32>() % (len as u32);
1716
+ tmp.insert(&list1, index as usize, val()).unwrap();
1717
+ }
1718
+ for _ in 0..num_deletes {
1719
+ let len = tmp.length(&list1);
1720
+ let index = rng.random::<u32>() % (len as u32);
1721
+ tmp.delete(&list1, index as usize).unwrap();
1722
+ }
1723
+ let change = tmp.get_last_local_change().unwrap();
1724
+ changes.push(change);
1725
+ }
1726
+ merge_and_diff(&mut doc2, &mut doc2_copy, &changes);
1727
+ }
1728
+ merge_and_diff(&mut doc1, &mut doc1_copy, &changes);
1729
+ }
1730
+
1731
+ #[test]
1732
+ fn batch_text_patch() {
1733
+ let mut rng = make_rng();
1734
+ let mut value = 0;
1735
+ let mut val = move || {
1736
+ value += 1;
1737
+ value
1738
+ };
1739
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1740
+ let text1 = doc1.put_object(&ROOT, "text1", ObjType::Text).unwrap();
1741
+ doc1.splice_text(&text1, 0, 0, "--------").unwrap();
1742
+
1743
+ let mut doc1_copy = doc1.fork().with_actor(rng.random());
1744
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1745
+ let mut doc2_copy = doc1.fork().with_actor(rng.random());
1746
+
1747
+ let mut changes = vec![];
1748
+ for _ in 0..10 {
1749
+ for _ in 0..5 {
1750
+ let mut tmp = doc2.fork().with_actor(rng.random());
1751
+ let num_splices = rng.random::<u32>() % 10 + 1;
1752
+ for _ in 0..num_splices {
1753
+ let len = tmp.length(&text1) as u32;
1754
+ let index = rng.random::<u32>() % len;
1755
+ let del = std::cmp::min(rng.random::<u32>() % 2, len - index);
1756
+ tmp.splice_text(
1757
+ &text1,
1758
+ index as usize,
1759
+ del as isize,
1760
+ &format!("[{}]", val()),
1761
+ )
1762
+ .unwrap();
1763
+ }
1764
+ let change = tmp.get_last_local_change().unwrap();
1765
+ changes.push(change);
1766
+ }
1767
+ merge_and_diff(&mut doc2, &mut doc2_copy, &changes);
1768
+ }
1769
+ merge_and_diff(&mut doc1, &mut doc1_copy, &changes);
1770
+ }
1771
+
1772
+ #[test]
1773
+ fn batch_marks_patch() {
1774
+ let mut rng = make_rng();
1775
+ let mut value = 0;
1776
+ let mut val = move || {
1777
+ value += 1;
1778
+ value
1779
+ };
1780
+ let mut doc1 = AutoCommit::new().with_actor(rng.random());
1781
+ let text1 = doc1.put_object(&ROOT, "text1", ObjType::Text).unwrap();
1782
+ doc1.splice_text(&text1, 0, 0, "---------------------")
1783
+ .unwrap();
1784
+
1785
+ let mut doc1_copy = doc1.fork().with_actor(rng.random());
1786
+ let mut doc2 = doc1.fork().with_actor(rng.random());
1787
+ let mut doc2_copy = doc1.fork().with_actor(rng.random());
1788
+
1789
+ let mut changes = vec![];
1790
+ for _ in 0..5 {
1791
+ for _ in 0..10 {
1792
+ let mut tmp = doc2.fork().with_actor(rng.random());
1793
+ let num_splices = rng.random::<u32>() % 10 + 1;
1794
+ for _ in 0..num_splices {
1795
+ let len = tmp.length(&text1) as u32;
1796
+ let index = rng.random::<u32>() % len;
1797
+ let del = std::cmp::min(rng.random::<u32>() % 2, len - index);
1798
+ tmp.splice_text(
1799
+ &text1,
1800
+ index as usize,
1801
+ del as isize,
1802
+ &format!("[{}]", val()),
1803
+ )
1804
+ .unwrap();
1805
+ }
1806
+ let num_marks = rng.random::<u32>() % 3 + 1;
1807
+ for _ in 0..num_marks {
1808
+ let len = tmp.length(&text1) as u32;
1809
+ let a = rng.random::<u32>() % len;
1810
+ let b = rng.random::<u32>() % len;
1811
+ if a == b {
1812
+ continue;
1813
+ }
1814
+ let start = std::cmp::min(a, b);
1815
+ let end = std::cmp::max(a, b);
1816
+ let name = "bold".into();
1817
+ let value = ScalarValue::from(val());
1818
+ let mark = Mark {
1819
+ start: start as usize,
1820
+ end: end as usize,
1821
+ name,
1822
+ value,
1823
+ };
1824
+ tmp.mark(&text1, mark, ExpandMark::After).unwrap();
1825
+ }
1826
+ let change = tmp.get_last_local_change().unwrap();
1827
+ changes.push(change);
1828
+ }
1829
+ merge_and_diff(&mut doc2, &mut doc2_copy, &changes);
1830
+ }
1831
+ merge_and_diff(&mut doc1, &mut doc1_copy, &changes);
1832
+ }
1833
+
1834
+ fn merge_and_diff(a: &mut AutoCommit, a_copy: &mut AutoCommit, changes: &[Change]) {
1835
+ let heads = a.get_heads();
1836
+
1837
+ a.update_diff_cursor();
1838
+ a.apply_changes_batch(changes.to_owned()).unwrap();
1839
+ a.validate_top_index();
1840
+ let pa = a.diff_incremental();
1841
+ let final_heads = a.get_heads();
1842
+
1843
+ a_copy.apply_changes_iter(changes.to_owned()).unwrap();
1844
+ let pb = a_copy.diff(&heads, &final_heads);
1845
+
1846
+ let len = std::cmp::max(pa.len(), pb.len());
1847
+
1848
+ assert_eq!(a.get_heads(), a_copy.get_heads());
1849
+
1850
+ for i in 0..len {
1851
+ if pa.get(i) != pb.get(i) {
1852
+ log!(" i={} ", i);
1853
+ log!(" pa={:?}", pa.get(i));
1854
+ log!(" pb={:?}", pb.get(i));
1855
+ }
1856
+ }
1857
+
1858
+ if pa != pb {
1859
+ panic!()
1860
+ }
1861
+ }
1862
+
1863
+ #[test]
1864
+ fn map_key_conflict() {
1865
+ let mut rng = make_rng();
1866
+ let mut doc = AutoCommit::new().with_actor(rng.random());
1867
+
1868
+ doc.put(&ROOT, "key1", "value1").unwrap();
1869
+
1870
+ const CYCLES: u32 = 10;
1871
+ const DOCS: u32 = 5;
1872
+ const KEYS: u32 = 4;
1873
+
1874
+ let mut docs = vec![];
1875
+
1876
+ for _ in 0..DOCS {
1877
+ docs.push(doc.fork().with_actor(rng.random()));
1878
+ }
1879
+
1880
+ for _ in 0..CYCLES {
1881
+ for d in &mut docs {
1882
+ for _ in 0..10 {
1883
+ let k = rng.random::<u32>() % KEYS;
1884
+ let val = rng.random::<u32>();
1885
+ d.put(&ROOT, format!("key{}", k), format!("value{}", val))
1886
+ .unwrap();
1887
+ }
1888
+ let k = rng.random::<u32>() % KEYS;
1889
+ let _ = d.delete(&ROOT, format!("key{}", k));
1890
+ }
1891
+
1892
+ let changes: Vec<_> = docs
1893
+ .iter_mut()
1894
+ .map(|d| d.get_last_local_change().unwrap())
1895
+ .collect();
1896
+
1897
+ doc.apply_changes(changes).unwrap();
1898
+
1899
+ doc.validate_top_index();
1900
+ }
1901
+ }
1902
+
1903
+ #[test]
1904
+ fn list_element_conflict() {
1905
+ let mut rng = make_rng();
1906
+ let mut doc = AutoCommit::new().with_actor(rng.random());
1907
+
1908
+ let list = doc.put_object(&ROOT, "list", ObjType::List).unwrap();
1909
+
1910
+ const CYCLES: u32 = 5;
1911
+ const DOCS: u32 = 6;
1912
+ const KEYS: u32 = 3;
1913
+
1914
+ for i in 0..KEYS {
1915
+ doc.insert(&list, i as usize, "_").unwrap();
1916
+ }
1917
+
1918
+ let mut docs = vec![];
1919
+
1920
+ for _ in 0..DOCS {
1921
+ docs.push(doc.fork().with_actor(rng.random()));
1922
+ }
1923
+
1924
+ for _ in 0..CYCLES {
1925
+ for d in &mut docs {
1926
+ for _ in 0..3 {
1927
+ let k = rng.random::<u32>() % KEYS;
1928
+ let val = rng.random::<u32>();
1929
+ d.put(&list, k as usize, format!("value{}", val)).unwrap();
1930
+ }
1931
+ }
1932
+
1933
+ let changes: Vec<_> = docs
1934
+ .iter_mut()
1935
+ .map(|d| d.get_last_local_change().unwrap())
1936
+ .collect();
1937
+
1938
+ doc.apply_changes(changes).unwrap();
1939
+ doc.validate_top_index();
1940
+ }
1941
+ }
1942
+
1943
+ #[test]
1944
+ fn conflicts_with_isolate() {
1945
+ let mut rng = make_rng();
1946
+ let mut doc = AutoCommit::new().with_actor(rng.random());
1947
+
1948
+ let list = doc.put_object(&ROOT, "list", ObjType::List).unwrap();
1949
+ let map = doc.put_object(&ROOT, "map", ObjType::Map).unwrap();
1950
+ doc.insert(&list, 0, "_").unwrap();
1951
+ doc.put(&map, "key", "_").unwrap();
1952
+
1953
+ const CYCLES: u32 = 5;
1954
+ const DOCS: u32 = 6;
1955
+
1956
+ let mut docs = vec![];
1957
+ let mut heads = vec![doc.get_heads()];
1958
+
1959
+ for _ in 0..DOCS {
1960
+ docs.push(doc.fork().with_actor(rng.random()));
1961
+ }
1962
+
1963
+ for _ in 0..CYCLES {
1964
+ for d in &mut docs {
1965
+ let head = rng.random::<u32>() % (heads.len() as u32);
1966
+ d.isolate(&heads[head as usize]);
1967
+ for _ in 0..3 {
1968
+ let del = rng.random::<u32>() % 5;
1969
+ let val = rng.random::<u32>();
1970
+ let len = d.length(&list);
1971
+ let val = format!("value{}", val);
1972
+ if del == 0 {
1973
+ if len > 0 {
1974
+ d.delete(&list, 0).unwrap();
1975
+ }
1976
+ d.delete(&map, "key").unwrap();
1977
+ } else {
1978
+ if len > 0 {
1979
+ d.put(&list, 0, &val).unwrap();
1980
+ } else {
1981
+ d.insert(&list, 0, &val).unwrap();
1982
+ }
1983
+ d.put(&map, "key", &val).unwrap();
1984
+ }
1985
+ }
1986
+ d.integrate();
1987
+ d.validate_top_index();
1988
+ }
1989
+
1990
+ let changes: Vec<_> = docs
1991
+ .iter_mut()
1992
+ .map(|d| d.get_last_local_change().unwrap())
1993
+ .collect();
1994
+
1995
+ doc.apply_changes(changes).unwrap();
1996
+
1997
+ heads.push(doc.get_heads());
1998
+
1999
+ doc.validate_top_index();
2000
+ }
2001
+ }
2002
+ }