-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnode.go
135 lines (111 loc) · 2.48 KB
/
node.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package tomtp
import (
"errors"
"fmt"
"sync"
)
type Node[K comparable, V any] struct {
Key K
Value V
Parent *Node[K, V]
Left *Node[K, V]
Right *Node[K, V]
shadow bool
mu sync.RWMutex
}
func (n *Node[K, V]) String() string {
if k, isUint64Key := any(n.Key).(uint64); isUint64Key {
if v, isUint64Value := any(n.Value).(uint64); isUint64Value {
streamOffset, streamLen := GetRangeOffsetLen(k)
return fmt.Sprintf("{Offset: %d, Len: %d,Time: %d}", streamOffset, streamLen, v)
}
}
return fmt.Sprintf("{Key: %v, Value: %v}", n.Key, n.Value)
}
func NewNode[K comparable, V any](key K, value V) *Node[K, V] {
return &Node[K, V]{Key: key, Value: value}
}
func (n *Node[K, V]) IsShadow() bool {
n.mu.RLock()
defer n.mu.RUnlock()
return n.shadow
}
func (n *Node[K, V]) Split(leftKey K, leftValue V, rightKey K, rightValue V) (*Node[K, V], *Node[K, V]) {
n.mu.Lock()
defer n.mu.Unlock()
if n.shadow {
panic(errors.New("cannot split a shadowed node"))
}
n.shadow = true
left := NewNode(leftKey, leftValue)
right := NewNode(rightKey, rightValue)
n.Left = left
n.Right = right
left.Parent = n
right.Parent = n
return left, right
}
func (n *Node[K, V]) removeDown() []K {
if n == nil {
return nil
}
keys := make([]K, 0)
// Store references before clearing
left := n.Left
right := n.Right
// Clear references first
n.Left = nil
n.Right = nil
// Then process children
if left != nil {
leftKeys := left.removeDown()
keys = append(keys, leftKeys...)
keys = append(keys, left.Key)
}
if right != nil {
rightKeys := right.removeDown()
keys = append(keys, rightKeys...)
keys = append(keys, right.Key)
}
return keys
}
func (n *Node[K, V]) removeUp() []K {
if n == nil {
return nil
}
keys := make([]K, 0)
// Store reference before clearing
parent := n.Parent
wasLeft := parent != nil && parent.Left == n
// Break parent link
if parent != nil {
if parent.Left == n {
parent.Left = nil
}
if parent.Right == n {
parent.Right = nil
}
}
n.Parent = nil
// Process parent if we were left child
if wasLeft {
parentKeys := parent.removeUp()
keys = append(keys, parentKeys...)
keys = append(keys, parent.Key)
}
return keys
}
func (n *Node[K, V]) Remove() []K {
if n == nil {
return nil
}
n.mu.Lock()
defer n.mu.Unlock()
downKeys := n.removeDown()
upKeys := n.removeUp()
keys := make([]K, 0, len(downKeys)+len(upKeys)+1)
keys = append(keys, downKeys...)
keys = append(keys, upKeys...)
keys = append(keys, n.Key)
return keys
}