diff --git a/api/converter/from_pb.go b/api/converter/from_pb.go index 5194b171e..0ecd0895b 100644 --- a/api/converter/from_pb.go +++ b/api/converter/from_pb.go @@ -408,9 +408,6 @@ func fromEdit(pbEdit *api.Operation_Edit) (*operations.Edit, error) { if err != nil { return nil, err } - if err != nil { - return nil, err - } executedAt, err := fromTimeTicket(pbEdit.ExecutedAt) if err != nil { return nil, err @@ -438,9 +435,6 @@ func fromStyle(pbStyle *api.Operation_Style) (*operations.Style, error) { if err != nil { return nil, err } - if err != nil { - return nil, err - } executedAt, err := fromTimeTicket(pbStyle.ExecutedAt) if err != nil { return nil, err @@ -495,13 +489,6 @@ func fromTreeEdit(pbTreeEdit *api.Operation_TreeEdit) (*operations.TreeEdit, err return nil, err } - createdAtMapByActor, err := fromCreatedAtMapByActor( - pbTreeEdit.CreatedAtMapByActor, - ) - if err != nil { - return nil, err - } - nodes, err := FromTreeNodesWhenEdit(pbTreeEdit.Contents) if err != nil { return nil, err @@ -513,7 +500,6 @@ func fromTreeEdit(pbTreeEdit *api.Operation_TreeEdit) (*operations.TreeEdit, err to, nodes, int(pbTreeEdit.SplitLevel), - createdAtMapByActor, executedAt, ), nil } @@ -539,19 +525,11 @@ func fromTreeStyle(pbTreeStyle *api.Operation_TreeStyle) (*operations.TreeStyle, return nil, err } - createdAtMapByActor, err := fromCreatedAtMapByActor( - pbTreeStyle.CreatedAtMapByActor, - ) - if err != nil { - return nil, err - } - if len(pbTreeStyle.AttributesToRemove) > 0 { return operations.NewTreeStyleRemove( parentCreatedAt, from, to, - createdAtMapByActor, pbTreeStyle.AttributesToRemove, executedAt, ), nil @@ -561,7 +539,6 @@ func fromTreeStyle(pbTreeStyle *api.Operation_TreeStyle) (*operations.TreeStyle, parentCreatedAt, from, to, - createdAtMapByActor, pbTreeStyle.Attributes, executedAt, ), nil diff --git a/api/converter/to_pb.go b/api/converter/to_pb.go index 74341bff2..925471457 100644 --- a/api/converter/to_pb.go +++ b/api/converter/to_pb.go @@ -383,13 +383,12 @@ func toIncrease(increase *operations.Increase) (*api.Operation_Increase_, error) func toTreeEdit(e *operations.TreeEdit) (*api.Operation_TreeEdit_, error) { return &api.Operation_TreeEdit_{ TreeEdit: &api.Operation_TreeEdit{ - ParentCreatedAt: ToTimeTicket(e.ParentCreatedAt()), - From: toTreePos(e.FromPos()), - To: toTreePos(e.ToPos()), - Contents: ToTreeNodesWhenEdit(e.Contents()), - SplitLevel: int32(e.SplitLevel()), - CreatedAtMapByActor: toCreatedAtMapByActor(e.MaxCreatedAtMapByActor()), - ExecutedAt: ToTimeTicket(e.ExecutedAt()), + ParentCreatedAt: ToTimeTicket(e.ParentCreatedAt()), + From: toTreePos(e.FromPos()), + To: toTreePos(e.ToPos()), + Contents: ToTreeNodesWhenEdit(e.Contents()), + SplitLevel: int32(e.SplitLevel()), + ExecutedAt: ToTimeTicket(e.ExecutedAt()), }, }, nil } @@ -397,13 +396,12 @@ func toTreeEdit(e *operations.TreeEdit) (*api.Operation_TreeEdit_, error) { func toTreeStyle(style *operations.TreeStyle) (*api.Operation_TreeStyle_, error) { return &api.Operation_TreeStyle_{ TreeStyle: &api.Operation_TreeStyle{ - ParentCreatedAt: ToTimeTicket(style.ParentCreatedAt()), - From: toTreePos(style.FromPos()), - To: toTreePos(style.ToPos()), - Attributes: style.Attributes(), - ExecutedAt: ToTimeTicket(style.ExecutedAt()), - AttributesToRemove: style.AttributesToRemove(), - CreatedAtMapByActor: toCreatedAtMapByActor(style.MaxCreatedAtMapByActor()), + ParentCreatedAt: ToTimeTicket(style.ParentCreatedAt()), + From: toTreePos(style.FromPos()), + To: toTreePos(style.ToPos()), + Attributes: style.Attributes(), + ExecutedAt: ToTimeTicket(style.ExecutedAt()), + AttributesToRemove: style.AttributesToRemove(), }, }, nil } diff --git a/pkg/document/crdt/tree.go b/pkg/document/crdt/tree.go index 42454818b..cf1cd5eb0 100644 --- a/pkg/document/crdt/tree.go +++ b/pkg/document/crdt/tree.go @@ -381,20 +381,20 @@ func (n *TreeNode) remove(removedAt *time.Ticket) bool { return false } -func (n *TreeNode) canDelete(removedAt *time.Ticket, maxCreatedAt *time.Ticket) bool { - if !n.id.CreatedAt.After(maxCreatedAt) && +func (n *TreeNode) canDelete(removedAt *time.Ticket, clientLamportAtChange int64) bool { + if (n.id.CreatedAt.Lamport() <= clientLamportAtChange) && (n.removedAt == nil || n.removedAt.Compare(removedAt) > 0) { return true } return false } -func (n *TreeNode) canStyle(editedAt *time.Ticket, maxCreatedAt *time.Ticket) bool { +func (n *TreeNode) canStyle(editedAt *time.Ticket, clientLamportAtChange int64) bool { if n.IsText() { return false } - return !n.id.CreatedAt.After(maxCreatedAt) && + return (n.id.CreatedAt.Lamport() <= clientLamportAtChange) && (n.removedAt == nil || editedAt.After(n.removedAt)) } @@ -669,7 +669,7 @@ func (t *Tree) EditT( return err } - _, _, err = t.Edit(fromPos, toPos, contents, splitLevel, editedAt, issueTimeTicket, nil) + _, err = t.Edit(fromPos, toPos, contents, splitLevel, editedAt, issueTimeTicket, nil) return err } @@ -716,24 +716,24 @@ func (t *Tree) Edit( splitLevel int, editedAt *time.Ticket, issueTimeTicket func() *time.Ticket, - maxCreatedAtMapByActor map[string]*time.Ticket, -) (map[string]*time.Ticket, []GCPair, error) { + versionVector time.VersionVector, +) ([]GCPair, error) { // 01. find nodes from the given range and split nodes. fromParent, fromLeft, err := t.FindTreeNodesWithSplitText(from, editedAt) if err != nil { - return nil, nil, err + return nil, err } toParent, toLeft, err := t.FindTreeNodesWithSplitText(to, editedAt) if err != nil { - return nil, nil, err + return nil, err } - toBeRemoveds, toBeMovedToFromParents, maxCreatedAtMap, err := t.collectBetween( + toBeRemoveds, toBeMovedToFromParents, err := t.collectBetween( fromParent, fromLeft, toParent, toLeft, - maxCreatedAtMapByActor, editedAt, + editedAt, versionVector, ) if err != nil { - return nil, nil, err + return nil, err } // 02. Delete: delete the nodes that are marked as removed. @@ -751,14 +751,14 @@ func (t *Tree) Edit( for _, node := range toBeMovedToFromParents { if node.removedAt == nil { if err := fromParent.Append(node); err != nil { - return nil, nil, err + return nil, err } } } // 04. Split: split the element nodes for the given splitLevel. if err := t.split(fromParent, fromLeft, splitLevel, issueTimeTicket); err != nil { - return nil, nil, err + return nil, err } // 05. Insert: insert the given node at the given position. @@ -771,13 +771,13 @@ func (t *Tree) Edit( // 05-1-1. when there's no leftSibling, then insert content into very front of parent's children List err := fromParent.InsertAt(content, 0) if err != nil { - return nil, nil, err + return nil, err } } else { // 05-1-2. insert after leftSibling err := fromParent.InsertAfter(content, leftInChildren) if err != nil { - return nil, nil, err + return nil, err } } @@ -786,15 +786,7 @@ func (t *Tree) Edit( // if insertion happens during concurrent editing and parent node has been removed, // make new nodes as tombstone immediately if fromParent.IsRemoved() { - actorIDHex := node.Value.id.CreatedAt.ActorIDHex() - if node.Value.remove(editedAt) { - maxCreatedAt := maxCreatedAtMap[actorIDHex] - createdAt := node.Value.id.CreatedAt - if maxCreatedAt == nil || createdAt.After(maxCreatedAt) { - maxCreatedAtMap[actorIDHex] = createdAt - } - } - + node.Value.remove(editedAt) pairs = append(pairs, GCPair{ Parent: t, Child: node.Value, @@ -806,20 +798,18 @@ func (t *Tree) Edit( } } - return maxCreatedAtMap, pairs, nil + return pairs, nil } -// collectBetween collects nodes that are marked as removed or moved. It also -// returns the maxCreatedAtMapByActor that is used to determine whether the -// node can be deleted or not. +// collectBetween collects nodes that are marked as removed or moved. func (t *Tree) collectBetween( fromParent *TreeNode, fromLeft *TreeNode, toParent *TreeNode, toLeft *TreeNode, - maxCreatedAtMapByActor map[string]*time.Ticket, editedAt *time.Ticket, -) ([]*TreeNode, []*TreeNode, map[string]*time.Ticket, error) { + editedAt *time.Ticket, + versionVector time.VersionVector, +) ([]*TreeNode, []*TreeNode, error) { var toBeRemoveds []*TreeNode var toBeMovedToFromParents []*TreeNode - createdAtMapByActor := make(map[string]*time.Ticket) if err := t.traverseInPosRange( fromParent, fromLeft, toParent, toLeft, @@ -842,28 +832,23 @@ func (t *Tree) collectBetween( } } - actorIDHex := node.id.CreatedAt.ActorIDHex() + actorID := node.id.CreatedAt.ActorID() - var maxCreatedAt *time.Ticket - if maxCreatedAtMapByActor == nil { - maxCreatedAt = time.MaxTicket + var clientLamportAtChange int64 + if versionVector == nil { + clientLamportAtChange = time.MaxLamport } else { - createdAt, ok := maxCreatedAtMapByActor[actorIDHex] + lamport, ok := versionVector.Get(actorID) if ok { - maxCreatedAt = createdAt + clientLamportAtChange = lamport } else { - maxCreatedAt = time.InitialTicket + clientLamportAtChange = 0 } } // NOTE(sejongk): If the node is removable or its parent is going to // be removed, then this node should be removed. - if node.canDelete(editedAt, maxCreatedAt) || slices.Contains(toBeRemoveds, node.Index.Parent.Value) { - maxCreatedAt = createdAtMapByActor[actorIDHex] - createdAt := node.id.CreatedAt - if maxCreatedAt == nil || createdAt.After(maxCreatedAt) { - createdAtMapByActor[actorIDHex] = createdAt - } + if node.canDelete(editedAt, clientLamportAtChange) || slices.Contains(toBeRemoveds, node.Index.Parent.Value) { // NOTE(hackerwins): If the node overlaps as an end token with the // range then we need to keep the node. if tokenType == index.Text || tokenType == index.Start { @@ -872,10 +857,10 @@ func (t *Tree) collectBetween( } }, ); err != nil { - return nil, nil, nil, err + return nil, nil, err } - return toBeRemoveds, toBeMovedToFromParents, createdAtMapByActor, nil + return toBeRemoveds, toBeMovedToFromParents, nil } func (t *Tree) split( @@ -934,19 +919,19 @@ func (t *Tree) StyleByIndex( start, end int, attributes map[string]string, editedAt *time.Ticket, - maxCreatedAtMapByActor map[string]*time.Ticket, -) (map[string]*time.Ticket, []GCPair, error) { + versionVector time.VersionVector, +) ([]GCPair, error) { fromPos, err := t.FindPos(start) if err != nil { - return nil, nil, err + return nil, err } toPos, err := t.FindPos(end) if err != nil { - return nil, nil, err + return nil, err } - return t.Style(fromPos, toPos, attributes, editedAt, maxCreatedAtMapByActor) + return t.Style(fromPos, toPos, attributes, editedAt, versionVector) } // Style applies the given attributes of the given range. @@ -954,41 +939,35 @@ func (t *Tree) Style( from, to *TreePos, attrs map[string]string, editedAt *time.Ticket, - maxCreatedAtMapByActor map[string]*time.Ticket, -) (map[string]*time.Ticket, []GCPair, error) { + versionVector time.VersionVector, +) ([]GCPair, error) { fromParent, fromLeft, err := t.FindTreeNodesWithSplitText(from, editedAt) if err != nil { - return nil, nil, err + return nil, err } toParent, toLeft, err := t.FindTreeNodesWithSplitText(to, editedAt) if err != nil { - return nil, nil, err + return nil, err } var pairs []GCPair - createdAtMapByActor := make(map[string]*time.Ticket) if err = t.traverseInPosRange(fromParent, fromLeft, toParent, toLeft, func(token index.TreeToken[*TreeNode], _ bool) { node := token.Node - actorIDHex := node.id.CreatedAt.ActorIDHex() + actorID := node.id.CreatedAt.ActorID() - var maxCreatedAt *time.Ticket - if maxCreatedAtMapByActor == nil { - maxCreatedAt = time.MaxTicket + var clientLamportAtChange int64 + if versionVector == nil { + clientLamportAtChange = time.MaxLamport } else { - if createdAt, ok := maxCreatedAtMapByActor[actorIDHex]; ok { - maxCreatedAt = createdAt + lamport, ok := versionVector.Get(actorID) + if ok { + clientLamportAtChange = lamport } else { - maxCreatedAt = time.InitialTicket + clientLamportAtChange = 0 } } - if node.canStyle(editedAt, maxCreatedAt) && len(attrs) > 0 { - maxCreatedAt = createdAtMapByActor[actorIDHex] - createdAt := node.id.CreatedAt - if maxCreatedAt == nil || createdAt.After(maxCreatedAt) { - createdAtMapByActor[actorIDHex] = createdAt - } - + if node.canStyle(editedAt, clientLamportAtChange) && len(attrs) > 0 { for key, value := range attrs { if rhtNode := node.SetAttr(key, value, editedAt); rhtNode != nil { pairs = append(pairs, GCPair{ @@ -999,10 +978,10 @@ func (t *Tree) Style( } } }); err != nil { - return nil, nil, err + return nil, err } - return createdAtMapByActor, pairs, nil + return pairs, nil } // RemoveStyle removes the given attributes of the given range. @@ -1011,41 +990,35 @@ func (t *Tree) RemoveStyle( to *TreePos, attrs []string, editedAt *time.Ticket, - maxCreatedAtMapByActor map[string]*time.Ticket, -) (map[string]*time.Ticket, []GCPair, error) { + versionVector time.VersionVector, +) ([]GCPair, error) { fromParent, fromLeft, err := t.FindTreeNodesWithSplitText(from, editedAt) if err != nil { - return nil, nil, err + return nil, err } toParent, toLeft, err := t.FindTreeNodesWithSplitText(to, editedAt) if err != nil { - return nil, nil, err + return nil, err } var pairs []GCPair - createdAtMapByActor := make(map[string]*time.Ticket) if err = t.traverseInPosRange(fromParent, fromLeft, toParent, toLeft, func(token index.TreeToken[*TreeNode], _ bool) { node := token.Node - actorIDHex := node.id.CreatedAt.ActorIDHex() + actorID := node.id.CreatedAt.ActorID() - var maxCreatedAt *time.Ticket - if maxCreatedAtMapByActor == nil { - maxCreatedAt = time.MaxTicket + var clientLamportAtChange int64 + if versionVector == nil { + clientLamportAtChange = time.MaxLamport } else { - if createdAt, ok := maxCreatedAtMapByActor[actorIDHex]; ok { - maxCreatedAt = createdAt + lamport, ok := versionVector.Get(actorID) + if ok { + clientLamportAtChange = lamport } else { - maxCreatedAt = time.InitialTicket + clientLamportAtChange = 0 } } - if node.canStyle(editedAt, maxCreatedAt) && len(attrs) > 0 { - maxCreatedAt = createdAtMapByActor[actorIDHex] - createdAt := node.id.CreatedAt - if maxCreatedAt == nil || createdAt.After(maxCreatedAt) { - createdAtMapByActor[actorIDHex] = createdAt - } - + if node.canStyle(editedAt, clientLamportAtChange) && len(attrs) > 0 { for _, attr := range attrs { rhtNodes := node.RemoveAttr(attr, editedAt) for _, rhtNode := range rhtNodes { @@ -1057,10 +1030,10 @@ func (t *Tree) RemoveStyle( } } }); err != nil { - return nil, nil, err + return nil, err } - return createdAtMapByActor, pairs, nil + return pairs, nil } // FindTreeNodesWithSplitText finds TreeNode of the given crdt.TreePos and diff --git a/pkg/document/crdt/tree_test.go b/pkg/document/crdt/tree_test.go index 3384fe727..d526287a6 100644 --- a/pkg/document/crdt/tree_test.go +++ b/pkg/document/crdt/tree_test.go @@ -405,28 +405,28 @@ func TestTreeEdit(t *testing.T) { assert.Equal(t, "

ab

cd

", tree.ToXML()) // style attributes with opening tag - _, _, err = tree.StyleByIndex(0, 1, map[string]string{"weight": "bold"}, helper.TimeT(ctx), nil) + _, err = tree.StyleByIndex(0, 1, map[string]string{"weight": "bold"}, helper.TimeT(ctx), nil) assert.NoError(t, err) assert.Equal(t, `

ab

cd

`, tree.ToXML()) // style attributes with closing tag - _, _, err = tree.StyleByIndex(3, 4, map[string]string{"color": "red"}, helper.TimeT(ctx), nil) + _, err = tree.StyleByIndex(3, 4, map[string]string{"color": "red"}, helper.TimeT(ctx), nil) assert.NoError(t, err) assert.Equal(t, `

ab

cd

`, tree.ToXML()) // style attributes with the whole - _, _, err = tree.StyleByIndex(0, 4, map[string]string{"size": "small"}, helper.TimeT(ctx), nil) + _, err = tree.StyleByIndex(0, 4, map[string]string{"size": "small"}, helper.TimeT(ctx), nil) assert.NoError(t, err) assert.Equal(t, `

ab

cd

`, tree.ToXML()) // 02. style attributes to elements. - _, _, err = tree.StyleByIndex(0, 5, map[string]string{"style": "italic"}, helper.TimeT(ctx), nil) + _, err = tree.StyleByIndex(0, 5, map[string]string{"style": "italic"}, helper.TimeT(ctx), nil) assert.NoError(t, err) assert.Equal(t, `

ab

`+ `

cd

`, tree.ToXML()) // 03. Ignore styling attributes to text nodes. - _, _, err = tree.StyleByIndex(1, 3, map[string]string{"bold": "true"}, helper.TimeT(ctx), nil) + _, err = tree.StyleByIndex(1, 3, map[string]string{"bold": "true"}, helper.TimeT(ctx), nil) assert.NoError(t, err) assert.Equal(t, `

ab

`+ `

cd

`, tree.ToXML()) diff --git a/pkg/document/json/tree.go b/pkg/document/json/tree.go index faae3f807..ddb51fb85 100644 --- a/pkg/document/json/tree.go +++ b/pkg/document/json/tree.go @@ -221,7 +221,7 @@ func (t *Tree) Style(fromIdx, toIdx int, attributes map[string]string) bool { } ticket := t.context.IssueTimeTicket() - maxCreationMapByActor, pairs, err := t.Tree.Style(fromPos, toPos, attributes, ticket, nil) + pairs, err := t.Tree.Style(fromPos, toPos, attributes, ticket, nil) if err != nil { panic(err) } @@ -234,7 +234,6 @@ func (t *Tree) Style(fromIdx, toIdx int, attributes map[string]string) bool { t.CreatedAt(), fromPos, toPos, - maxCreationMapByActor, attributes, ticket, )) @@ -262,7 +261,7 @@ func (t *Tree) RemoveStyle(fromIdx, toIdx int, attributesToRemove []string) bool } ticket := t.context.IssueTimeTicket() - maxCreationMapByActor, pairs, err := t.Tree.RemoveStyle(fromPos, toPos, attributesToRemove, ticket, nil) + pairs, err := t.Tree.RemoveStyle(fromPos, toPos, attributesToRemove, ticket, nil) if err != nil { panic(err) } @@ -275,7 +274,6 @@ func (t *Tree) RemoveStyle(fromIdx, toIdx int, attributesToRemove []string) bool t.CreatedAt(), fromPos, toPos, - maxCreationMapByActor, attributesToRemove, ticket, )) @@ -346,7 +344,7 @@ func (t *Tree) edit(fromPos, toPos *crdt.TreePos, contents []*TreeNode, splitLev } ticket = t.context.LastTimeTicket() - maxCreationMapByActor, pairs, err := t.Tree.Edit( + pairs, err := t.Tree.Edit( fromPos, toPos, clones, @@ -369,7 +367,6 @@ func (t *Tree) edit(fromPos, toPos *crdt.TreePos, contents []*TreeNode, splitLev toPos, nodes, splitLevel, - maxCreationMapByActor, ticket, )) diff --git a/pkg/document/operations/add.go b/pkg/document/operations/add.go index 28aba1143..e7ef6b7a1 100644 --- a/pkg/document/operations/add.go +++ b/pkg/document/operations/add.go @@ -52,7 +52,7 @@ func NewAdd( } // Execute executes this operation on the given document(`root`). -func (o *Add) Execute(root *crdt.Root, opts ...Option) error { +func (o *Add) Execute(root *crdt.Root, _ ...Option) error { parent := root.FindByCreatedAt(o.parentCreatedAt) obj, ok := parent.(*crdt.Array) diff --git a/pkg/document/operations/array_set.go b/pkg/document/operations/array_set.go index 6edbe9ede..70c7edba3 100644 --- a/pkg/document/operations/array_set.go +++ b/pkg/document/operations/array_set.go @@ -52,7 +52,7 @@ func NewArraySet( } // Execute executes this operation on the given document(`root`). -func (o *ArraySet) Execute(root *crdt.Root, opts ...Option) error { +func (o *ArraySet) Execute(root *crdt.Root, _ ...Option) error { parent := root.FindByCreatedAt(o.parentCreatedAt) obj, ok := parent.(*crdt.Array) diff --git a/pkg/document/operations/increase.go b/pkg/document/operations/increase.go index 427da0dc3..12c4202b3 100644 --- a/pkg/document/operations/increase.go +++ b/pkg/document/operations/increase.go @@ -43,7 +43,7 @@ func NewIncrease( } // Execute executes this operation on the given document(`root`). -func (o *Increase) Execute(root *crdt.Root, opts ...Option) error { +func (o *Increase) Execute(root *crdt.Root, _ ...Option) error { parent := root.FindByCreatedAt(o.parentCreatedAt) cnt, ok := parent.(*crdt.Counter) if !ok { diff --git a/pkg/document/operations/move.go b/pkg/document/operations/move.go index 92d4852fe..b0fea48f0 100644 --- a/pkg/document/operations/move.go +++ b/pkg/document/operations/move.go @@ -52,7 +52,7 @@ func NewMove( } // Execute executes this operation on the given document(`root`). -func (o *Move) Execute(root *crdt.Root, opts ...Option) error { +func (o *Move) Execute(root *crdt.Root, _ ...Option) error { parent := root.FindByCreatedAt(o.parentCreatedAt) obj, ok := parent.(*crdt.Array) diff --git a/pkg/document/operations/operation.go b/pkg/document/operations/operation.go index d378bd3df..d7c79d495 100644 --- a/pkg/document/operations/operation.go +++ b/pkg/document/operations/operation.go @@ -31,12 +31,16 @@ var ( ErrNotApplicableDataType = errors.New("not applicable datatype") ) +// ExecuteOption contains options for executing operations. type ExecuteOption struct { + // VersionVector represents the version vector at the time of operation creation. VersionVector time.VersionVector } +// Option is a function type that configures ExecuteOption. type Option func(*ExecuteOption) +// WithVersionVector returns an Option that sets the version vector for the operation. func WithVersionVector(versionVector time.VersionVector) Option { return func(option *ExecuteOption) { option.VersionVector = versionVector diff --git a/pkg/document/operations/remove.go b/pkg/document/operations/remove.go index 0cce8c9bd..605b64b67 100644 --- a/pkg/document/operations/remove.go +++ b/pkg/document/operations/remove.go @@ -48,7 +48,7 @@ func NewRemove( } // Execute executes this operation on the given document(`root`). -func (o *Remove) Execute(root *crdt.Root, opts ...Option) error { +func (o *Remove) Execute(root *crdt.Root, _ ...Option) error { parentElem := root.FindByCreatedAt(o.parentCreatedAt) switch parent := parentElem.(type) { diff --git a/pkg/document/operations/set.go b/pkg/document/operations/set.go index 03c22c884..03dbd74b6 100644 --- a/pkg/document/operations/set.go +++ b/pkg/document/operations/set.go @@ -53,7 +53,7 @@ func NewSet( } // Execute executes this operation on the given document(`root`). -func (o *Set) Execute(root *crdt.Root, opts ...Option) error { +func (o *Set) Execute(root *crdt.Root, _ ...Option) error { parent := root.FindByCreatedAt(o.parentCreatedAt) obj, ok := parent.(*crdt.Object) diff --git a/pkg/document/operations/tree_edit.go b/pkg/document/operations/tree_edit.go index add7ac0e5..0515e1402 100644 --- a/pkg/document/operations/tree_edit.go +++ b/pkg/document/operations/tree_edit.go @@ -39,10 +39,6 @@ type TreeEdit struct { // splitLevel is the level of the split. splitLevel int - // maxCreatedAtMapByActor is a map that stores the latest creation time - // by actor for the nodes included in the editing range. - maxCreatedAtMapByActor map[string]*time.Ticket - // executedAt is the time the operation was executed. executedAt *time.Ticket } @@ -54,22 +50,25 @@ func NewTreeEdit( to *crdt.TreePos, contents []*crdt.TreeNode, splitLevel int, - maxCreatedAtMapByActor map[string]*time.Ticket, executedAt *time.Ticket, ) *TreeEdit { return &TreeEdit{ - parentCreatedAt: parentCreatedAt, - from: from, - to: to, - contents: contents, - splitLevel: splitLevel, - maxCreatedAtMapByActor: maxCreatedAtMapByActor, - executedAt: executedAt, + parentCreatedAt: parentCreatedAt, + from: from, + to: to, + contents: contents, + splitLevel: splitLevel, + executedAt: executedAt, } } // Execute executes this operation on the given `CRDTRoot`. func (e *TreeEdit) Execute(root *crdt.Root, opts ...Option) error { + options := &ExecuteOption{} + for _, opt := range opts { + opt(options) + } + parent := root.FindByCreatedAt(e.parentCreatedAt) switch obj := parent.(type) { @@ -89,7 +88,7 @@ func (e *TreeEdit) Execute(root *crdt.Root, opts ...Option) error { } } - _, pairs, err := obj.Edit( + pairs, err := obj.Edit( e.from, e.to, contents, @@ -116,7 +115,7 @@ func (e *TreeEdit) Execute(root *crdt.Root, opts ...Option) error { ) } }(), - e.maxCreatedAtMapByActor, + options.VersionVector, ) if err != nil { return err @@ -164,12 +163,6 @@ func (e *TreeEdit) SplitLevel() int { return e.splitLevel } -// MaxCreatedAtMapByActor returns the map that stores the latest creation time -// by actor for the nodes included in the editing range. -func (e *TreeEdit) MaxCreatedAtMapByActor() map[string]*time.Ticket { - return e.maxCreatedAtMapByActor -} - // ExecutedAt returns execution time of this operation. func (e *TreeEdit) ExecutedAt() *time.Ticket { return e.executedAt diff --git a/pkg/document/operations/tree_style.go b/pkg/document/operations/tree_style.go index c3d716b91..57f0b1684 100644 --- a/pkg/document/operations/tree_style.go +++ b/pkg/document/operations/tree_style.go @@ -32,10 +32,6 @@ type TreeStyle struct { // toPos represents the end point of the editing range. to *crdt.TreePos - // maxCreatedAtMapByActor is a map that stores the latest creation time - // by actor for the nodes included in the styling range. - maxCreatedAtMapByActor map[string]*time.Ticket - // attributes represents the tree style to be added. attributes map[string]string @@ -51,18 +47,16 @@ func NewTreeStyle( parentCreatedAt *time.Ticket, from *crdt.TreePos, to *crdt.TreePos, - maxCreatedAtMapByActor map[string]*time.Ticket, attributes map[string]string, executedAt *time.Ticket, ) *TreeStyle { return &TreeStyle{ - parentCreatedAt: parentCreatedAt, - from: from, - to: to, - maxCreatedAtMapByActor: maxCreatedAtMapByActor, - attributes: attributes, - attributesToRemove: []string{}, - executedAt: executedAt, + parentCreatedAt: parentCreatedAt, + from: from, + to: to, + attributes: attributes, + attributesToRemove: []string{}, + executedAt: executedAt, } } @@ -71,23 +65,26 @@ func NewTreeStyleRemove( parentCreatedAt *time.Ticket, from *crdt.TreePos, to *crdt.TreePos, - maxCreatedAtMapByActor map[string]*time.Ticket, attributesToRemove []string, executedAt *time.Ticket, ) *TreeStyle { return &TreeStyle{ - parentCreatedAt: parentCreatedAt, - from: from, - to: to, - maxCreatedAtMapByActor: maxCreatedAtMapByActor, - attributes: map[string]string{}, - attributesToRemove: attributesToRemove, - executedAt: executedAt, + parentCreatedAt: parentCreatedAt, + from: from, + to: to, + attributes: map[string]string{}, + attributesToRemove: attributesToRemove, + executedAt: executedAt, } } // Execute executes this operation on the given `CRDTRoot`. func (e *TreeStyle) Execute(root *crdt.Root, opts ...Option) error { + options := &ExecuteOption{} + for _, opt := range opts { + opt(options) + } + parent := root.FindByCreatedAt(e.parentCreatedAt) obj, ok := parent.(*crdt.Tree) if !ok { @@ -97,12 +94,12 @@ func (e *TreeStyle) Execute(root *crdt.Root, opts ...Option) error { var pairs []crdt.GCPair var err error if len(e.attributes) > 0 { - _, pairs, err = obj.Style(e.from, e.to, e.attributes, e.executedAt, e.maxCreatedAtMapByActor) + pairs, err = obj.Style(e.from, e.to, e.attributes, e.executedAt, options.VersionVector) if err != nil { return err } } else { - _, pairs, err = obj.RemoveStyle(e.from, e.to, e.attributesToRemove, e.executedAt, e.maxCreatedAtMapByActor) + pairs, err = obj.RemoveStyle(e.from, e.to, e.attributesToRemove, e.executedAt, options.VersionVector) if err != nil { return err } @@ -149,9 +146,3 @@ func (e *TreeStyle) Attributes() map[string]string { func (e *TreeStyle) AttributesToRemove() []string { return e.attributesToRemove } - -// MaxCreatedAtMapByActor returns the map that stores the latest creation time -// by actor for the nodes included in the styling range. -func (e *TreeStyle) MaxCreatedAtMapByActor() map[string]*time.Ticket { - return e.maxCreatedAtMapByActor -}