Skip to content

Commit 985fbc0

Browse files
Merge pull request Workiva#146 from azr/master
slice/skip: atomize SkipList.num operations
2 parents c99f2e5 + 33938ac commit 985fbc0

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

slice/skip/skip.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ package skip
6060
import (
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

219220
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
221222
return nil, 1
222223
}
223224

@@ -253,11 +254,11 @@ func (sl *SkipList) resetMaxLevel() {
253254
}
254255

255256
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
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

341342
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()
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.
416417
func (sl *SkipList) Len() uint64 {
417-
return sl.num
418+
return atomic.LoadUint64(&sl.num)
418419
}
419420

420421
func (sl *SkipList) iterAtPosition(pos uint64) *iterator {
@@ -462,7 +463,7 @@ func (sl *SkipList) Iter(cmp common.Comparator) Iterator {
462463
// the content of this list.
463464
func (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

Comments
 (0)