@@ -60,6 +60,7 @@ package skip
60
60
import (
61
61
"math/rand"
62
62
"sync"
63
+ "sync/atomic"
63
64
"time"
64
65
65
66
"github.com/Workiva/go-datastructures/common"
@@ -120,7 +121,7 @@ func insertNode(sl *SkipList, n *node, cmp common.Comparator, pos uint64, cache
120
121
n .entry = cmp
121
122
return oldEntry
122
123
}
123
- sl .num ++
124
+ atomic . AddUint64 ( & sl .num , 1 )
124
125
125
126
nodeLevel := generateLevel (sl .maxLevel )
126
127
if nodeLevel > sl .level {
@@ -174,8 +175,8 @@ func splitAt(sl *SkipList, index uint64) (*SkipList, *SkipList) {
174
175
sl .cache [i ].forward [i ] = nil
175
176
}
176
177
177
- right .num = sl .num - index
178
- sl . num = sl .num - right .num
178
+ right .num = sl .Len () - index // right is not in user's hands yet
179
+ atomic . AddUint64 ( & sl .num , - right .num )
179
180
180
181
sl .resetMaxLevel ()
181
182
right .resetMaxLevel ()
@@ -217,7 +218,7 @@ func (sl *SkipList) init(ifc interface{}) {
217
218
}
218
219
219
220
func (sl * SkipList ) search (cmp common.Comparator , update nodes , widths widths ) (* node , uint64 ) {
220
- if sl .num == 0 { // nothing in the list
221
+ if sl .Len () == 0 { // nothing in the list
221
222
return nil , 1
222
223
}
223
224
@@ -253,11 +254,11 @@ func (sl *SkipList) resetMaxLevel() {
253
254
}
254
255
255
256
func (sl * SkipList ) searchByPosition (position uint64 , update nodes , widths widths ) (* node , uint64 ) {
256
- if sl .num == 0 { // nothing in the list
257
+ if sl .Len () == 0 { // nothing in the list
257
258
return nil , 1
258
259
}
259
260
260
- if position > sl .num {
261
+ if position > sl .Len () {
261
262
return nil , 1
262
263
}
263
264
@@ -339,8 +340,8 @@ func (sl *SkipList) Insert(comparators ...common.Comparator) common.Comparators
339
340
}
340
341
341
342
func (sl * SkipList ) insertAtPosition (position uint64 , cmp common.Comparator ) {
342
- if position > sl .num {
343
- position = sl .num
343
+ if position > sl .Len () {
344
+ position = sl .Len ()
344
345
}
345
346
n , pos := sl .searchByPosition (position , sl .cache , sl .posCache )
346
347
insertNode (sl , n , cmp , pos , sl .cache , sl .posCache , true )
@@ -377,7 +378,7 @@ func (sl *SkipList) delete(cmp common.Comparator) common.Comparator {
377
378
return nil
378
379
}
379
380
380
- sl .num --
381
+ atomic . AddUint64 ( & sl .num , ^ uint64 ( 0 )) // decrement
381
382
382
383
for i := uint8 (0 ); i <= sl .level ; i ++ {
383
384
if sl .cache [i ].forward [i ] != n {
@@ -414,7 +415,7 @@ func (sl *SkipList) Delete(comparators ...common.Comparator) common.Comparators
414
415
415
416
// Len returns the number of items in this skiplist.
416
417
func (sl * SkipList ) Len () uint64 {
417
- return sl .num
418
+ return atomic . LoadUint64 ( & sl .num )
418
419
}
419
420
420
421
func (sl * SkipList ) iterAtPosition (pos uint64 ) * iterator {
@@ -462,7 +463,7 @@ func (sl *SkipList) Iter(cmp common.Comparator) Iterator {
462
463
// the content of this list.
463
464
func (sl * SkipList ) SplitAt (index uint64 ) (* SkipList , * SkipList ) {
464
465
index ++ // 0-index offset
465
- if index >= sl .num {
466
+ if index >= sl .Len () {
466
467
return sl , nil
467
468
}
468
469
return splitAt (sl , index )
0 commit comments