Skip to content

Commit

Permalink
Updated API to support node updates when ID matches instead of replac…
Browse files Browse the repository at this point in the history
…ement. This allows the node implementation to decide what data is adopted
  • Loading branch information
mcphailtom committed Sep 11, 2023
1 parent e740203 commit aecdaa3
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 25 deletions.
3 changes: 3 additions & 0 deletions tree/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ type Node[T any, id comparable] interface {

// SetParent sets the parent of this node.
SetParent(parent Node[T, id])

// UpdateNode updates the node with the provided node.
UpdateNode(node Node[T, id])
}
8 changes: 3 additions & 5 deletions tree/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import "fmt"

type Option[T any, id comparable] func(t *Tree[T, id]) error

// WithReplaceExisting allows nodes to be replaced when inserting into the tree.
// If this option is not set, then an error will be returned if a node with the
// same nodeIndex key already exists in the tree.
func WithReplaceExisting[T any, id comparable](rep bool) Option[T, id] {
// WithUpdatesAllowed allows updates to existing nodes.
func WithUpdatesAllowed[T any, id comparable](rep bool) Option[T, id] {
return func(t *Tree[T, id]) error {
t.replaceExisting = rep
t.updatesAllowed = rep
return nil
}
}
Expand Down
29 changes: 9 additions & 20 deletions tree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ var (

// Tree implements a tree based data structure with an index.
type Tree[T any, id comparable] struct {
root Node[T, id]
nodeIndex *index[T, id]
replaceExisting bool
root Node[T, id]
nodeIndex *index[T, id]
updatesAllowed bool
}

// NewTree creates and returns an empty tree.
func NewTree[T any, id comparable](options ...Option[T, id]) (*Tree[T, id], error) {
t := Tree[T, id]{
nodeIndex: &index[T, id]{},
replaceExisting: false,
nodeIndex: &index[T, id]{},
updatesAllowed: false,
}

if err := t.withOptions(options...); err != nil {
Expand Down Expand Up @@ -57,7 +57,7 @@ func (t *Tree[T, id]) Insert(node Node[T, id]) error {
var exists bool
existingNode, err := t.nodeIndex.find(node.GetID())
if err == nil {
if !t.replaceExisting {
if !t.updatesAllowed {
return NodeExists
}
exists = true
Expand Down Expand Up @@ -85,25 +85,14 @@ func (t *Tree[T, id]) Insert(node Node[T, id]) error {
parent.AddChildren(node)
}

// If there is an existing node, remove it from the tree
// The new node inherits the children of the existing node
// If there is an existing node, update it
if exists {
children := existingNode.GetChildren()
for _, child := range children {
child.SetParent(node)
}
node.AddChildren(children...)

existingNode.RemoveChildren(children...)
parent, err := t.nodeIndex.find(existingNode.GetParentID())
if err != nil {
parent.RemoveChildren(existingNode)
}
existingNode.UpdateNode(node)
return nil
}

// add to nodeIndex index
t.nodeIndex.insert(node)

return nil
}

Expand Down

0 comments on commit aecdaa3

Please sign in to comment.