Skip to content

Commit

Permalink
Add images
Browse files Browse the repository at this point in the history
  • Loading branch information
MoonGyu1 authored Aug 25, 2023
1 parent ffed1e7 commit 9af9634
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions design/concurrent-tree-editing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This document introduces the `Tree` data structure, and explains the operations

### Goals

This document aims to help new SDK contributors understand the overall `Tree`` data structure and explain how Yorkie ensures consistency when multiple clients are editing concurrently.
This document aims to help new SDK contributors understand the overall `Tree` data structure and explain how Yorkie ensures consistency when multiple clients are editing concurrently.

### Non-Goals

Expand All @@ -27,13 +27,14 @@ In yorkie, a JSON-like `Tree` is used to represent the document model of a tree-

This tree-based document model resembles XML tree and consists of element nodes and text nodes. element nodes can have attributes, and text nodes contain a string as their value. For example:

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/b5500d8b-43db-4d89-983d-5708b7041cc4" width="500" />


**Operation**

The JSON-like `Tree` provides specialized operations tailored for text editing rather than typical operations of a general tree. To specify the operation's range, an `index` is used. For example:

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/88d6acde-6775-4af2-ae32-ba7a6b324abc" width="450" />

These `index`es are assigned in order at positions where the user's cursor can reach. These `index`es draw inspiration from ProseMirror's index and share a similar structural concept.

Expand All @@ -45,7 +46,7 @@ Users can use the `Edit` operation to insert or delete nodes within the `Tree`.

Where `fromIdx` is the starting position of editing, `toIdx` is the ending position, and `contents` represent the nodes to be inserted. If `contents` are omitted, the operation only deletes nodes between `fromIdx` and `toIdx`.

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/c1184839-3e50-41fa-b558-8c0677285660" width="450" />

[코드]

Expand All @@ -61,17 +62,17 @@ Users can use the `Style` operation to specify attributes for the element nodes

**Tree Coordinate System**

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/08c1e917-08cf-492c-84c2-cf72b98c38f3" width="600" />

Yorkie implements the above data structure to create a JSON-like `Document`, which consists of different layers, each with its own coordinate system. The dependency graph above can be divided into three main groups. The **JSON-like** group directly used by users to edit JSON-like `Document`s. The **CRDT** Group is utilized from the JSON-like group to resolve conflicts in concurrent editing situations. Finally, the **common** group is used for the detailed implementation of CRDT group and serves general purposes.

Thus, the JSON-like `Tree`, introduced in this document, has dependencies such as **'`Tree``CRDTTree``IndexTree`'**, and each layer has its own coordinate system:

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/33519a1e-c8cb-4b4d-9d0e-d2fcc2052013" width="450" />

These coordinate systems transform in the order of '`index(path)``IndexTree.TreePos``CRDTTree.TreeNodeID``CRDTTree.TreePos`'.

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/af339dc7-5c03-4cae-a1cb-f5879bfce3be" />

1. `index``IndexTree.TreePos`

Expand Down Expand Up @@ -118,11 +119,11 @@ In the case of local editing, the given `index`es are converted to `CRDTTree.Tre

**Coverage**

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/c911ffb4-9021-4a1f-9a11-b8e28fb41435" width="850" >

Using conditions such as range type, node type, and edit type, 27 possible cases of concurrent editing can be represented.

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/d1054938-b701-4e90-bcbb-8ff5d62b19d4" width="400">

Eventual consistency is guaranteed for these 27 cases. In addition, eventual consistency is ensured for the following edge cases:

Expand All @@ -137,7 +138,7 @@ Eventual consistency is guaranteed for these 27 cases. In addition, eventual con

`latestCreatedAtMapByActor` is a map that stores the latest creation time by actor for the nodes included in the editing range. However, relying solely on the typical `lamport` clocks that represent local clock of clients, it's not possible to determine if two events are causally related or concurrent. For instance:

[이미지]
<img src="https://github.com/yorkie-team/yorkie/assets/78714820/cc025542-2c85-40ef-b846-157f38177487" width="450" />

In the case of the example above, during the process of synchronizing operations between clients A and B, client A is unaware of the existence of '`c`' when client B performs `Edit(0,2)`. As a result, an issue arises where the element '`c`', which is within the contained range, gets deleted together.

Expand Down

1 comment on commit 9af9634

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go Benchmark

Benchmark suite Current: 9af9634 Previous: e0e7b17 Ratio
BenchmarkDocument/constructor_test - ns/op 1832 ns/op 1631 ns/op 1.12
BenchmarkDocument/constructor_test - B/op 984 B/op 984 B/op 1
BenchmarkDocument/constructor_test - allocs/op 16 allocs/op 16 allocs/op 1
BenchmarkDocument/status_test - ns/op 1071 ns/op 1568 ns/op 0.68
BenchmarkDocument/status_test - B/op 952 B/op 952 B/op 1
BenchmarkDocument/status_test - allocs/op 14 allocs/op 14 allocs/op 1
BenchmarkDocument/equals_test - ns/op 10280 ns/op 9842 ns/op 1.04
BenchmarkDocument/equals_test - B/op 6192 B/op 6192 B/op 1
BenchmarkDocument/equals_test - allocs/op 106 allocs/op 106 allocs/op 1
BenchmarkDocument/nested_update_test - ns/op 25637 ns/op 25128 ns/op 1.02
BenchmarkDocument/nested_update_test - B/op 11689 B/op 11689 B/op 1
BenchmarkDocument/nested_update_test - allocs/op 248 allocs/op 248 allocs/op 1
BenchmarkDocument/delete_test - ns/op 41012 ns/op 33223 ns/op 1.23
BenchmarkDocument/delete_test - B/op 14914 B/op 14913 B/op 1.00
BenchmarkDocument/delete_test - allocs/op 327 allocs/op 327 allocs/op 1
BenchmarkDocument/object_test - ns/op 15396 ns/op 11854 ns/op 1.30
BenchmarkDocument/object_test - B/op 6449 B/op 6449 B/op 1
BenchmarkDocument/object_test - allocs/op 110 allocs/op 110 allocs/op 1
BenchmarkDocument/array_test - ns/op 43069 ns/op 40251 ns/op 1.07
BenchmarkDocument/array_test - B/op 11546 B/op 11546 B/op 1
BenchmarkDocument/array_test - allocs/op 264 allocs/op 264 allocs/op 1
BenchmarkDocument/text_test - ns/op 47271 ns/op 42988 ns/op 1.10
BenchmarkDocument/text_test - B/op 14618 B/op 14618 B/op 1
BenchmarkDocument/text_test - allocs/op 470 allocs/op 470 allocs/op 1
BenchmarkDocument/text_composition_test - ns/op 50287 ns/op 44497 ns/op 1.13
BenchmarkDocument/text_composition_test - B/op 18002 B/op 18002 B/op 1
BenchmarkDocument/text_composition_test - allocs/op 471 allocs/op 471 allocs/op 1
BenchmarkDocument/rich_text_test - ns/op 133359 ns/op 121385 ns/op 1.10
BenchmarkDocument/rich_text_test - B/op 36807 B/op 36807 B/op 1
BenchmarkDocument/rich_text_test - allocs/op 1131 allocs/op 1131 allocs/op 1
BenchmarkDocument/counter_test - ns/op 27987 ns/op 24778 ns/op 1.13
BenchmarkDocument/counter_test - B/op 9971 B/op 9971 B/op 1
BenchmarkDocument/counter_test - allocs/op 235 allocs/op 235 allocs/op 1
BenchmarkDocument/text_edit_gc_100 - ns/op 5033786 ns/op 4953916 ns/op 1.02
BenchmarkDocument/text_edit_gc_100 - B/op 1553234 B/op 1553154 B/op 1.00
BenchmarkDocument/text_edit_gc_100 - allocs/op 17161 allocs/op 17162 allocs/op 1.00
BenchmarkDocument/text_edit_gc_1000 - ns/op 361644520 ns/op 415539332 ns/op 0.87
BenchmarkDocument/text_edit_gc_1000 - B/op 136643421 B/op 136654077 B/op 1.00
BenchmarkDocument/text_edit_gc_1000 - allocs/op 210776 allocs/op 210807 allocs/op 1.00
BenchmarkDocument/text_split_gc_100 - ns/op 5303865 ns/op 5163744 ns/op 1.03
BenchmarkDocument/text_split_gc_100 - B/op 2217699 B/op 2217867 B/op 1.00
BenchmarkDocument/text_split_gc_100 - allocs/op 16590 allocs/op 16589 allocs/op 1.00
BenchmarkDocument/text_split_gc_1000 - ns/op 429811250 ns/op 459261506 ns/op 0.94
BenchmarkDocument/text_split_gc_1000 - B/op 214869629 B/op 214825368 B/op 1.00
BenchmarkDocument/text_split_gc_1000 - allocs/op 211499 allocs/op 211278 allocs/op 1.00
BenchmarkDocument/text_delete_all_10000 - ns/op 22509980 ns/op 21640628 ns/op 1.04
BenchmarkDocument/text_delete_all_10000 - B/op 5904605 B/op 5904350 B/op 1.00
BenchmarkDocument/text_delete_all_10000 - allocs/op 41128 allocs/op 41125 allocs/op 1.00
BenchmarkDocument/text_delete_all_100000 - ns/op 311090095 ns/op 293915504 ns/op 1.06
BenchmarkDocument/text_delete_all_100000 - B/op 53874832 B/op 53849444 B/op 1.00
BenchmarkDocument/text_delete_all_100000 - allocs/op 415955 allocs/op 416019 allocs/op 1.00
BenchmarkDocument/text_100 - ns/op 404343 ns/op 368364 ns/op 1.10
BenchmarkDocument/text_100 - B/op 118214 B/op 118211 B/op 1.00
BenchmarkDocument/text_100 - allocs/op 5074 allocs/op 5074 allocs/op 1
BenchmarkDocument/text_1000 - ns/op 4141072 ns/op 4020698 ns/op 1.03
BenchmarkDocument/text_1000 - B/op 1152831 B/op 1152828 B/op 1.00
BenchmarkDocument/text_1000 - allocs/op 50078 allocs/op 50078 allocs/op 1
BenchmarkDocument/array_1000 - ns/op 2054339 ns/op 1982625 ns/op 1.04
BenchmarkDocument/array_1000 - B/op 1102768 B/op 1102720 B/op 1.00
BenchmarkDocument/array_1000 - allocs/op 11867 allocs/op 11867 allocs/op 1
BenchmarkDocument/array_10000 - ns/op 23976178 ns/op 24133350 ns/op 0.99
BenchmarkDocument/array_10000 - B/op 9907029 B/op 9908265 B/op 1.00
BenchmarkDocument/array_10000 - allocs/op 120719 allocs/op 120725 allocs/op 1.00
BenchmarkDocument/array_gc_100 - ns/op 214536 ns/op 218206 ns/op 0.98
BenchmarkDocument/array_gc_100 - B/op 98170 B/op 98170 B/op 1
BenchmarkDocument/array_gc_100 - allocs/op 1243 allocs/op 1243 allocs/op 1
BenchmarkDocument/array_gc_1000 - ns/op 2281142 ns/op 2439002 ns/op 0.94
BenchmarkDocument/array_gc_1000 - B/op 1170430 B/op 1170334 B/op 1.00
BenchmarkDocument/array_gc_1000 - allocs/op 12906 allocs/op 12906 allocs/op 1
BenchmarkDocument/counter_1000 - ns/op 335024 ns/op 348837 ns/op 0.96
BenchmarkDocument/counter_1000 - B/op 198533 B/op 198533 B/op 1
BenchmarkDocument/counter_1000 - allocs/op 6503 allocs/op 6503 allocs/op 1
BenchmarkDocument/counter_10000 - ns/op 3721532 ns/op 3797783 ns/op 0.98
BenchmarkDocument/counter_10000 - B/op 2165464 B/op 2165466 B/op 1.00
BenchmarkDocument/counter_10000 - allocs/op 69510 allocs/op 69510 allocs/op 1
BenchmarkDocument/object_1000 - ns/op 2332304 ns/op 2176596 ns/op 1.07
BenchmarkDocument/object_1000 - B/op 1451452 B/op 1451413 B/op 1.00
BenchmarkDocument/object_1000 - allocs/op 9915 allocs/op 9915 allocs/op 1
BenchmarkDocument/object_10000 - ns/op 27993099 ns/op 29075180 ns/op 0.96
BenchmarkDocument/object_10000 - B/op 12369864 B/op 12368142 B/op 1.00
BenchmarkDocument/object_10000 - allocs/op 101220 allocs/op 101216 allocs/op 1.00
BenchmarkRPC/client_to_server - ns/op 482365441 ns/op 623741911 ns/op 0.77
BenchmarkRPC/client_to_server - B/op 12270514 B/op 12446728 B/op 0.99
BenchmarkRPC/client_to_server - allocs/op 177231 allocs/op 177074 allocs/op 1.00
BenchmarkRPC/client_to_client_via_server - ns/op 809211391 ns/op 1007493091 ns/op 0.80
BenchmarkRPC/client_to_client_via_server - B/op 22666536 B/op 22360952 B/op 1.01
BenchmarkRPC/client_to_client_via_server - allocs/op 331835 allocs/op 315734 allocs/op 1.05
BenchmarkRPC/attach_large_document - ns/op 1649185810 ns/op 1462175961 ns/op 1.13
BenchmarkRPC/attach_large_document - B/op 1809507648 B/op 1799019544 B/op 1.01
BenchmarkRPC/attach_large_document - allocs/op 11049 allocs/op 9450 allocs/op 1.17
BenchmarkRPC/adminCli_to_server - ns/op 691499877 ns/op 824637910 ns/op 0.84
BenchmarkRPC/adminCli_to_server - B/op 20397392 B/op 20415996 B/op 1.00
BenchmarkRPC/adminCli_to_server - allocs/op 321623 allocs/op 321647 allocs/op 1.00
BenchmarkLocker - ns/op 155.6 ns/op 144.4 ns/op 1.08
BenchmarkLocker - B/op 16 B/op 16 B/op 1
BenchmarkLocker - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkLockerParallel - ns/op 152 ns/op 142.7 ns/op 1.07
BenchmarkLockerParallel - B/op 0 B/op 0 B/op NaN
BenchmarkLockerParallel - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkLockerMoreKeys - ns/op 388.8 ns/op 330.2 ns/op 1.18
BenchmarkLockerMoreKeys - B/op 14 B/op 15 B/op 0.93
BenchmarkLockerMoreKeys - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkSync/memory_sync_10_test - ns/op 8833 ns/op 8751 ns/op 1.01
BenchmarkSync/memory_sync_10_test - B/op 1284 B/op 1284 B/op 1
BenchmarkSync/memory_sync_10_test - allocs/op 38 allocs/op 38 allocs/op 1
BenchmarkSync/memory_sync_100_test - ns/op 81099 ns/op 79832 ns/op 1.02
BenchmarkSync/memory_sync_100_test - B/op 8775 B/op 8908 B/op 0.99
BenchmarkSync/memory_sync_100_test - allocs/op 281 allocs/op 289 allocs/op 0.97
BenchmarkSync/memory_sync_1000_test - ns/op 805320 ns/op 763146 ns/op 1.06
BenchmarkSync/memory_sync_1000_test - B/op 82145 B/op 82936 B/op 0.99
BenchmarkSync/memory_sync_1000_test - allocs/op 2596 allocs/op 2647 allocs/op 0.98
BenchmarkSync/memory_sync_10000_test - ns/op 8310115 ns/op 8311071 ns/op 1.00
BenchmarkSync/memory_sync_10000_test - B/op 853773 B/op 879987 B/op 0.97
BenchmarkSync/memory_sync_10000_test - allocs/op 26645 allocs/op 28295 allocs/op 0.94
BenchmarkTextEditing - ns/op 31580123599 ns/op 32727791991 ns/op 0.96
BenchmarkTextEditing - B/op 8456705360 B/op 8456442864 B/op 1.00
BenchmarkTextEditing - allocs/op 20613134 allocs/op 20611911 allocs/op 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.