From 6f986753d8e52a39b2d2055ef5c264bb573a1bfa Mon Sep 17 00:00:00 2001 From: JOOHOJANG Date: Thu, 19 Dec 2024 16:01:38 +0900 Subject: [PATCH 1/2] Fix missing handling for vv-related processing --- pkg/document/crdt/rga_tree_split.go | 6 ++++-- pkg/document/crdt/text.go | 7 +++++-- pkg/document/crdt/tree.go | 21 +++++++++++++++------ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/pkg/document/crdt/rga_tree_split.go b/pkg/document/crdt/rga_tree_split.go index fa704d5a1..d44251379 100644 --- a/pkg/document/crdt/rga_tree_split.go +++ b/pkg/document/crdt/rga_tree_split.go @@ -527,6 +527,8 @@ func (s *RGATreeSplit[V]) deleteNodes( ) (map[string]*time.Ticket, map[string]*RGATreeSplitNode[V]) { createdAtMapByActor := make(map[string]*time.Ticket) removedNodeMap := make(map[string]*RGATreeSplitNode[V]) + isVersionVectorEmpty := len(versionVector) == 0 + isMaxCreatedAtMapByActorEmpty := len(maxCreatedAtMapByActor) == 0 if len(candidates) == 0 { return createdAtMapByActor, removedNodeMap @@ -545,10 +547,10 @@ func (s *RGATreeSplit[V]) deleteNodes( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 - if versionVector == nil && maxCreatedAtMapByActor == nil { + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { // Local edit - use version vector comparison clientLamportAtChange = time.MaxLamport - } else if len(versionVector) > 0 { + } else if !isVersionVectorEmpty { lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport diff --git a/pkg/document/crdt/text.go b/pkg/document/crdt/text.go index 18653e80e..1b135d198 100644 --- a/pkg/document/crdt/text.go +++ b/pkg/document/crdt/text.go @@ -312,6 +312,9 @@ func (t *Text) Style( // 02. style nodes between from and to nodes := t.rgaTreeSplit.findBetween(fromRight, toRight) createdAtMapByActor := make(map[string]*time.Ticket) + isVersionVectorEmpty := len(versionVector) == 0 + isMaxCreatedAtMapByActorEmpty := len(maxCreatedAtMapByActor) == 0 + var toBeStyled []*RGATreeSplitNode[*TextValue] for _, node := range nodes { @@ -320,10 +323,10 @@ func (t *Text) Style( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 - if versionVector == nil && maxCreatedAtMapByActor == nil { + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { // Local edit - use version vector comparison clientLamportAtChange = time.MaxLamport - } else if versionVector != nil { + } else if !isVersionVectorEmpty { lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport diff --git a/pkg/document/crdt/tree.go b/pkg/document/crdt/tree.go index 3b84d82fa..3ba8dcb63 100644 --- a/pkg/document/crdt/tree.go +++ b/pkg/document/crdt/tree.go @@ -842,6 +842,9 @@ func (t *Tree) collectBetween( var toBeRemoveds []*TreeNode var toBeMovedToFromParents []*TreeNode createdAtMapByActor := make(map[string]*time.Ticket) + isVersionVectorEmpty := len(versionVector) == 0 + isMaxCreatedAtMapByActorEmpty := len(maxCreatedAtMapByActor) == 0 + if err := t.traverseInPosRange( fromParent, fromLeft, toParent, toLeft, @@ -869,10 +872,10 @@ func (t *Tree) collectBetween( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 - if versionVector == nil && maxCreatedAtMapByActor == nil { + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { // Local edit - use version vector comparison clientLamportAtChange = time.MaxLamport - } else if versionVector != nil { + } else if !isVersionVectorEmpty { lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -1000,6 +1003,9 @@ func (t *Tree) Style( return nil, nil, err } + isVersionVectorEmpty := len(versionVector) == 0 + isMaxCreatedAtMapByActorEmpty := len(maxCreatedAtMapByActor) == 0 + var pairs []GCPair createdAtMapByActor := make(map[string]*time.Ticket) if err = t.traverseInPosRange(fromParent, fromLeft, toParent, toLeft, func(token index.TreeToken[*TreeNode], _ bool) { @@ -1009,10 +1015,10 @@ func (t *Tree) Style( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 - if versionVector == nil && maxCreatedAtMapByActor == nil { + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { // Local edit - use version vector comparison clientLamportAtChange = time.MaxLamport - } else if versionVector != nil { + } else if !isVersionVectorEmpty { lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -1069,6 +1075,9 @@ func (t *Tree) RemoveStyle( return nil, nil, err } + isVersionVectorEmpty := len(versionVector) == 0 + isMaxCreatedAtMapByActorEmpty := len(maxCreatedAtMapByActor) == 0 + var pairs []GCPair createdAtMapByActor := make(map[string]*time.Ticket) if err = t.traverseInPosRange(fromParent, fromLeft, toParent, toLeft, func(token index.TreeToken[*TreeNode], _ bool) { @@ -1078,10 +1087,10 @@ func (t *Tree) RemoveStyle( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 - if versionVector == nil && maxCreatedAtMapByActor == nil { + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { // Local edit - use version vector comparison clientLamportAtChange = time.MaxLamport - } else if versionVector != nil { + } else if !isVersionVectorEmpty { lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport From e37c3ea2b7c48eccebb25f9936f21bd4a6c3c6ce Mon Sep 17 00:00:00 2001 From: Youngteac Hong Date: Thu, 19 Dec 2024 17:19:35 +0900 Subject: [PATCH 2/2] Add comments --- pkg/document/crdt/rga_tree_split.go | 4 +++- pkg/document/crdt/text.go | 4 +++- pkg/document/crdt/tree.go | 13 ++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/document/crdt/rga_tree_split.go b/pkg/document/crdt/rga_tree_split.go index d44251379..fc876f1fd 100644 --- a/pkg/document/crdt/rga_tree_split.go +++ b/pkg/document/crdt/rga_tree_split.go @@ -548,9 +548,10 @@ func (s *RGATreeSplit[V]) deleteNodes( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { - // Local edit - use version vector comparison + // Case 1: local editing from json package clientLamportAtChange = time.MaxLamport } else if !isVersionVectorEmpty { + // Case 2: from operation with version vector(After v0.5.7) lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -558,6 +559,7 @@ func (s *RGATreeSplit[V]) deleteNodes( clientLamportAtChange = 0 } } else { + // Case 3: from operation without version vector(Before v0.5.6) createdAt, ok := maxCreatedAtMapByActor[actorIDHex] if ok { maxCreatedAt = createdAt diff --git a/pkg/document/crdt/text.go b/pkg/document/crdt/text.go index 1b135d198..deaf90eac 100644 --- a/pkg/document/crdt/text.go +++ b/pkg/document/crdt/text.go @@ -324,9 +324,10 @@ func (t *Text) Style( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { - // Local edit - use version vector comparison + // Case 1: local editing from json package clientLamportAtChange = time.MaxLamport } else if !isVersionVectorEmpty { + // Case 2: from operation with version vector(After v0.5.7) lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -334,6 +335,7 @@ func (t *Text) Style( clientLamportAtChange = 0 } } else { + // Case 3: from operation without version vector(Before v0.5.6) createdAt, ok := maxCreatedAtMapByActor[actorIDHex] if ok { maxCreatedAt = createdAt diff --git a/pkg/document/crdt/tree.go b/pkg/document/crdt/tree.go index 3ba8dcb63..a6f19d2dc 100644 --- a/pkg/document/crdt/tree.go +++ b/pkg/document/crdt/tree.go @@ -872,10 +872,12 @@ func (t *Tree) collectBetween( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 + if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { - // Local edit - use version vector comparison + // Case 1: local editing from json package clientLamportAtChange = time.MaxLamport } else if !isVersionVectorEmpty { + // Case 2: from operation with version vector(After v0.5.7) lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -883,6 +885,7 @@ func (t *Tree) collectBetween( clientLamportAtChange = 0 } } else { + // Case 3: from operation without version vector(Before v0.5.6) createdAt, ok := maxCreatedAtMapByActor[actorIDHex] if ok { maxCreatedAt = createdAt @@ -1016,9 +1019,10 @@ func (t *Tree) Style( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { - // Local edit - use version vector comparison + // Case 1: local editing from json package clientLamportAtChange = time.MaxLamport } else if !isVersionVectorEmpty { + // Case 2: from operation with version vector(After v0.5.7) lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -1026,6 +1030,7 @@ func (t *Tree) Style( clientLamportAtChange = 0 } } else { + // Case 3: from operation without version vector(Before v0.5.6) createdAt, ok := maxCreatedAtMapByActor[actorIDHex] if ok { maxCreatedAt = createdAt @@ -1088,9 +1093,10 @@ func (t *Tree) RemoveStyle( var maxCreatedAt *time.Ticket var clientLamportAtChange int64 if isVersionVectorEmpty && isMaxCreatedAtMapByActorEmpty { - // Local edit - use version vector comparison + // Case 1: local editing from json package clientLamportAtChange = time.MaxLamport } else if !isVersionVectorEmpty { + // Case 2: from operation with version vector(After v0.5.7) lamport, ok := versionVector.Get(actorID) if ok { clientLamportAtChange = lamport @@ -1098,6 +1104,7 @@ func (t *Tree) RemoveStyle( clientLamportAtChange = 0 } } else { + // Case 3: from operation without version vector(Before v0.5.6) createdAt, ok := maxCreatedAtMapByActor[actorIDHex] if ok { maxCreatedAt = createdAt