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
-}