@@ -16,7 +16,11 @@ limitations under the License.
1616
1717package palm
1818
19- import "log"
19+ import (
20+ "log"
21+
22+ "github.com/Workiva/go-datastructures/slice/skip"
23+ )
2024
2125func getParent (parent * node , key Key ) * node {
2226 var n * node
@@ -28,72 +32,142 @@ func getParent(parent *node, key Key) *node {
2832 return parent
2933}
3034
31- type nodes []* node
35+ type nodes struct {
36+ list * skip.SkipList
37+ }
3238
3339func (ns * nodes ) push (n * node ) {
34- * ns = append (* ns , n )
40+ ns .list .InsertAtPosition (ns .list .Len (), n )
41+ }
42+
43+ func (ns * nodes ) splitAt (i uint64 ) (* nodes , * nodes ) {
44+ _ , right := ns .list .SplitAt (i )
45+ return ns , & nodes {list : right }
3546}
3647
37- func (ns * nodes ) insertAt ( n * node , i int ) {
38- if i == len ( * ns ) {
39- * ns = append ( * ns , n )
40- return
48+ func (ns * nodes ) byPosition ( pos uint64 ) * node {
49+ n , ok := ns . list . ByPosition ( pos ).( * node )
50+ if ! ok {
51+ return nil
4152 }
4253
43- * ns = append (* ns , nil )
44- copy ((* ns )[i + 1 :], (* ns )[i :])
45- (* ns )[i ] = n
54+ return n
55+ }
56+
57+ func (ns * nodes ) insertAt (i uint64 , n * node ) {
58+ ns .list .InsertAtPosition (i , n )
59+ }
60+
61+ func (ns * nodes ) replaceAt (i uint64 , n * node ) {
62+ ns .list .ReplaceAtPosition (i , n )
63+ }
64+
65+ func (ns * nodes ) len () uint64 {
66+ return ns .list .Len ()
67+ }
68+
69+ func newNodes () * nodes {
70+ return & nodes {
71+ list : skip .New (uint64 (0 )),
72+ }
73+ }
74+
75+ type keys struct {
76+ list * skip.SkipList
77+ }
78+
79+ func (ks * keys ) splitAt (i uint64 ) (* keys , * keys ) {
80+ _ , right := ks .list .SplitAt (i )
81+ return ks , & keys {list : right }
82+ }
83+
84+ func (ks * keys ) len () uint64 {
85+ return ks .list .Len ()
86+ }
87+
88+ func (ks * keys ) byPosition (i uint64 ) Key {
89+ k , ok := ks .list .ByPosition (i ).(Key )
90+ if ! ok {
91+ return nil
92+ }
93+
94+ return k
95+ }
96+
97+ func (ks * keys ) delete (k Key ) {
98+ ks .list .Delete (k .(skip.Entry ))
99+ }
100+
101+ func (ks * keys ) search (key Key ) uint64 {
102+ n , i := ks .list .GetWithPosition (key .(skip.Entry ))
103+ if n == nil {
104+ return ks .list .Len ()
105+ }
106+
107+ return i
108+ }
109+
110+ func (ks * keys ) insert (key Key ) Key {
111+ old := ks .list .Insert (key )[0 ]
112+ if old == nil {
113+ return nil
114+ }
115+
116+ return old .(Key )
117+ }
118+
119+ func (ks * keys ) last () Key {
120+ return ks .list .ByPosition (ks .list .Len () - 1 ).(Key )
121+ }
122+
123+ func (ks * keys ) insertAt (i uint64 , k Key ) {
124+ ks .list .InsertAtPosition (i , k .(skip.Entry ))
125+ }
126+
127+ func newKeys () * keys {
128+ return & keys {
129+ list : skip .New (uint64 (0 )),
130+ }
46131}
47132
48133type node struct {
49- keys Keys
50- nodes nodes
134+ keys * keys
135+ nodes * nodes
51136 isLeaf bool
52137 parent , right * node
53138}
54139
55140func (n * node ) needsSplit (ary uint64 ) bool {
56- return uint64 ( len ( n .keys ) ) >= ary
141+ return n .keys . len ( ) >= ary
57142}
58143
59144func (n * node ) splitLeaf () (Key , * node , * node ) {
60- i := ( len ( n .keys ) / 2 )
61- key := n .keys [ i ]
145+ i := n .keys . len ( ) / 2
146+ key := n .keys . byPosition ( i )
62147 _ , rightKeys := n .keys .splitAt (i )
63148 nn := & node {
64149 keys : rightKeys ,
150+ nodes : newNodes (),
65151 isLeaf : true ,
66152 }
67153 n .right = nn
68154 return key , n , nn
69155}
70156
71157func (n * node ) splitInternal () (Key , * node , * node ) {
72- i := (len (n .keys ) / 2 )
73- key := n .keys [i ]
158+ i := n .keys .len () / 2
159+ key := n .keys .byPosition (i )
160+ n .keys .delete (key )
74161
75- rightKeys := make (Keys , len (n .keys )- 1 - i , cap (n .keys ))
76- rightNodes := make (nodes , len (rightKeys )+ 1 , cap (n .nodes ))
77-
78- copy (rightKeys , n .keys [i + 1 :])
79- copy (rightNodes , n .nodes [i + 1 :])
80-
81- // for garbage collection
82- for j := i + 1 ; j < len (n .nodes ); j ++ {
83- if j != len (n .keys ) {
84- n .keys [j ] = nil
85- }
86- n .nodes [j ] = nil
87- }
162+ _ , rightKeys := n .keys .splitAt (i - 1 )
163+ _ , rightNodes := n .nodes .splitAt (i )
88164
89165 nn := newNode (false , rightKeys , rightNodes )
90- for _ , nd := range rightNodes {
166+ for iter := rightNodes .list .IterAtPosition (0 ); iter .Next (); {
167+ nd := iter .Value ().(* node )
91168 nd .parent = nn
92169 }
93170
94- n .keys = n .keys [:i ]
95- n .nodes = n .nodes [:i + 1 ]
96-
97171 return key , n , nn
98172}
99173
@@ -105,34 +179,47 @@ func (n *node) split() (Key, *node, *node) {
105179 return n .splitInternal ()
106180}
107181
108- func (n * node ) search (key Key ) int {
182+ func (n * node ) search (key Key ) uint64 {
109183 return n .keys .search (key )
110184}
111185
112186func (n * node ) searchNode (key Key ) * node {
113187 i := n .search (key )
114188
115- return n .nodes [ i ]
189+ return n .nodes . byPosition ( uint64 ( i ))
116190}
117191
118192func (n * node ) key () Key {
119- return n .keys [ len ( n . keys ) - 1 ]
193+ return n .keys . last ()
120194}
121195
122196func (n * node ) print (output * log.Logger ) {
123197 output .Printf (`NODE: %+v, %p` , n , n )
198+ for iter := n .keys .list .IterAtPosition (0 ); iter .Next (); {
199+ k := iter .Value ().(Key )
200+ output .Printf (`KEY: %+v` , k )
201+ }
124202 if ! n .isLeaf {
125- for _ , n := range n .nodes {
203+ for iter := n .nodes .list .IterAtPosition (0 ); iter .Next (); {
204+ n := iter .Value ().(* node )
126205 if n == nil {
127206 output .Println (`NIL NODE` )
128207 continue
129208 }
209+
130210 n .print (output )
131211 }
132212 }
133213}
134214
135- func newNode (isLeaf bool , keys Keys , ns nodes ) * node {
215+ // Compare is required by the skip.Entry interface but nodes are always
216+ // added by position so while this method is required it doesn't
217+ // need to return anything useful.
218+ func (n * node ) Compare (e skip.Entry ) int {
219+ return 0
220+ }
221+
222+ func newNode (isLeaf bool , keys * keys , ns * nodes ) * node {
136223 return & node {
137224 isLeaf : isLeaf ,
138225 keys : keys ,
0 commit comments