@@ -60,6 +60,7 @@ package skip
6060import (
6161 "math/rand"
6262 "sync"
63+ "sync/atomic"
6364 "time"
6465
6566 "github.com/Workiva/go-datastructures/common"
@@ -120,7 +121,7 @@ func insertNode(sl *SkipList, n *node, cmp common.Comparator, pos uint64, cache
120121 n .entry = cmp
121122 return oldEntry
122123 }
123- sl .num ++
124+ atomic . AddUint64 ( & sl .num , 1 )
124125
125126 nodeLevel := generateLevel (sl .maxLevel )
126127 if nodeLevel > sl .level {
@@ -174,8 +175,8 @@ func splitAt(sl *SkipList, index uint64) (*SkipList, *SkipList) {
174175 sl .cache [i ].forward [i ] = nil
175176 }
176177
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 )
179180
180181 sl .resetMaxLevel ()
181182 right .resetMaxLevel ()
@@ -217,7 +218,7 @@ func (sl *SkipList) init(ifc interface{}) {
217218}
218219
219220func (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
221222 return nil , 1
222223 }
223224
@@ -253,11 +254,11 @@ func (sl *SkipList) resetMaxLevel() {
253254}
254255
255256func (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
257258 return nil , 1
258259 }
259260
260- if position > sl .num {
261+ if position > sl .Len () {
261262 return nil , 1
262263 }
263264
@@ -339,8 +340,8 @@ func (sl *SkipList) Insert(comparators ...common.Comparator) common.Comparators
339340}
340341
341342func (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 ()
344345 }
345346 n , pos := sl .searchByPosition (position , sl .cache , sl .posCache )
346347 insertNode (sl , n , cmp , pos , sl .cache , sl .posCache , true )
@@ -377,7 +378,7 @@ func (sl *SkipList) delete(cmp common.Comparator) common.Comparator {
377378 return nil
378379 }
379380
380- sl .num --
381+ atomic . AddUint64 ( & sl .num , ^ uint64 ( 0 )) // decrement
381382
382383 for i := uint8 (0 ); i <= sl .level ; i ++ {
383384 if sl .cache [i ].forward [i ] != n {
@@ -414,7 +415,7 @@ func (sl *SkipList) Delete(comparators ...common.Comparator) common.Comparators
414415
415416// Len returns the number of items in this skiplist.
416417func (sl * SkipList ) Len () uint64 {
417- return sl .num
418+ return atomic . LoadUint64 ( & sl .num )
418419}
419420
420421func (sl * SkipList ) iterAtPosition (pos uint64 ) * iterator {
@@ -462,7 +463,7 @@ func (sl *SkipList) Iter(cmp common.Comparator) Iterator {
462463// the content of this list.
463464func (sl * SkipList ) SplitAt (index uint64 ) (* SkipList , * SkipList ) {
464465 index ++ // 0-index offset
465- if index >= sl .num {
466+ if index >= sl .Len () {
466467 return sl , nil
467468 }
468469 return splitAt (sl , index )
0 commit comments