Documentation ¶
Overview ¶
Package crdt provides the implementation of the CRDT data structure. The CRDT data structure is a data structure that can be replicated and shared among multiple replicas.
Index ¶
- Variables
- func CounterValueFromBytes(counterType CounterType, value []byte) (interface{}, error)
- func EscapeString(s string) string
- func ToXML(node *TreeNode) string
- func ValueFromBytes(valueType ValueType, value []byte) (interface{}, error)
- type Array
- func (a *Array) Add(elem Element) error
- func (a *Array) CreatedAt() *time.Ticket
- func (a *Array) DeepCopy() (Element, error)
- func (a *Array) Delete(idx int, deletedAt *time.Ticket) (Element, error)
- func (a *Array) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (Element, error)
- func (a *Array) Descendants(callback func(elem Element, parent Container) bool)
- func (a *Array) Elements() []Element
- func (a *Array) FindPrevCreatedAt(createdAt *time.Ticket) (*time.Ticket, error)
- func (a *Array) Get(idx int) (Element, error)
- func (a *Array) InsertAfter(prevCreatedAt *time.Ticket, element Element) error
- func (a *Array) LastCreatedAt() *time.Ticket
- func (a *Array) Len() int
- func (a *Array) Marshal() string
- func (a *Array) MoveAfter(prevCreatedAt, createdAt, executedAt *time.Ticket) error
- func (a *Array) MovedAt() *time.Ticket
- func (a *Array) Purge(elem Element) error
- func (a *Array) RGANodes() []*RGATreeListNode
- func (a *Array) Remove(removedAt *time.Ticket) bool
- func (a *Array) RemovedAt() *time.Ticket
- func (a *Array) Set(createdAt *time.Ticket, element Element, executedAt *time.Ticket) (Element, error)
- func (a *Array) SetMovedAt(movedAt *time.Ticket)
- func (a *Array) SetRemovedAt(removedAt *time.Ticket)
- func (a *Array) ToTestString() string
- type Container
- type Counter
- func (p *Counter) Bytes() ([]byte, error)
- func (p *Counter) CreatedAt() *time.Ticket
- func (p *Counter) DeepCopy() (Element, error)
- func (p *Counter) Increase(v *Primitive) (*Counter, error)
- func (p *Counter) IsNumericType() bool
- func (p *Counter) Marshal() string
- func (p *Counter) MovedAt() *time.Ticket
- func (p *Counter) Remove(removedAt *time.Ticket) bool
- func (p *Counter) RemovedAt() *time.Ticket
- func (p *Counter) SetMovedAt(movedAt *time.Ticket)
- func (p *Counter) SetRemovedAt(removedAt *time.Ticket)
- func (p *Counter) Value() interface{}
- func (p *Counter) ValueType() CounterType
- type CounterType
- type Element
- type ElementPair
- type ElementRHT
- func (rht *ElementRHT) Delete(k string, deletedAt *time.Ticket) Element
- func (rht *ElementRHT) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (Element, error)
- func (rht *ElementRHT) Elements() map[string]Element
- func (rht *ElementRHT) Get(key string) Element
- func (rht *ElementRHT) Has(key string) bool
- func (rht *ElementRHT) Marshal() string
- func (rht *ElementRHT) Nodes() []*ElementRHTNode
- func (rht *ElementRHT) Set(k string, v Element) Element
- type ElementRHTNode
- type GCChild
- type GCPair
- type GCParent
- type Object
- func (o *Object) CreatedAt() *time.Ticket
- func (o *Object) DeepCopy() (Element, error)
- func (o *Object) Delete(k string, deletedAt *time.Ticket) Element
- func (o *Object) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (Element, error)
- func (o *Object) Descendants(callback func(elem Element, parent Container) bool)
- func (o *Object) Get(k string) Element
- func (o *Object) Has(k string) bool
- func (o *Object) Marshal() string
- func (o *Object) Members() map[string]Element
- func (o *Object) MovedAt() *time.Ticket
- func (o *Object) Purge(elem Element) error
- func (o *Object) RHTNodes() []*ElementRHTNode
- func (o *Object) Remove(removedAt *time.Ticket) bool
- func (o *Object) RemovedAt() *time.Ticket
- func (o *Object) Set(k string, v Element) Element
- func (o *Object) SetMovedAt(movedAt *time.Ticket)
- func (o *Object) SetRemovedAt(removedAt *time.Ticket)
- type Primitive
- func (p *Primitive) Bytes() []byte
- func (p *Primitive) CreatedAt() *time.Ticket
- func (p *Primitive) DeepCopy() (Element, error)
- func (p *Primitive) IsNumericType() bool
- func (p *Primitive) Marshal() string
- func (p *Primitive) MovedAt() *time.Ticket
- func (p *Primitive) Remove(removedAt *time.Ticket) bool
- func (p *Primitive) RemovedAt() *time.Ticket
- func (p *Primitive) SetMovedAt(movedAt *time.Ticket)
- func (p *Primitive) SetRemovedAt(removedAt *time.Ticket)
- func (p *Primitive) Value() interface{}
- func (p *Primitive) ValueType() ValueType
- type RGATreeList
- func (a *RGATreeList) Add(elem Element) error
- func (a *RGATreeList) Delete(idx int, deletedAt *time.Ticket) (*RGATreeListNode, error)
- func (a *RGATreeList) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (*RGATreeListNode, error)
- func (a *RGATreeList) FindPrevCreatedAt(createdAt *time.Ticket) (*time.Ticket, error)
- func (a *RGATreeList) Get(idx int) (*RGATreeListNode, error)
- func (a *RGATreeList) InsertAfter(prevCreatedAt *time.Ticket, elem Element) error
- func (a *RGATreeList) LastCreatedAt() *time.Ticket
- func (a *RGATreeList) Len() int
- func (a *RGATreeList) Marshal() string
- func (a *RGATreeList) MoveAfter(prevCreatedAt, createdAt, executedAt *time.Ticket) error
- func (a *RGATreeList) Nodes() []*RGATreeListNode
- func (a *RGATreeList) Set(createdAt *time.Ticket, element Element, executedAt *time.Ticket) (*RGATreeListNode, error)
- func (a *RGATreeList) ToTestString() string
- type RGATreeListNode
- type RGATreeSplit
- func (s *RGATreeSplit[V]) CheckWeight() bool
- func (s *RGATreeSplit[V]) FindNode(id *RGATreeSplitNodeID) *RGATreeSplitNode[V]
- func (s *RGATreeSplit[V]) InitialHead() *RGATreeSplitNode[V]
- func (s *RGATreeSplit[V]) InsertAfter(prev, node *RGATreeSplitNode[V]) *RGATreeSplitNode[V]
- func (s *RGATreeSplit[V]) Purge(child GCChild) error
- func (s *RGATreeSplit[V]) ToTestString() string
- type RGATreeSplitNode
- func (s *RGATreeSplitNode[V]) DeepCopy() *RGATreeSplitNode[V]
- func (s *RGATreeSplitNode[V]) ID() *RGATreeSplitNodeID
- func (s *RGATreeSplitNode[V]) IDString() string
- func (s *RGATreeSplitNode[V]) InsPrevID() *RGATreeSplitNodeID
- func (s *RGATreeSplitNode[V]) Len() int
- func (s *RGATreeSplitNode[V]) Marshal() string
- func (s *RGATreeSplitNode[V]) Remove(removedAt *time.Ticket, maxCreatedAt *time.Ticket) bool
- func (s *RGATreeSplitNode[V]) RemovedAt() *time.Ticket
- func (s *RGATreeSplitNode[V]) SetInsPrev(node *RGATreeSplitNode[V])
- func (s *RGATreeSplitNode[V]) String() string
- func (s *RGATreeSplitNode[V]) Value() V
- type RGATreeSplitNodeID
- func (id *RGATreeSplitNodeID) Compare(other llrb.Key) int
- func (id *RGATreeSplitNodeID) CreatedAt() *time.Ticket
- func (id *RGATreeSplitNodeID) Equal(other llrb.Key) bool
- func (id *RGATreeSplitNodeID) Offset() int
- func (id *RGATreeSplitNodeID) Split(offset int) *RGATreeSplitNodeID
- func (id *RGATreeSplitNodeID) ToTestString() string
- type RGATreeSplitNodePos
- type RGATreeSplitValue
- type RHT
- func (rht *RHT) DeepCopy() *RHT
- func (rht *RHT) Elements() map[string]string
- func (rht *RHT) Get(key string) string
- func (rht *RHT) Has(key string) bool
- func (rht *RHT) Len() int
- func (rht *RHT) Marshal() string
- func (rht *RHT) Nodes() []*RHTNode
- func (rht *RHT) Purge(child *RHTNode) error
- func (rht *RHT) Remove(k string, executedAt *time.Ticket) []*RHTNode
- func (rht *RHT) Set(k, v string, executedAt *time.Ticket) *RHTNode
- func (rht *RHT) SetInternal(k string, v string, updatedAt *time.Ticket, removed bool)
- type RHTNode
- type Root
- func (r *Root) DeepCopy() (*Root, error)
- func (r *Root) ElementMapLen() int
- func (r *Root) FindByCreatedAt(createdAt *time.Ticket) Element
- func (r *Root) GarbageCollect(ticket *time.Ticket) (int, error)
- func (r *Root) GarbageElementLen() int
- func (r *Root) GarbageLen() int
- func (r *Root) Object() *Object
- func (r *Root) RegisterElement(element Element)
- func (r *Root) RegisterGCPair(pair GCPair)
- func (r *Root) RegisterRemovedElementPair(parent Container, elem Element)
- type Text
- func (t *Text) CheckWeight() bool
- func (t *Text) CreateRange(from, to int) (*RGATreeSplitNodePos, *RGATreeSplitNodePos, error)
- func (t *Text) CreatedAt() *time.Ticket
- func (t *Text) DeepCopy() (Element, error)
- func (t *Text) Edit(from, to *RGATreeSplitNodePos, maxCreatedAtMapByActor map[string]*time.Ticket, ...) (*RGATreeSplitNodePos, map[string]*time.Ticket, []GCPair, error)
- func (t *Text) GCPairs() []GCPair
- func (t *Text) Marshal() string
- func (t *Text) MovedAt() *time.Ticket
- func (t *Text) Nodes() []*RGATreeSplitNode[*TextValue]
- func (t *Text) Remove(removedAt *time.Ticket) bool
- func (t *Text) RemovedAt() *time.Ticket
- func (t *Text) SetMovedAt(movedAt *time.Ticket)
- func (t *Text) SetRemovedAt(removedAt *time.Ticket)
- func (t *Text) String() string
- func (t *Text) Style(from, to *RGATreeSplitNodePos, maxCreatedAtMapByActor map[string]*time.Ticket, ...) (map[string]*time.Ticket, []GCPair, error)
- func (t *Text) ToTestString() string
- func (t *Text) TreeByID() *llrb.Tree[*RGATreeSplitNodeID, *RGATreeSplitNode[*TextValue]]
- func (t *Text) TreeByIndex() *splay.Tree[*RGATreeSplitNode[*TextValue]]
- type TextValue
- func (t *TextValue) Attrs() *RHT
- func (t *TextValue) DeepCopy() RGATreeSplitValue
- func (t *TextValue) GCPairs() []GCPair
- func (t *TextValue) Len() int
- func (t *TextValue) Marshal() string
- func (t *TextValue) Purge(child GCChild) error
- func (t *TextValue) Split(offset int) RGATreeSplitValue
- func (t *TextValue) String() string
- func (t *TextValue) Value() string
- type Tree
- func (t *Tree) CreatedAt() *time.Ticket
- func (t *Tree) DeepCopy() (Element, error)
- func (t *Tree) Edit(from, to *TreePos, contents []*TreeNode, splitLevel int, editedAt *time.Ticket, ...) (map[string]*time.Ticket, []GCPair, error)
- func (t *Tree) EditT(start, end int, contents []*TreeNode, splitLevel int, editedAt *time.Ticket, ...) error
- func (t *Tree) FindPos(offset int) (*TreePos, error)
- func (t *Tree) FindTreeNodesWithSplitText(pos *TreePos, editedAt *time.Ticket) (*TreeNode, *TreeNode, error)
- func (t *Tree) GCPairs() []GCPair
- func (t *Tree) Marshal() string
- func (t *Tree) MovedAt() *time.Ticket
- func (t *Tree) NodeLen() int
- func (t *Tree) Nodes() []*TreeNode
- func (t *Tree) PathToPos(path []int) (*TreePos, error)
- func (t *Tree) Purge(child GCChild) error
- func (t *Tree) Remove(removedAt *time.Ticket) bool
- func (t *Tree) RemoveStyle(from *TreePos, to *TreePos, attrs []string, editedAt *time.Ticket, ...) (map[string]*time.Ticket, []GCPair, error)
- func (t *Tree) RemovedAt() *time.Ticket
- func (t *Tree) Root() *TreeNode
- func (t *Tree) SetMovedAt(movedAt *time.Ticket)
- func (t *Tree) SetRemovedAt(removedAt *time.Ticket)
- func (t *Tree) Style(from, to *TreePos, attrs map[string]string, editedAt *time.Ticket, ...) (map[string]*time.Ticket, []GCPair, error)
- func (t *Tree) StyleByIndex(start, end int, attributes map[string]string, editedAt *time.Ticket, ...) (map[string]*time.Ticket, []GCPair, error)
- func (t *Tree) ToIndex(parentNode, leftSiblingNode *TreeNode) (int, error)
- func (t *Tree) ToPath(parentNode, leftSiblingNode *TreeNode) ([]int, error)
- func (t *Tree) ToTreeNodeForTest() TreeNodeForTest
- func (t *Tree) ToTreeNodes(pos *TreePos) (*TreeNode, *TreeNode)
- func (t *Tree) ToXML() string
- type TreeNode
- func (n *TreeNode) Append(newNodes ...*TreeNode) error
- func (n *TreeNode) Attributes() string
- func (n *TreeNode) Child(offset int) (*TreeNode, error)
- func (n *TreeNode) DeepCopy() (*TreeNode, error)
- func (n *TreeNode) GCPairs() []GCPair
- func (n *TreeNode) ID() *TreeNodeID
- func (n *TreeNode) IDString() string
- func (n *TreeNode) InsertAfter(content *TreeNode, children *TreeNode) error
- func (n *TreeNode) InsertAt(newNode *TreeNode, offset int) error
- func (n *TreeNode) IsRemoved() bool
- func (n *TreeNode) IsText() bool
- func (n *TreeNode) Len() int
- func (n *TreeNode) Length() int
- func (n *TreeNode) Prepend(newNodes ...*TreeNode) error
- func (n *TreeNode) Purge(child GCChild) error
- func (n *TreeNode) RemoveAttr(k string, ticket *time.Ticket) []*RHTNode
- func (n *TreeNode) RemovedAt() *time.Ticket
- func (n *TreeNode) SetAttr(k string, v string, ticket *time.Ticket) *RHTNode
- func (n *TreeNode) SetRemovedAt(ticket *time.Ticket)
- func (n *TreeNode) Split(tree *Tree, offset int, issueTimeTicket func() *time.Ticket) error
- func (n *TreeNode) SplitElement(offset int, issueTimeTicket func() *time.Ticket) (*TreeNode, error)
- func (n *TreeNode) SplitText(offset, absOffset int) (*TreeNode, error)
- func (n *TreeNode) String() string
- func (n *TreeNode) Type() string
- type TreeNodeForTest
- type TreeNodeID
- type TreePos
- type ValueType
Constants ¶
This section is empty.
Variables ¶
var ErrChildNotFound = errors.New("child not found")
ErrChildNotFound is returned when the child is not found in the container.
var ( // ErrNodeNotFound is returned when the node is not found. ErrNodeNotFound = errors.New("node not found") )
var ErrUnsupportedType = errors.New("unsupported type")
ErrUnsupportedType is returned when the given type is not supported.
Functions ¶
func CounterValueFromBytes ¶
func CounterValueFromBytes(counterType CounterType, value []byte) (interface{}, error)
CounterValueFromBytes parses the given bytes into value.
func EscapeString ¶
EscapeString returns a string that is safe to embed in a JSON document.
func ValueFromBytes ¶
ValueFromBytes parses the given bytes into value.
Types ¶
type Array ¶
type Array struct {
// contains filtered or unexported fields
}
Array represents JSON array data structure including logical clock. Array implements Element interface.
func NewArray ¶
func NewArray(elements *RGATreeList, createdAt *time.Ticket, value ...[]Element) *Array
NewArray creates a new instance of Array.
func (*Array) DeleteByCreatedAt ¶
DeleteByCreatedAt deletes the given element.
func (*Array) Descendants ¶
Descendants traverse the descendants of this array.
func (*Array) FindPrevCreatedAt ¶
FindPrevCreatedAt returns the creation time of the previous element of the given element.
func (*Array) InsertAfter ¶
InsertAfter inserts the given element after the given previous element.
func (*Array) LastCreatedAt ¶
LastCreatedAt returns the creation time of the last element.
func (*Array) MoveAfter ¶
MoveAfter moves the given `createdAt` element after the `prevCreatedAt` element.
func (*Array) RGANodes ¶
func (a *Array) RGANodes() []*RGATreeListNode
RGANodes returns the slices of RGATreeListNode.
func (*Array) Set ¶ added in v0.5.0
func (a *Array) Set(createdAt *time.Ticket, element Element, executedAt *time.Ticket) (Element, error)
Set sets the given element at the given position of the creation time.
func (*Array) SetMovedAt ¶
SetMovedAt sets the move time of this array.
func (*Array) SetRemovedAt ¶
SetRemovedAt sets the removal time of this array.
func (*Array) ToTestString ¶ added in v0.4.8
ToTestString returns a String containing the metadata of the elements for debugging purpose.
type Container ¶
type Container interface { Element // Purge physically purges the given child element. Purge(child Element) error // Descendants returns all descendants of this container. Descendants(callback func(elem Element, parent Container) bool) // DeleteByCreatedAt removes the given element from this container. DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (Element, error) }
Container represents Array or Object.
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter represents changeable number data type.
func NewCounter ¶
func NewCounter(valueType CounterType, value interface{}, createdAt *time.Ticket) (*Counter, error)
NewCounter creates a new instance of Counter.
func (*Counter) Increase ¶
Increase increases integer, long or double. If the result of the operation is greater than MaxInt32 or less than MinInt32, Counter's value type can be changed Integer to Long. Because in golang, int can be either int32 or int64. So we need to assert int to int32.
func (*Counter) IsNumericType ¶
IsNumericType checks for numeric types.
func (*Counter) SetMovedAt ¶
SetMovedAt sets the move time of this element.
func (*Counter) SetRemovedAt ¶
SetRemovedAt sets the removal time of this element.
func (*Counter) Value ¶ added in v0.4.13
func (p *Counter) Value() interface{}
Value returns the value of this counter. TODO(hackerwins): We need to use generics to avoid using interface{}.
func (*Counter) ValueType ¶
func (p *Counter) ValueType() CounterType
ValueType returns the type of the value.
type CounterType ¶
type CounterType int
CounterType represents any type that can be used as a counter.
const ( IntegerCnt CounterType = iota LongCnt )
The values below are the types that can be used as counters.
type Element ¶
type Element interface { // Marshal returns the JSON encoding of this element. Marshal() string // DeepCopy copies itself deeply. DeepCopy() (Element, error) // CreatedAt returns the creation time of this element. CreatedAt() *time.Ticket // MovedAt returns the move time of this element. MovedAt() *time.Ticket // SetMovedAt sets the move time of this element. SetMovedAt(*time.Ticket) // RemovedAt returns the removal time of this element. RemovedAt() *time.Ticket // Remove removes this element. Remove(*time.Ticket) bool }
Element represents JSON element.
type ElementPair ¶
type ElementPair struct {
// contains filtered or unexported fields
}
ElementPair represents pair that has a parent element and child element.
type ElementRHT ¶ added in v0.3.1
type ElementRHT struct {
// contains filtered or unexported fields
}
ElementRHT is a hashtable with logical clock(Replicated hashtable).
func NewElementRHT ¶ added in v0.3.1
func NewElementRHT() *ElementRHT
NewElementRHT creates a new instance of ElementRHT.
func (*ElementRHT) Delete ¶ added in v0.3.1
func (rht *ElementRHT) Delete(k string, deletedAt *time.Ticket) Element
Delete deletes the Element of the given key.
func (*ElementRHT) DeleteByCreatedAt ¶ added in v0.3.1
func (rht *ElementRHT) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (Element, error)
DeleteByCreatedAt deletes the Element of the given creation time.
func (*ElementRHT) Elements ¶ added in v0.3.1
func (rht *ElementRHT) Elements() map[string]Element
Elements returns a map of elements because the map easy to use for loop. TODO: If we encounter performance issues, we need to replace this with other solution.
func (*ElementRHT) Get ¶ added in v0.3.1
func (rht *ElementRHT) Get(key string) Element
Get returns the value of the given key.
func (*ElementRHT) Has ¶ added in v0.3.1
func (rht *ElementRHT) Has(key string) bool
Has returns whether the element exists of the given key or not.
func (*ElementRHT) Marshal ¶ added in v0.3.1
func (rht *ElementRHT) Marshal() string
Marshal returns the JSON encoding of this map.
func (*ElementRHT) Nodes ¶ added in v0.3.1
func (rht *ElementRHT) Nodes() []*ElementRHTNode
Nodes returns a map of elements because the map easy to use for loop. TODO: If we encounter performance issues, we need to replace this with other solution.
type ElementRHTNode ¶ added in v0.3.1
type ElementRHTNode struct {
// contains filtered or unexported fields
}
ElementRHTNode is a node of ElementRHT.
func (*ElementRHTNode) Element ¶ added in v0.3.1
func (n *ElementRHTNode) Element() Element
Element returns the element of this node.
func (*ElementRHTNode) Key ¶ added in v0.3.1
func (n *ElementRHTNode) Key() string
Key returns the key of this node.
type GCChild ¶ added in v0.4.20
GCChild is an interface for the child of the garbage collection target.
type GCPair ¶ added in v0.4.20
GCPair is a structure that represents a pair of parent and child for garbage collection.
type GCParent ¶ added in v0.4.20
GCParent is an interface for the parent of the garbage collection target.
type Object ¶
type Object struct {
// contains filtered or unexported fields
}
Object represents a JSON object, but unlike regular JSON, it has time tickets which is created by logical clock.
func NewObject ¶
func NewObject(memberNodes *ElementRHT, createdAt *time.Ticket, value ...map[string]Element) *Object
NewObject creates a new instance of Object.
func (*Object) DeleteByCreatedAt ¶
DeleteByCreatedAt deletes the element of the given creation time.
func (*Object) Descendants ¶
Descendants traverse the descendants of this object.
func (*Object) RHTNodes ¶
func (o *Object) RHTNodes() []*ElementRHTNode
RHTNodes returns the ElementRHT nodes.
func (*Object) SetMovedAt ¶
SetMovedAt sets the move time of this object.
func (*Object) SetRemovedAt ¶
SetRemovedAt sets the removal time of this array.
type Primitive ¶
type Primitive struct {
// contains filtered or unexported fields
}
Primitive represents JSON primitive data type including logical lock.
func NewPrimitive ¶
NewPrimitive creates a new instance of Primitive.
func (*Primitive) IsNumericType ¶
IsNumericType checks for numeric types.
func (*Primitive) SetMovedAt ¶
SetMovedAt sets the move time of this element.
func (*Primitive) SetRemovedAt ¶
SetRemovedAt sets the removal time of this element.
type RGATreeList ¶
type RGATreeList struct {
// contains filtered or unexported fields
}
RGATreeList is a list with improved index-based lookup in RGA. RGA is a linked list that has a logical clock and tombstone. Since RGA is composed as a linked list, index-based element search is slow, O(n). To optimise for fast insertions and removals at any index in the list, RGATreeList has a tree.
func NewRGATreeList ¶
func NewRGATreeList() *RGATreeList
NewRGATreeList creates a new instance of RGATreeList.
func (*RGATreeList) Add ¶
func (a *RGATreeList) Add(elem Element) error
Add adds the given element at the last.
func (*RGATreeList) Delete ¶
func (a *RGATreeList) Delete(idx int, deletedAt *time.Ticket) (*RGATreeListNode, error)
Delete deletes the node of the given index.
func (*RGATreeList) DeleteByCreatedAt ¶
func (a *RGATreeList) DeleteByCreatedAt(createdAt *time.Ticket, deletedAt *time.Ticket) (*RGATreeListNode, error)
DeleteByCreatedAt deletes the given element.
func (*RGATreeList) FindPrevCreatedAt ¶
FindPrevCreatedAt returns the creation time of the previous element of the given element.
func (*RGATreeList) Get ¶
func (a *RGATreeList) Get(idx int) (*RGATreeListNode, error)
Get returns the element of the given index.
func (*RGATreeList) InsertAfter ¶
func (a *RGATreeList) InsertAfter(prevCreatedAt *time.Ticket, elem Element) error
InsertAfter inserts the given element after the given previous element.
func (*RGATreeList) LastCreatedAt ¶
func (a *RGATreeList) LastCreatedAt() *time.Ticket
LastCreatedAt returns the creation time of last elements.
func (*RGATreeList) Marshal ¶
func (a *RGATreeList) Marshal() string
Marshal returns the JSON encoding of this RGATreeList.
func (*RGATreeList) MoveAfter ¶
func (a *RGATreeList) MoveAfter(prevCreatedAt, createdAt, executedAt *time.Ticket) error
MoveAfter moves the given `createdAt` element after the `prevCreatedAt` element.
func (*RGATreeList) Nodes ¶
func (a *RGATreeList) Nodes() []*RGATreeListNode
Nodes returns an array of elements contained in this RGATreeList. TODO: If we encounter performance issues, we need to replace this with other solution.
func (*RGATreeList) Set ¶ added in v0.5.0
func (a *RGATreeList) Set( createdAt *time.Ticket, element Element, executedAt *time.Ticket, ) (*RGATreeListNode, error)
Set sets the given element at the given creation time.
func (*RGATreeList) ToTestString ¶ added in v0.4.8
func (a *RGATreeList) ToTestString() string
ToTestString returns a String containing the metadata of the node id for debugging purpose.
type RGATreeListNode ¶
type RGATreeListNode struct {
// contains filtered or unexported fields
}
RGATreeListNode is a node of RGATreeList.
func (*RGATreeListNode) CreatedAt ¶
func (n *RGATreeListNode) CreatedAt() *time.Ticket
CreatedAt returns the creation time of this element.
func (*RGATreeListNode) Element ¶
func (n *RGATreeListNode) Element() Element
Element returns the element of this node.
func (*RGATreeListNode) Len ¶
func (n *RGATreeListNode) Len() int
Len returns the length of this node.
func (*RGATreeListNode) PositionedAt ¶
func (n *RGATreeListNode) PositionedAt() *time.Ticket
PositionedAt returns the time this element was positioned.
func (*RGATreeListNode) String ¶
func (n *RGATreeListNode) String() string
String returns the string representation of this node.
type RGATreeSplit ¶
type RGATreeSplit[V RGATreeSplitValue] struct { // contains filtered or unexported fields }
RGATreeSplit is a block-based list with improved index-based lookup in RGA. The difference from RGATreeList is that it has data on a block basis to reduce the size of CRDT metadata. When an Edit occurs on a block, the block is split.
func NewRGATreeSplit ¶
func NewRGATreeSplit[V RGATreeSplitValue](initialHead *RGATreeSplitNode[V]) *RGATreeSplit[V]
NewRGATreeSplit creates a new instance of RGATreeSplit.
func (*RGATreeSplit[V]) CheckWeight ¶
func (s *RGATreeSplit[V]) CheckWeight() bool
CheckWeight returns false when there is an incorrect weight node. for debugging purpose.
func (*RGATreeSplit[V]) FindNode ¶
func (s *RGATreeSplit[V]) FindNode(id *RGATreeSplitNodeID) *RGATreeSplitNode[V]
FindNode returns the node of the given ID.
func (*RGATreeSplit[V]) InitialHead ¶
func (s *RGATreeSplit[V]) InitialHead() *RGATreeSplitNode[V]
InitialHead returns the head node of this RGATreeSplit.
func (*RGATreeSplit[V]) InsertAfter ¶
func (s *RGATreeSplit[V]) InsertAfter(prev, node *RGATreeSplitNode[V]) *RGATreeSplitNode[V]
InsertAfter inserts the given node after the given previous node.
func (*RGATreeSplit[V]) Purge ¶ added in v0.4.20
func (s *RGATreeSplit[V]) Purge(child GCChild) error
Purge physically purge the given node from RGATreeSplit.
func (*RGATreeSplit[V]) ToTestString ¶ added in v0.4.8
func (s *RGATreeSplit[V]) ToTestString() string
ToTestString returns a String containing the metadata of the nodes for debugging purpose.
type RGATreeSplitNode ¶
type RGATreeSplitNode[V RGATreeSplitValue] struct { // contains filtered or unexported fields }
RGATreeSplitNode is a node of RGATreeSplit.
func InitialTextNode ¶
func InitialTextNode() *RGATreeSplitNode[*TextValue]
InitialTextNode creates an initial node of Text. The text is edited as this node is split into multiple nodes.
func NewRGATreeSplitNode ¶
func NewRGATreeSplitNode[V RGATreeSplitValue](id *RGATreeSplitNodeID, value V) *RGATreeSplitNode[V]
NewRGATreeSplitNode creates a new instance of RGATreeSplit.
func (*RGATreeSplitNode[V]) DeepCopy ¶
func (s *RGATreeSplitNode[V]) DeepCopy() *RGATreeSplitNode[V]
DeepCopy returns a new instance of this RGATreeSplitNode without structural info.
func (*RGATreeSplitNode[V]) ID ¶
func (s *RGATreeSplitNode[V]) ID() *RGATreeSplitNodeID
ID returns the ID of this RGATreeSplitNode.
func (*RGATreeSplitNode[V]) IDString ¶ added in v0.4.20
func (s *RGATreeSplitNode[V]) IDString() string
IDString returns the string representation of the ID.
func (*RGATreeSplitNode[V]) InsPrevID ¶
func (s *RGATreeSplitNode[V]) InsPrevID() *RGATreeSplitNodeID
InsPrevID returns previous node ID at the time of this node insertion.
func (*RGATreeSplitNode[V]) Len ¶
func (s *RGATreeSplitNode[V]) Len() int
Len returns the length of this node.
func (*RGATreeSplitNode[V]) Marshal ¶
func (s *RGATreeSplitNode[V]) Marshal() string
Marshal returns the JSON encoding of this node.
func (*RGATreeSplitNode[V]) Remove ¶
Remove removes this node if it created before the time of deletion are deleted. It only marks the deleted time (tombstone).
func (*RGATreeSplitNode[V]) RemovedAt ¶
func (s *RGATreeSplitNode[V]) RemovedAt() *time.Ticket
RemovedAt return the remove time of this node.
func (*RGATreeSplitNode[V]) SetInsPrev ¶
func (s *RGATreeSplitNode[V]) SetInsPrev(node *RGATreeSplitNode[V])
SetInsPrev sets previous node of this node insertion.
func (*RGATreeSplitNode[V]) String ¶
func (s *RGATreeSplitNode[V]) String() string
String returns the string representation of this node.
func (*RGATreeSplitNode[V]) Value ¶
func (s *RGATreeSplitNode[V]) Value() V
Value returns the value of this node.
type RGATreeSplitNodeID ¶
type RGATreeSplitNodeID struct {
// contains filtered or unexported fields
}
RGATreeSplitNodeID is an ID of RGATreeSplitNode.
func NewRGATreeSplitNodeID ¶
func NewRGATreeSplitNodeID(createdAt *time.Ticket, offset int) *RGATreeSplitNodeID
NewRGATreeSplitNodeID creates a new instance of RGATreeSplitNodeID.
func (*RGATreeSplitNodeID) Compare ¶
func (id *RGATreeSplitNodeID) Compare(other llrb.Key) int
Compare returns an integer comparing two ID. The result will be 0 if id==other, -1 if id < other, and +1 if id > other. If the receiver or argument is nil, it would panic at runtime. This method is following golang standard interface.
func (*RGATreeSplitNodeID) CreatedAt ¶
func (id *RGATreeSplitNodeID) CreatedAt() *time.Ticket
CreatedAt returns the creation time of this ID.
func (*RGATreeSplitNodeID) Equal ¶
func (id *RGATreeSplitNodeID) Equal(other llrb.Key) bool
Equal returns whether given ID equals to this ID or not.
func (*RGATreeSplitNodeID) Offset ¶
func (id *RGATreeSplitNodeID) Offset() int
Offset returns the offset of this ID.
func (*RGATreeSplitNodeID) Split ¶
func (id *RGATreeSplitNodeID) Split(offset int) *RGATreeSplitNodeID
Split creates a new ID with an offset from this ID.
func (*RGATreeSplitNodeID) ToTestString ¶ added in v0.4.8
func (id *RGATreeSplitNodeID) ToTestString() string
ToTestString returns a String containing the metadata of the node id for debugging purpose.
type RGATreeSplitNodePos ¶
type RGATreeSplitNodePos struct {
// contains filtered or unexported fields
}
RGATreeSplitNodePos is the position of the text inside the node.
func NewRGATreeSplitNodePos ¶
func NewRGATreeSplitNodePos(id *RGATreeSplitNodeID, offset int) *RGATreeSplitNodePos
NewRGATreeSplitNodePos creates a new instance of RGATreeSplitNodePos.
func (*RGATreeSplitNodePos) Equal ¶
func (pos *RGATreeSplitNodePos) Equal(other *RGATreeSplitNodePos) bool
Equal returns whether the given pos equals or not.
func (*RGATreeSplitNodePos) ID ¶
func (pos *RGATreeSplitNodePos) ID() *RGATreeSplitNodeID
ID returns the ID of this RGATreeSplitNodePos.
func (*RGATreeSplitNodePos) RelativeOffset ¶
func (pos *RGATreeSplitNodePos) RelativeOffset() int
RelativeOffset returns the relative offset of this RGATreeSplitNodePos.
func (*RGATreeSplitNodePos) ToTestString ¶ added in v0.4.8
func (pos *RGATreeSplitNodePos) ToTestString() string
ToTestString returns a String containing the metadata of the position for debugging purpose.
type RGATreeSplitValue ¶
type RGATreeSplitValue interface { Split(offset int) RGATreeSplitValue Len() int DeepCopy() RGATreeSplitValue String() string Marshal() string // contains filtered or unexported methods }
RGATreeSplitValue is a value of RGATreeSplitNode.
type RHT ¶
type RHT struct {
// contains filtered or unexported fields
}
RHT is a hashtable with logical clock(Replicated hashtable). For more details about RHT: http://csl.skku.edu/papers/jpdc11.pdf NOTE(justiceHui): RHT and ElementRHT has duplicated functions.
func (*RHT) Elements ¶
Elements returns a map of elements because the map easy to use for loop. TODO: If we encounter performance issues, we need to replace this with other solution.
func (*RHT) Nodes ¶
Nodes returns a map of elements because the map easy to use for loop. TODO: If we encounter performance issues, we need to replace this with other solution.
type RHTNode ¶
type RHTNode struct {
// contains filtered or unexported fields
}
RHTNode is a node of RHT(Replicated Hashtable).
func (*RHTNode) IDString ¶ added in v0.4.20
IDString returns the string representation of this node.
type Root ¶
type Root struct {
// contains filtered or unexported fields
}
Root is a structure represents the root of JSON. It has a hash table of all JSON elements to find a specific element when applying remote changes received from server.
Every element has a unique time ticket at creation, which allows us to find a particular element.
func (*Root) ElementMapLen ¶
ElementMapLen returns the size of element map.
func (*Root) FindByCreatedAt ¶
FindByCreatedAt returns the element of given creation time.
func (*Root) GarbageCollect ¶
GarbageCollect purge elements that were removed before the given time.
func (*Root) GarbageElementLen ¶ added in v0.4.20
GarbageElementLen return the count of removed elements.
func (*Root) GarbageLen ¶
GarbageLen returns the count of removed elements and internal nodes.
func (*Root) RegisterElement ¶
RegisterElement registers the given element to hash table.
func (*Root) RegisterGCPair ¶ added in v0.4.20
RegisterGCPair registers the given pair to hash table.
func (*Root) RegisterRemovedElementPair ¶
RegisterRemovedElementPair register the given element pair to hash table.
type Text ¶
type Text struct {
// contains filtered or unexported fields
}
Text is an extended data type for the contents of a text editor.
func NewText ¶
func NewText(elements *RGATreeSplit[*TextValue], createdAt *time.Ticket) *Text
NewText creates a new instance of Text.
func (*Text) CheckWeight ¶
CheckWeight returns false when there is an incorrect weight node. for debugging purpose.
func (*Text) CreateRange ¶
func (t *Text) CreateRange(from, to int) (*RGATreeSplitNodePos, *RGATreeSplitNodePos, error)
CreateRange returns a pair of RGATreeSplitNodePos of the given integer offsets.
func (*Text) Edit ¶
func (t *Text) Edit( from, to *RGATreeSplitNodePos, maxCreatedAtMapByActor map[string]*time.Ticket, content string, attributes map[string]string, executedAt *time.Ticket, ) (*RGATreeSplitNodePos, map[string]*time.Ticket, []GCPair, error)
Edit edits the given range with the given content and attributes.
func (*Text) Nodes ¶
func (t *Text) Nodes() []*RGATreeSplitNode[*TextValue]
Nodes returns the internal nodes of this Text.
func (*Text) SetMovedAt ¶
SetMovedAt sets the move time of this Text.
func (*Text) SetRemovedAt ¶
SetRemovedAt sets the removal time of this array.
func (*Text) Style ¶ added in v0.3.0
func (t *Text) Style( from, to *RGATreeSplitNodePos, maxCreatedAtMapByActor map[string]*time.Ticket, attributes map[string]string, executedAt *time.Ticket, ) (map[string]*time.Ticket, []GCPair, error)
Style applies the given attributes of the given range.
func (*Text) ToTestString ¶ added in v0.4.8
ToTestString returns a String containing the metadata of the text for debugging purpose.
func (*Text) TreeByID ¶ added in v0.4.26
func (t *Text) TreeByID() *llrb.Tree[*RGATreeSplitNodeID, *RGATreeSplitNode[*TextValue]]
TreeByID returns the tree by ID for debugging purpose.
func (*Text) TreeByIndex ¶ added in v0.4.26
func (t *Text) TreeByIndex() *splay.Tree[*RGATreeSplitNode[*TextValue]]
TreeByIndex returns IndexTree of the text for debugging purpose.
type TextValue ¶
type TextValue struct {
// contains filtered or unexported fields
}
TextValue is a value of Text which has an attributes that represent the text style.
func NewTextValue ¶
NewTextValue creates a value of Text.
func (*TextValue) DeepCopy ¶
func (t *TextValue) DeepCopy() RGATreeSplitValue
DeepCopy copies itself deeply.
func (*TextValue) Len ¶
Len returns the length of this value. It is calculated in UTF-16 code units.
func (*TextValue) Split ¶
func (t *TextValue) Split(offset int) RGATreeSplitValue
Split splits this value by the given offset.
type Tree ¶ added in v0.4.0
type Tree struct { IndexTree *index.Tree[*TreeNode] NodeMapByID *llrb.Tree[*TreeNodeID, *TreeNode] // contains filtered or unexported fields }
Tree represents the tree of CRDT. It has doubly linked list structure and index tree structure.
func (*Tree) Edit ¶ added in v0.4.0
func (t *Tree) Edit( from, to *TreePos, contents []*TreeNode, splitLevel int, editedAt *time.Ticket, issueTimeTicket func() *time.Ticket, maxCreatedAtMapByActor map[string]*time.Ticket, ) (map[string]*time.Ticket, []GCPair, error)
Edit edits the tree with the given range and content. If the content is undefined, the range will be removed.
func (*Tree) EditT ¶ added in v0.4.10
func (t *Tree) EditT( start, end int, contents []*TreeNode, splitLevel int, editedAt *time.Ticket, issueTimeTicket func() *time.Ticket, ) error
EditT edits the given range with the given value. This method uses indexes instead of a pair of TreePos for testing.
func (*Tree) FindPos ¶ added in v0.4.0
FindPos finds the position of the given index in the tree. (local) index -> (local) TreePos in indexTree -> (logical) TreePos in Tree
func (*Tree) FindTreeNodesWithSplitText ¶ added in v0.4.6
func (t *Tree) FindTreeNodesWithSplitText(pos *TreePos, editedAt *time.Ticket) ( *TreeNode, *TreeNode, error, )
FindTreeNodesWithSplitText finds TreeNode of the given crdt.TreePos and splits the text node if the position is in the middle of the text node. crdt.TreePos is a position in the CRDT perspective. This is different from indexTree.TreePos which is a position of the tree in physical perspective.
func (*Tree) RemoveStyle ¶ added in v0.4.13
func (t *Tree) RemoveStyle( from *TreePos, to *TreePos, attrs []string, editedAt *time.Ticket, maxCreatedAtMapByActor map[string]*time.Ticket, ) (map[string]*time.Ticket, []GCPair, error)
RemoveStyle removes the given attributes of the given range.
func (*Tree) SetMovedAt ¶ added in v0.4.0
SetMovedAt sets the move time of this Text.
func (*Tree) SetRemovedAt ¶ added in v0.4.0
SetRemovedAt sets the removal time of this array.
func (*Tree) Style ¶ added in v0.4.2
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)
Style applies the given attributes of the given range.
func (*Tree) StyleByIndex ¶ added in v0.4.2
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)
StyleByIndex applies the given attributes of the given range. This method uses indexes instead of a pair of TreePos for testing.
func (*Tree) ToIndex ¶ added in v0.4.6
ToIndex converts the given CRDTTreePos to the index of the tree.
func (*Tree) ToTreeNodeForTest ¶ added in v0.4.8
func (t *Tree) ToTreeNodeForTest() TreeNodeForTest
ToTreeNodeForTest returns the JSON of this tree for debugging.
func (*Tree) ToTreeNodes ¶ added in v0.4.16
ToTreeNodes converts the pos to parent and left sibling nodes. If the position points to the middle of a node, then the left sibling node is the node that contains the position. Otherwise, the left sibling node is the node that is the left of the position.
type TreeNode ¶ added in v0.4.0
type TreeNode struct { Index *index.Node[*TreeNode] InsPrevID *TreeNodeID InsNextID *TreeNodeID // Value is optional. If the value is not empty, it means that the node is a // text node. Value string // Attrs is optional. If the value is not empty, //it means that the node is an element node. Attrs *RHT // contains filtered or unexported fields }
TreeNode is a node of Tree.
func NewTreeNode ¶ added in v0.4.0
func NewTreeNode(id *TreeNodeID, nodeType string, attributes *RHT, value ...string) *TreeNode
NewTreeNode creates a new instance of TreeNode.
func (*TreeNode) Attributes ¶ added in v0.4.2
Attributes returns the string representation of this node's attributes.
func (*TreeNode) ID ¶ added in v0.4.6
func (n *TreeNode) ID() *TreeNodeID
ID returns the ID of this Node.
func (*TreeNode) InsertAfter ¶ added in v0.4.10
InsertAfter inserts the given node after the given leftSibling.
func (*TreeNode) Prepend ¶ added in v0.4.0
Prepend prepends the given node to the beginning of the children.
func (*TreeNode) RemoveAttr ¶ added in v0.4.20
RemoveAttr removes the given attribute of the element.
func (*TreeNode) SetRemovedAt ¶ added in v0.4.20
SetRemovedAt sets the removal time of this node.
func (*TreeNode) SplitElement ¶ added in v0.4.6
SplitElement splits the given element at the given offset.
type TreeNodeForTest ¶ added in v0.4.0
type TreeNodeForTest struct { Type string Children []TreeNodeForTest Value string Size int IsRemoved bool }
TreeNodeForTest is a TreeNode for test.
func ToTreeNodeForTest ¶ added in v0.4.8
func ToTreeNodeForTest(node *TreeNode) TreeNodeForTest
ToTreeNodeForTest returns the JSON of this tree for debugging.
type TreeNodeID ¶ added in v0.4.6
TreeNodeID represent an ID of a node in the tree. It is used to identify a node in the tree. It is composed of the creation time of the node and the offset from the beginning of the node if the node is split.
Some replicas may have nodes that are not split yet. In this case, we can use `map.floorEntry()` to find the adjacent node.
func NewTreeNodeID ¶ added in v0.4.6
func NewTreeNodeID(createdAt *time.Ticket, offset int) *TreeNodeID
NewTreeNodeID creates a new instance of TreeNodeID.
func (*TreeNodeID) Compare ¶ added in v0.4.6
func (t *TreeNodeID) Compare(other llrb.Key) int
Compare compares the given two CRDTTreePos.
func (*TreeNodeID) Equals ¶ added in v0.4.10
func (t *TreeNodeID) Equals(id *TreeNodeID) bool
Equals returns whether given ID is equal to this ID or not.
type TreePos ¶ added in v0.4.0
type TreePos struct { // ParentID is the ID of the parent node. ParentID *TreeNodeID // LeftSiblingID is the ID of the left sibling node. If the node is the // parent, it means that the position is leftmost. LeftSiblingID *TreeNodeID }
TreePos represents a position in the tree. It is used to determine the position of insertion, deletion, and style change.
func NewTreePos ¶ added in v0.4.0
func NewTreePos(parentID *TreeNodeID, leftSiblingID *TreeNodeID) *TreePos
NewTreePos creates a new instance of TreePos.