-
Notifications
You must be signed in to change notification settings - Fork 49
/
skiplist.go
460 lines (403 loc) · 12.5 KB
/
skiplist.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
// This implementation is based on https://github.com/liyue201/gostl/tree/master/ds/skiplist
// (many thanks), added many optimizations, such as:
//
// - adaptive level
// - lesser search for prevs when key already exists.
// - reduce memory allocations
// - richer interface.
//
// etc.
package stl4go
import (
"math/bits"
"math/rand"
"time"
)
const (
skipListMaxLevel = 40
)
// SkipList is a probabilistic data structure that seem likely to supplant balanced trees as the
// implementation method of choice for many applications. Skip list algorithms have the same
// asymptotic expected time bounds as balanced trees and are simpler, faster and use less space.
//
// See https://en.wikipedia.org/wiki/Skip_list for more details.
type SkipList[K any, V any] struct {
level int // Current level, may increase dynamically during insertion
len int // Total elements number in the skiplist.
head skipListNode[K, V] // head.next[level] is the head of each level.
// This cache is used to save the previous nodes when modifying the skip list to avoid
// allocating memory each time it is called.
prevsCache []*skipListNode[K, V]
rander *rand.Rand
impl skipListImpl[K, V]
}
// NewSkipList creates a new SkipList for Ordered key type.
func NewSkipList[K Ordered, V any]() *SkipList[K, V] {
sl := skipListOrdered[K, V]{}
sl.init()
sl.impl = (skipListImpl[K, V])(&sl)
return &sl.SkipList
}
// NewSkipListFromMap creates a new SkipList from a map.
func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V] {
sl := NewSkipList[K, V]()
for k, v := range m {
sl.Insert(k, v)
}
return sl
}
// NewSkipListFunc creates a new SkipList with specified compare function keyCmp.
func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V] {
sl := skipListFunc[K, V]{}
sl.init()
sl.keyCmp = keyCmp
sl.impl = skipListImpl[K, V](&sl)
return &sl.SkipList
}
// IsEmpty implements the Container interface.
func (sl *SkipList[K, V]) IsEmpty() bool {
return sl.len == 0
}
// Len implements the Container interface.
func (sl *SkipList[K, V]) Len() int {
return sl.len
}
// Clear implements the Container interface.
func (sl *SkipList[K, V]) Clear() {
for i := range sl.head.next {
sl.head.next[i] = nil
}
sl.level = 1
sl.len = 0
}
// Iterate return an iterator to the skiplist.
func (sl *SkipList[K, V]) Iterate() MutableMapIterator[K, V] {
return &skipListIterator[K, V]{sl.head.next[0], nil}
}
// Insert inserts a key-value pair into the skiplist.
// If the key is already in the skip list, it's value will be updated.
func (sl *SkipList[K, V]) Insert(key K, value V) {
node, prevs := sl.impl.findInsertPoint(key)
if node != nil {
// Already exist, update the value
node.value = value
return
}
level := sl.randomLevel()
node = newSkipListNode(level, key, value)
// Insert node to each level
for i := 0; i < Min(level, sl.level); i++ {
node.next[i] = prevs[i].next[i]
prevs[i].next[i] = node
}
if level > sl.level {
// Increase the level
for i := sl.level; i < level; i++ {
sl.head.next[i] = node
}
sl.level = level
}
sl.len++
}
// Find returns the value associated with the passed key if the key is in the skiplist, otherwise
// returns nil.
func (sl *SkipList[K, V]) Find(key K) *V {
node := sl.impl.findNode(key)
if node != nil {
return &node.value
}
return nil
}
// Has implement the Map interface.
func (sl *SkipList[K, V]) Has(key K) bool {
return sl.impl.findNode(key) != nil
}
// LowerBound returns an iterator to the first element in the skiplist that
// does not satisfy element < value (i.e. greater or equal to),
// or a end iterator if no such element is found.
func (sl *SkipList[K, V]) LowerBound(key K) MutableMapIterator[K, V] {
return &skipListIterator[K, V]{sl.impl.lowerBound(key), nil}
}
// UpperBound returns an iterator to the first element in the skiplist that
// does not satisfy value < element (i.e. strictly greater),
// or a end iterator if no such element is found.
func (sl *SkipList[K, V]) UpperBound(key K) MutableMapIterator[K, V] {
return &skipListIterator[K, V]{sl.impl.upperBound(key), nil}
}
// FindRange returns an iterator in range [first, last) (last is not included).
func (sl *SkipList[K, V]) FindRange(first, last K) MutableMapIterator[K, V] {
return &skipListIterator[K, V]{sl.impl.lowerBound(first), sl.impl.upperBound(last)}
}
// Remove removes the key-value pair associated with the passed key and returns true if the key is
// in the skiplist, otherwise returns false.
func (sl *SkipList[K, V]) Remove(key K) bool {
node, prevs := sl.impl.findRemovePoint(key)
if node == nil {
return false
}
for i, v := range node.next { // Nomove the node from each level's links.
prevs[i].next[i] = v
}
// Decrease the level if the top level become empty
for sl.level > 1 && sl.head.next[sl.level-1] == nil {
sl.level--
}
sl.len--
return true
}
// ForEach implements the Map interface.
func (sl *SkipList[K, V]) ForEach(op func(K, V)) {
for e := sl.head.next[0]; e != nil; e = e.next[0] {
op(e.key, e.value)
}
}
// ForEachMutable implements the Map interface.
func (sl *SkipList[K, V]) ForEachMutable(op func(K, *V)) {
for e := sl.head.next[0]; e != nil; e = e.next[0] {
op(e.key, &e.value)
}
}
// ForEachIf implements the Map interface.
func (sl *SkipList[K, V]) ForEachIf(op func(K, V) bool) {
for e := sl.head.next[0]; e != nil; e = e.next[0] {
if !op(e.key, e.value) {
return
}
}
}
// ForEachMutableIf implements the Map interface.
func (sl *SkipList[K, V]) ForEachMutableIf(op func(K, *V) bool) {
for e := sl.head.next[0]; e != nil; e = e.next[0] {
if !op(e.key, &e.value) {
return
}
}
}
/// SkipList implementation part.
type skipListNode[K any, V any] struct {
key K
value V
next []*skipListNode[K, V]
}
//go:generate bash ./skiplist_newnode_generate.sh skipListMaxLevel skiplist_newnode.go
// func newSkipListNode[K Ordered, V any](level int, key K, value V) *skipListNode[K, V]
type skipListIterator[K any, V any] struct {
node, end *skipListNode[K, V]
}
func (it *skipListIterator[K, V]) IsNotEnd() bool {
return it.node != it.end
}
func (it *skipListIterator[K, V]) MoveToNext() {
it.node = it.node.next[0]
}
func (it *skipListIterator[K, V]) Key() K {
return it.node.key
}
func (it *skipListIterator[K, V]) Value() V {
return it.node.value
}
func (it *skipListIterator[K, V]) Pointer() *V {
return &it.node.value
}
// skipListImpl is an interface to provide different implementation for Ordered key or CompareFn.
//
// We can use CompareFn to compare Ordered keys, but a separated implementation is much faster.
// We don't make the whole skip list an interface, in order to share the type independented method.
// And because these methods are called directly without going through the interface, they are also
// much faster.
type skipListImpl[K any, V any] interface {
findNode(key K) *skipListNode[K, V]
lowerBound(key K) *skipListNode[K, V]
upperBound(key K) *skipListNode[K, V]
findInsertPoint(key K) (*skipListNode[K, V], []*skipListNode[K, V])
findRemovePoint(key K) (*skipListNode[K, V], []*skipListNode[K, V])
}
func (sl *SkipList[K, V]) init() {
sl.level = 1
// #nosec G404 -- This is not a security condition
sl.rander = rand.New(rand.NewSource(time.Now().Unix()))
sl.prevsCache = make([]*skipListNode[K, V], skipListMaxLevel)
sl.head.next = make([]*skipListNode[K, V], skipListMaxLevel)
}
func (sl *SkipList[K, V]) randomLevel() int {
total := uint64(1)<<uint64(skipListMaxLevel) - 1 // 2^n-1
k := sl.rander.Uint64() & total
level := skipListMaxLevel - bits.Len64(k) + 1
// Since levels are randomly generated, most should be less than log2(s.len).
// Then make a limit according to sl.len to avoid unexpectedly large value.
for level > 3 && 1<<(level-3) > sl.len {
level--
}
return level
}
/// skipListOrdered part
// skipListOrdered is the skip list implementation for Ordered types.
type skipListOrdered[K Ordered, V any] struct {
SkipList[K, V]
}
func (sl *skipListOrdered[K, V]) findNode(key K) *skipListNode[K, V] {
return sl.doFindNode(key, true)
}
func (sl *skipListOrdered[K, V]) doFindNode(key K, eq bool) *skipListNode[K, V] {
// This function execute the job of findNode if eq is true, otherwise lowBound.
// Passing the control variable eq is ugly but it's faster than testing node
// again outside the function in findNode.
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
if cur.key == key {
return cur
}
if cur.key > key {
// All other node in this level must be greater than the key,
// search the next level.
break
}
prev = cur
}
}
if eq {
return nil
}
return prev.next[0]
}
func (sl *skipListOrdered[K, V]) lowerBound(key K) *skipListNode[K, V] {
return sl.doFindNode(key, false)
}
func (sl *skipListOrdered[K, V]) upperBound(key K) *skipListNode[K, V] {
node := sl.lowerBound(key)
if node != nil && node.key == key {
return node.next[0]
}
return node
}
// findInsertPoint returns (*node, nil) to the existed node if the key exists,
// or (nil, []*node) to the previous nodes if the key doesn't exist
func (sl *skipListOrdered[K, V]) findInsertPoint(key K) (*skipListNode[K, V], []*skipListNode[K, V]) {
prevs := sl.prevsCache[0:sl.level]
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for next := prev.next[i]; next != nil; next = next.next[i] {
if next.key == key {
// The key is already existed, prevs are useless because no new node insertion.
// stop searching.
return next, nil
}
if next.key > key {
// All other node in this level must be greater than the key,
// search the next level.
break
}
prev = next
}
prevs[i] = prev
}
return nil, prevs
}
// findRemovePoint finds the node which match the key and it's previous nodes.
func (sl *skipListOrdered[K, V]) findRemovePoint(key K) (*skipListNode[K, V], []*skipListNode[K, V]) {
prevs := sl.findPrevNodes(key)
node := prevs[0].next[0]
if node == nil || node.key != key {
return nil, nil
}
return node, prevs
}
func (sl *skipListOrdered[K, V]) findPrevNodes(key K) []*skipListNode[K, V] {
prevs := sl.prevsCache[0:sl.level]
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for next := prev.next[i]; next != nil; next = next.next[i] {
if next.key >= key {
break
}
prev = next
}
prevs[i] = prev
}
return prevs
}
/// skipListFunc part
// skipListFunc is the skip list implementation which compare keys with func.
type skipListFunc[K any, V any] struct {
SkipList[K, V]
keyCmp CompareFn[K]
}
func (sl *skipListFunc[K, V]) findNode(key K) *skipListNode[K, V] {
node := sl.lowerBound(key)
if node != nil && sl.keyCmp(node.key, key) == 0 {
return node
}
return nil
}
func (sl *skipListFunc[K, V]) lowerBound(key K) *skipListNode[K, V] {
var prev = &sl.head
for i := sl.level - 1; i >= 0; i-- {
cur := prev.next[i]
for ; cur != nil; cur = cur.next[i] {
cmpRet := sl.keyCmp(cur.key, key)
if cmpRet == 0 {
return cur
}
if cmpRet > 0 {
break
}
prev = cur
}
}
return prev.next[0]
}
func (sl *skipListFunc[K, V]) upperBound(key K) *skipListNode[K, V] {
node := sl.lowerBound(key)
if node != nil && sl.keyCmp(node.key, key) == 0 {
return node.next[0]
}
return node
}
// findInsertPoint returns (*node, nil) to the existed node if the key exists,
// or (nil, []*node) to the previous nodes if the key doesn't exist
func (sl *skipListFunc[K, V]) findInsertPoint(key K) (*skipListNode[K, V], []*skipListNode[K, V]) {
prevs := sl.prevsCache[0:sl.level]
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
r := sl.keyCmp(cur.key, key)
if r == 0 {
// The key is already existed, prevs are useless because no new node insertion.
// stop searching.
return cur, nil
}
if r > 0 {
// All other node in this level must be greater than the key,
// search the next level.
break
}
prev = cur
}
prevs[i] = prev
}
return nil, prevs
}
// findRemovePoint finds the node which match the key and it's previous nodes.
func (sl *skipListFunc[K, V]) findRemovePoint(key K) (*skipListNode[K, V], []*skipListNode[K, V]) {
prevs := sl.findPrevNodes(key)
node := prevs[0].next[0]
if node == nil || sl.keyCmp(node.key, key) != 0 {
return nil, nil
}
return node, prevs
}
func (sl *skipListFunc[K, V]) findPrevNodes(key K) []*skipListNode[K, V] {
prevs := sl.prevsCache[0:sl.level]
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for next := prev.next[i]; next != nil; next = next.next[i] {
if sl.keyCmp(next.key, key) >= 0 {
break
}
prev = next
}
prevs[i] = prev
}
return prevs
}