Skip to content

Commit

Permalink
Add test code for concurrently style with distinct/common key and Fix…
Browse files Browse the repository at this point in the history
… RHT to support concurrency
  • Loading branch information
justiceHui committed Jan 10, 2024
1 parent 13329e4 commit e6a3284
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
10 changes: 9 additions & 1 deletion pkg/document/crdt/rht.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,15 @@ func (rht *RHT) Set(k, v string, executedAt *time.Ticket) {

// Remove removes the Element of the given key.
func (rht *RHT) Remove(k string, executedAt *time.Ticket) string {
if node, ok := rht.nodeMapByKey[k]; ok && executedAt.After(node.updatedAt) {
if node, ok := rht.nodeMapByKey[k]; !ok || executedAt.After(node.updatedAt) {
// NOTE(justiceHui): Even if key is not existed, we must set flag `isRemoved` for concurrency
if node == nil {
rht.numberOfRemovedElement++
newNode := newRHTNode(k, ``, executedAt, true)
rht.nodeMapByKey[k] = newNode
return ""
}

alreadyRemoved := node.isRemoved
if !alreadyRemoved {
rht.numberOfRemovedElement++
Expand Down
6 changes: 5 additions & 1 deletion pkg/document/crdt/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,11 @@ func (t *Tree) RemoveStyle(from, to *TreePos, attributesToRemove []string, edite
err = t.traverseInPosRange(fromParent, fromLeft, toParent, toLeft,
func(token index.TreeToken[*TreeNode], _ bool) {
node := token.Node
if !node.IsRemoved() && !node.IsText() && len(attributesToRemove) > 0 && node.Attrs != nil {
// NOTE(justiceHui): Even if key is not existed, we must set flag `isRemoved` for concurrency
if !node.IsRemoved() && !node.IsText() {
if node.Attrs == nil {
node.Attrs = NewRHT()
}
for _, value := range attributesToRemove {
node.Attrs.Remove(value, editedAt)
}
Expand Down
90 changes: 90 additions & 0 deletions test/integration/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,96 @@ func TestTree(t *testing.T) {
assert.Equal(t, `{"type":"root","children":[{"type":"p","children":[{"type":"text","value":"ab"}]},{"type":"p","children":[{"type":"text","value":"cd"}]}]}`, d2.Root().GetTree("t").Marshal())
})

t.Run("concurrently style test", func(t *testing.T) {
// 0 1 2 3 4 5 6 7 8 9
// <root> <p> a </p> <p> b </p> <p> c </p> </root>
// 0,3 : |----------|
// 3,6 : |----------|
// 6,9 : |----------|

type ranges struct {
from1, to1, from2, to2 int
desc string
}

rangesToTest := []ranges{
{3, 6, 3, 6, `equal`}, // (3, 6) - (3, 6)
{0, 9, 3, 6, `contain`}, // (0, 9) - (3, 6)
{0, 6, 3, 9, `intersect`}, // (0, 6) - (3, 9)
{0, 3, 3, 6, `side-by-side`}, // (0, 3) - (3, 6)
}

operationsToTest := []string{
"remove", // Tree.RemoveStyle(x)
"aa", // Tree.Style({x: aa})
"bb", // Tree.Style({x, bb})
}

runTestStyle := func(interval ranges, op1, op2 string, style1, style2 string) {
clientsInternal := activeClients(t, 2)
c1Internal, c2Internal := clientsInternal[0], clientsInternal[1]
defer deactivateAndCloseClients(t, clientsInternal)

ctx := context.Background()
d1 := document.New(helper.TestDocKey(t))
assert.NoError(t, c1Internal.Attach(ctx, d1))
d2 := document.New(helper.TestDocKey(t))
assert.NoError(t, c2Internal.Attach(ctx, d2))

assert.NoError(t, d1.Update(func(root *json.Object, p *presence.Presence) error {
root.SetNewTree("t", &json.TreeNode{
Type: "root",
Children: []json.TreeNode{
{Type: "p", Children: []json.TreeNode{{Type: "text", Value: "a"}}},
{Type: "p", Children: []json.TreeNode{{Type: "text", Value: "b"}}},
{Type: "p", Children: []json.TreeNode{{Type: "text", Value: "c"}}},
},
})
return nil
}))
assert.NoError(t, c1Internal.Sync(ctx))
assert.NoError(t, c2Internal.Sync(ctx))
assert.Equal(t, `<root><p>a</p><p>b</p><p>c</p></root>`, d1.Root().GetTree("t").ToXML())
assert.Equal(t, `<root><p>a</p><p>b</p><p>c</p></root>`, d2.Root().GetTree("t").ToXML())

runOperation := func(doc *document.Document, from, to int, op string, style string) {
if op == `remove` {
assert.NoError(t, doc.Update(func(root *json.Object, p *presence.Presence) error {
root.GetTree("t").RemoveStyle(from, to, []string{style})
return nil
}))
} else {
assert.NoError(t, doc.Update(func(root *json.Object, p *presence.Presence) error {
root.GetTree("t").Style(from, to, map[string]string{style: op})
return nil
}))
}
}

runOperation(d1, interval.from1, interval.to1, op1, style1)
runOperation(d2, interval.from2, interval.to2, op2, style2)
syncClientsThenAssertEqual(t, []clientAndDocPair{{c1Internal, d1}, {c2Internal, d2}})
}

// distinct style test
for _, interval := range rangesToTest {
for i := 0; i < 2; i++ {
for j := 0; j < 2; j++ {
runTestStyle(interval, operationsToTest[i], operationsToTest[j], "bold", "italic")
}
}
}

// common style test
for _, interval := range rangesToTest {
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
runTestStyle(interval, operationsToTest[i], operationsToTest[j], "bold", "bold")
}
}
}
})

// Concurrent editing, overlapping range test
t.Run("concurrently delete overlapping elements test", func(t *testing.T) {
ctx := context.Background()
Expand Down

1 comment on commit e6a3284

@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: e6a3284 Previous: 4ea4eae Ratio
BenchmarkDocument/constructor_test - ns/op 1369 ns/op 1336 ns/op 1.02
BenchmarkDocument/constructor_test - B/op 1208 B/op 1208 B/op 1
BenchmarkDocument/constructor_test - allocs/op 20 allocs/op 20 allocs/op 1
BenchmarkDocument/status_test - ns/op 782.7 ns/op 785.2 ns/op 1.00
BenchmarkDocument/status_test - B/op 1176 B/op 1176 B/op 1
BenchmarkDocument/status_test - allocs/op 18 allocs/op 18 allocs/op 1
BenchmarkDocument/equals_test - ns/op 7135 ns/op 7092 ns/op 1.01
BenchmarkDocument/equals_test - B/op 6913 B/op 6913 B/op 1
BenchmarkDocument/equals_test - allocs/op 120 allocs/op 120 allocs/op 1
BenchmarkDocument/nested_update_test - ns/op 16092 ns/op 16151 ns/op 1.00
BenchmarkDocument/nested_update_test - B/op 11962 B/op 11963 B/op 1.00
BenchmarkDocument/nested_update_test - allocs/op 254 allocs/op 254 allocs/op 1
BenchmarkDocument/delete_test - ns/op 21828 ns/op 21933 ns/op 1.00
BenchmarkDocument/delete_test - B/op 15188 B/op 15188 B/op 1
BenchmarkDocument/delete_test - allocs/op 333 allocs/op 333 allocs/op 1
BenchmarkDocument/object_test - ns/op 8332 ns/op 8361 ns/op 1.00
BenchmarkDocument/object_test - B/op 6721 B/op 6721 B/op 1
BenchmarkDocument/object_test - allocs/op 116 allocs/op 116 allocs/op 1
BenchmarkDocument/array_test - ns/op 28392 ns/op 32610 ns/op 0.87
BenchmarkDocument/array_test - B/op 11819 B/op 11819 B/op 1
BenchmarkDocument/array_test - allocs/op 270 allocs/op 270 allocs/op 1
BenchmarkDocument/text_test - ns/op 34735 ns/op 30219 ns/op 1.15
BenchmarkDocument/text_test - B/op 14884 B/op 14795 B/op 1.01
BenchmarkDocument/text_test - allocs/op 468 allocs/op 468 allocs/op 1
BenchmarkDocument/text_composition_test - ns/op 28886 ns/op 28748 ns/op 1.00
BenchmarkDocument/text_composition_test - B/op 18398 B/op 18278 B/op 1.01
BenchmarkDocument/text_composition_test - allocs/op 477 allocs/op 477 allocs/op 1
BenchmarkDocument/rich_text_test - ns/op 79714 ns/op 79589 ns/op 1.00
BenchmarkDocument/rich_text_test - B/op 38645 B/op 38540 B/op 1.00
BenchmarkDocument/rich_text_test - allocs/op 1147 allocs/op 1147 allocs/op 1
BenchmarkDocument/counter_test - ns/op 16569 ns/op 16595 ns/op 1.00
BenchmarkDocument/counter_test - B/op 10210 B/op 10210 B/op 1
BenchmarkDocument/counter_test - allocs/op 236 allocs/op 236 allocs/op 1
BenchmarkDocument/text_edit_gc_100 - ns/op 2868401 ns/op 2884438 ns/op 0.99
BenchmarkDocument/text_edit_gc_100 - B/op 1658573 B/op 1655268 B/op 1.00
BenchmarkDocument/text_edit_gc_100 - allocs/op 17093 allocs/op 17093 allocs/op 1
BenchmarkDocument/text_edit_gc_1000 - ns/op 229096174 ns/op 230271811 ns/op 0.99
BenchmarkDocument/text_edit_gc_1000 - B/op 144402339 B/op 144376180 B/op 1.00
BenchmarkDocument/text_edit_gc_1000 - allocs/op 201031 allocs/op 201058 allocs/op 1.00
BenchmarkDocument/text_split_gc_100 - ns/op 3383593 ns/op 3383745 ns/op 1.00
BenchmarkDocument/text_split_gc_100 - B/op 2316594 B/op 2314004 B/op 1.00
BenchmarkDocument/text_split_gc_100 - allocs/op 16192 allocs/op 16197 allocs/op 1.00
BenchmarkDocument/text_split_gc_1000 - ns/op 288177070 ns/op 288385837 ns/op 1.00
BenchmarkDocument/text_split_gc_1000 - B/op 228937908 B/op 228887600 B/op 1.00
BenchmarkDocument/text_split_gc_1000 - allocs/op 204042 allocs/op 203930 allocs/op 1.00
BenchmarkDocument/text_delete_all_10000 - ns/op 10800239 ns/op 11000897 ns/op 0.98
BenchmarkDocument/text_delete_all_10000 - B/op 5811589 B/op 5809330 B/op 1.00
BenchmarkDocument/text_delete_all_10000 - allocs/op 40680 allocs/op 40669 allocs/op 1.00
BenchmarkDocument/text_delete_all_100000 - ns/op 175983937 ns/op 182534409 ns/op 0.96
BenchmarkDocument/text_delete_all_100000 - B/op 81888338 B/op 81903677 B/op 1.00
BenchmarkDocument/text_delete_all_100000 - allocs/op 411573 allocs/op 411647 allocs/op 1.00
BenchmarkDocument/text_100 - ns/op 218880 ns/op 218449 ns/op 1.00
BenchmarkDocument/text_100 - B/op 120107 B/op 118483 B/op 1.01
BenchmarkDocument/text_100 - allocs/op 5080 allocs/op 5080 allocs/op 1
BenchmarkDocument/text_1000 - ns/op 2386014 ns/op 2374004 ns/op 1.01
BenchmarkDocument/text_1000 - B/op 1169092 B/op 1153070 B/op 1.01
BenchmarkDocument/text_1000 - allocs/op 50084 allocs/op 50084 allocs/op 1
BenchmarkDocument/array_1000 - ns/op 1172600 ns/op 1196526 ns/op 0.98
BenchmarkDocument/array_1000 - B/op 1091281 B/op 1091301 B/op 1.00
BenchmarkDocument/array_1000 - allocs/op 11826 allocs/op 11826 allocs/op 1
BenchmarkDocument/array_10000 - ns/op 12910013 ns/op 13416629 ns/op 0.96
BenchmarkDocument/array_10000 - B/op 9799370 B/op 9799640 B/op 1.00
BenchmarkDocument/array_10000 - allocs/op 120288 allocs/op 120291 allocs/op 1.00
BenchmarkDocument/array_gc_100 - ns/op 142597 ns/op 143463 ns/op 0.99
BenchmarkDocument/array_gc_100 - B/op 132491 B/op 132481 B/op 1.00
BenchmarkDocument/array_gc_100 - allocs/op 1248 allocs/op 1248 allocs/op 1
BenchmarkDocument/array_gc_1000 - ns/op 1359641 ns/op 1378307 ns/op 0.99
BenchmarkDocument/array_gc_1000 - B/op 1158964 B/op 1158986 B/op 1.00
BenchmarkDocument/array_gc_1000 - allocs/op 12865 allocs/op 12865 allocs/op 1
BenchmarkDocument/counter_1000 - ns/op 196837 ns/op 198075 ns/op 0.99
BenchmarkDocument/counter_1000 - B/op 192853 B/op 192851 B/op 1.00
BenchmarkDocument/counter_1000 - allocs/op 5765 allocs/op 5765 allocs/op 1
BenchmarkDocument/counter_10000 - ns/op 2127368 ns/op 2156556 ns/op 0.99
BenchmarkDocument/counter_10000 - B/op 2087768 B/op 2087769 B/op 1.00
BenchmarkDocument/counter_10000 - allocs/op 59772 allocs/op 59772 allocs/op 1
BenchmarkDocument/object_1000 - ns/op 1310565 ns/op 1317018 ns/op 1.00
BenchmarkDocument/object_1000 - B/op 1427980 B/op 1427906 B/op 1.00
BenchmarkDocument/object_1000 - allocs/op 9845 allocs/op 9845 allocs/op 1
BenchmarkDocument/object_10000 - ns/op 14249549 ns/op 14690867 ns/op 0.97
BenchmarkDocument/object_10000 - B/op 12165926 B/op 12166752 B/op 1.00
BenchmarkDocument/object_10000 - allocs/op 100557 allocs/op 100562 allocs/op 1.00
BenchmarkDocument/tree_100 - ns/op 996702 ns/op 1009303 ns/op 0.99
BenchmarkDocument/tree_100 - B/op 943673 B/op 943675 B/op 1.00
BenchmarkDocument/tree_100 - allocs/op 6099 allocs/op 6099 allocs/op 1
BenchmarkDocument/tree_1000 - ns/op 73554597 ns/op 72072982 ns/op 1.02
BenchmarkDocument/tree_1000 - B/op 86460395 B/op 86459854 B/op 1.00
BenchmarkDocument/tree_1000 - allocs/op 60113 allocs/op 60114 allocs/op 1.00
BenchmarkDocument/tree_10000 - ns/op 9260221728 ns/op 9443141797 ns/op 0.98
BenchmarkDocument/tree_10000 - B/op 8580981880 B/op 8580991992 B/op 1.00
BenchmarkDocument/tree_10000 - allocs/op 600238 allocs/op 600248 allocs/op 1.00
BenchmarkDocument/tree_delete_all_1000 - ns/op 71533036 ns/op 71663719 ns/op 1.00
BenchmarkDocument/tree_delete_all_1000 - B/op 86990238 B/op 86990239 B/op 1.00
BenchmarkDocument/tree_delete_all_1000 - allocs/op 67749 allocs/op 67749 allocs/op 1
BenchmarkDocument/tree_edit_gc_100 - ns/op 3600533 ns/op 3632525 ns/op 0.99
BenchmarkDocument/tree_edit_gc_100 - B/op 4120990 B/op 4121046 B/op 1.00
BenchmarkDocument/tree_edit_gc_100 - allocs/op 14356 allocs/op 14356 allocs/op 1
BenchmarkDocument/tree_edit_gc_1000 - ns/op 296150432 ns/op 295614209 ns/op 1.00
BenchmarkDocument/tree_edit_gc_1000 - B/op 383467356 B/op 383467646 B/op 1.00
BenchmarkDocument/tree_edit_gc_1000 - allocs/op 145400 allocs/op 145413 allocs/op 1.00
BenchmarkDocument/tree_split_gc_100 - ns/op 2424754 ns/op 2433512 ns/op 1.00
BenchmarkDocument/tree_split_gc_100 - B/op 2386819 B/op 2386869 B/op 1.00
BenchmarkDocument/tree_split_gc_100 - allocs/op 10341 allocs/op 10341 allocs/op 1
BenchmarkDocument/tree_split_gc_1000 - ns/op 177156471 ns/op 183611128 ns/op 0.96
BenchmarkDocument/tree_split_gc_1000 - B/op 221989945 B/op 221991942 B/op 1.00
BenchmarkDocument/tree_split_gc_1000 - allocs/op 112244 allocs/op 112259 allocs/op 1.00
BenchmarkRPC/client_to_server - ns/op 357659078 ns/op 355717978 ns/op 1.01
BenchmarkRPC/client_to_server - B/op 17794869 B/op 17228981 B/op 1.03
BenchmarkRPC/client_to_server - allocs/op 166876 allocs/op 166831 allocs/op 1.00
BenchmarkRPC/client_to_client_via_server - ns/op 609989606 ns/op 606482578 ns/op 1.01
BenchmarkRPC/client_to_client_via_server - B/op 31229984 B/op 32116544 B/op 0.97
BenchmarkRPC/client_to_client_via_server - allocs/op 312399 allocs/op 312901 allocs/op 1.00
BenchmarkRPC/attach_large_document - ns/op 1234060163 ns/op 1170164855 ns/op 1.05
BenchmarkRPC/attach_large_document - B/op 1869051616 B/op 1888403296 B/op 0.99
BenchmarkRPC/attach_large_document - allocs/op 7547 allocs/op 7527 allocs/op 1.00
BenchmarkRPC/adminCli_to_server - ns/op 540020885 ns/op 542495623 ns/op 1.00
BenchmarkRPC/adminCli_to_server - B/op 35981596 B/op 36802124 B/op 0.98
BenchmarkRPC/adminCli_to_server - allocs/op 289651 allocs/op 289677 allocs/op 1.00
BenchmarkLocker - ns/op 65.84 ns/op 65.96 ns/op 1.00
BenchmarkLocker - B/op 16 B/op 16 B/op 1
BenchmarkLocker - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkLockerParallel - ns/op 38.76 ns/op 38.94 ns/op 1.00
BenchmarkLockerParallel - B/op 0 B/op 0 B/op NaN
BenchmarkLockerParallel - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkLockerMoreKeys - ns/op 147.5 ns/op 141.9 ns/op 1.04
BenchmarkLockerMoreKeys - B/op 15 B/op 15 B/op 1
BenchmarkLockerMoreKeys - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkChange/Push_10_Changes - ns/op 3785059 ns/op 3782260 ns/op 1.00
BenchmarkChange/Push_10_Changes - B/op 125713 B/op 125995 B/op 1.00
BenchmarkChange/Push_10_Changes - allocs/op 1254 allocs/op 1253 allocs/op 1.00
BenchmarkChange/Push_100_Changes - ns/op 14065727 ns/op 14268879 ns/op 0.99
BenchmarkChange/Push_100_Changes - B/op 649640 B/op 639349 B/op 1.02
BenchmarkChange/Push_100_Changes - allocs/op 6539 allocs/op 6540 allocs/op 1.00
BenchmarkChange/Push_1000_Changes - ns/op 112545946 ns/op 114005417 ns/op 0.99
BenchmarkChange/Push_1000_Changes - B/op 5902491 B/op 6146349 B/op 0.96
BenchmarkChange/Push_1000_Changes - allocs/op 62155 allocs/op 62158 allocs/op 1.00
BenchmarkChange/Pull_10_Changes - ns/op 2860311 ns/op 2883610 ns/op 0.99
BenchmarkChange/Pull_10_Changes - B/op 100633 B/op 100810 B/op 1.00
BenchmarkChange/Pull_10_Changes - allocs/op 951 allocs/op 952 allocs/op 1.00
BenchmarkChange/Pull_100_Changes - ns/op 4311423 ns/op 4323201 ns/op 1.00
BenchmarkChange/Pull_100_Changes - B/op 257907 B/op 258124 B/op 1.00
BenchmarkChange/Pull_100_Changes - allocs/op 3154 allocs/op 3153 allocs/op 1.00
BenchmarkChange/Pull_1000_Changes - ns/op 8300351 ns/op 8208312 ns/op 1.01
BenchmarkChange/Pull_1000_Changes - B/op 1394700 B/op 1395853 B/op 1.00
BenchmarkChange/Pull_1000_Changes - allocs/op 26872 allocs/op 26874 allocs/op 1.00
BenchmarkSnapshot/Push_3KB_snapshot - ns/op 16598198 ns/op 16781594 ns/op 0.99
BenchmarkSnapshot/Push_3KB_snapshot - B/op 807232 B/op 806918 B/op 1.00
BenchmarkSnapshot/Push_3KB_snapshot - allocs/op 6543 allocs/op 6543 allocs/op 1
BenchmarkSnapshot/Push_30KB_snapshot - ns/op 117060348 ns/op 117538584 ns/op 1.00
BenchmarkSnapshot/Push_30KB_snapshot - B/op 6320404 B/op 6293910 B/op 1.00
BenchmarkSnapshot/Push_30KB_snapshot - allocs/op 62163 allocs/op 62159 allocs/op 1.00
BenchmarkSnapshot/Pull_3KB_snapshot - ns/op 6547132 ns/op 6555276 ns/op 1.00
BenchmarkSnapshot/Pull_3KB_snapshot - B/op 904604 B/op 905327 B/op 1.00
BenchmarkSnapshot/Pull_3KB_snapshot - allocs/op 14876 allocs/op 14879 allocs/op 1.00
BenchmarkSnapshot/Pull_30KB_snapshot - ns/op 14760490 ns/op 14921599 ns/op 0.99
BenchmarkSnapshot/Pull_30KB_snapshot - B/op 6979816 B/op 6982547 B/op 1.00
BenchmarkSnapshot/Pull_30KB_snapshot - allocs/op 144142 allocs/op 144138 allocs/op 1.00
BenchmarkSync/memory_sync_10_test - ns/op 6851 ns/op 6869 ns/op 1.00
BenchmarkSync/memory_sync_10_test - B/op 1286 B/op 1286 B/op 1
BenchmarkSync/memory_sync_10_test - allocs/op 38 allocs/op 38 allocs/op 1
BenchmarkSync/memory_sync_100_test - ns/op 51440 ns/op 51839 ns/op 0.99
BenchmarkSync/memory_sync_100_test - B/op 8650 B/op 8646 B/op 1.00
BenchmarkSync/memory_sync_100_test - allocs/op 273 allocs/op 273 allocs/op 1
BenchmarkSync/memory_sync_1000_test - ns/op 584778 ns/op 597671 ns/op 0.98
BenchmarkSync/memory_sync_1000_test - B/op 74624 B/op 74301 B/op 1.00
BenchmarkSync/memory_sync_1000_test - allocs/op 2125 allocs/op 2106 allocs/op 1.01
BenchmarkSync/memory_sync_10000_test - ns/op 6987984 ns/op 7337210 ns/op 0.95
BenchmarkSync/memory_sync_10000_test - B/op 761163 B/op 759441 B/op 1.00
BenchmarkSync/memory_sync_10000_test - allocs/op 20612 allocs/op 20499 allocs/op 1.01
BenchmarkTextEditing - ns/op 18573575789 ns/op 18812245791 ns/op 0.99
BenchmarkTextEditing - B/op 9041928944 B/op 9038099880 B/op 1.00
BenchmarkTextEditing - allocs/op 19922422 allocs/op 19923868 allocs/op 1.00

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

Please sign in to comment.