github.com/hdt3213/godis@v1.2.9/datastruct/sortedset/skiplist.go (about) 1 package sortedset 2 3 import ( 4 "math/bits" 5 "math/rand" 6 ) 7 8 const ( 9 maxLevel = 16 10 ) 11 12 // Element is a key-score pair 13 type Element struct { 14 Member string 15 Score float64 16 } 17 18 // Level aspect of a node 19 type Level struct { 20 forward *node // forward node has greater score 21 span int64 22 } 23 24 type node struct { 25 Element 26 backward *node 27 level []*Level // level[0] is base level 28 } 29 30 type skiplist struct { 31 header *node 32 tail *node 33 length int64 34 level int16 35 } 36 37 func makeNode(level int16, score float64, member string) *node { 38 n := &node{ 39 Element: Element{ 40 Score: score, 41 Member: member, 42 }, 43 level: make([]*Level, level), 44 } 45 for i := range n.level { 46 n.level[i] = new(Level) 47 } 48 return n 49 } 50 51 func makeSkiplist() *skiplist { 52 return &skiplist{ 53 level: 1, 54 header: makeNode(maxLevel, 0, ""), 55 } 56 } 57 58 func randomLevel() int16 { 59 total := uint64(1)<<uint64(maxLevel) - 1 60 k := rand.Uint64() % total 61 return maxLevel - int16(bits.Len64(k+1)) + 1 62 } 63 64 func (skiplist *skiplist) insert(member string, score float64) *node { 65 update := make([]*node, maxLevel) // link new node with node in `update` 66 rank := make([]int64, maxLevel) 67 68 // find position to insert 69 node := skiplist.header 70 for i := skiplist.level - 1; i >= 0; i-- { 71 if i == skiplist.level-1 { 72 rank[i] = 0 73 } else { 74 rank[i] = rank[i+1] // store rank that is crossed to reach the insert position 75 } 76 if node.level[i] != nil { 77 // traverse the skip list 78 for node.level[i].forward != nil && 79 (node.level[i].forward.Score < score || 80 (node.level[i].forward.Score == score && node.level[i].forward.Member < member)) { // same score, different key 81 rank[i] += node.level[i].span 82 node = node.level[i].forward 83 } 84 } 85 update[i] = node 86 } 87 88 level := randomLevel() 89 // extend skiplist level 90 if level > skiplist.level { 91 for i := skiplist.level; i < level; i++ { 92 rank[i] = 0 93 update[i] = skiplist.header 94 update[i].level[i].span = skiplist.length 95 } 96 skiplist.level = level 97 } 98 99 // make node and link into skiplist 100 node = makeNode(level, score, member) 101 for i := int16(0); i < level; i++ { 102 node.level[i].forward = update[i].level[i].forward 103 update[i].level[i].forward = node 104 105 // update span covered by update[i] as node is inserted here 106 node.level[i].span = update[i].level[i].span - (rank[0] - rank[i]) 107 update[i].level[i].span = (rank[0] - rank[i]) + 1 108 } 109 110 // increment span for untouched levels 111 for i := level; i < skiplist.level; i++ { 112 update[i].level[i].span++ 113 } 114 115 // set backward node 116 if update[0] == skiplist.header { 117 node.backward = nil 118 } else { 119 node.backward = update[0] 120 } 121 if node.level[0].forward != nil { 122 node.level[0].forward.backward = node 123 } else { 124 skiplist.tail = node 125 } 126 skiplist.length++ 127 return node 128 } 129 130 /* 131 * param node: node to delete 132 * param update: backward node (of target) 133 */ 134 func (skiplist *skiplist) removeNode(node *node, update []*node) { 135 for i := int16(0); i < skiplist.level; i++ { 136 if update[i].level[i].forward == node { 137 update[i].level[i].span += node.level[i].span - 1 138 update[i].level[i].forward = node.level[i].forward 139 } else { 140 update[i].level[i].span-- 141 } 142 } 143 if node.level[0].forward != nil { 144 node.level[0].forward.backward = node.backward 145 } else { 146 skiplist.tail = node.backward 147 } 148 for skiplist.level > 1 && skiplist.header.level[skiplist.level-1].forward == nil { 149 skiplist.level-- 150 } 151 skiplist.length-- 152 } 153 154 /* 155 * return: has found and removed node 156 */ 157 func (skiplist *skiplist) remove(member string, score float64) bool { 158 /* 159 * find backward node (of target) or last node of each level 160 * their forward need to be updated 161 */ 162 update := make([]*node, maxLevel) 163 node := skiplist.header 164 for i := skiplist.level - 1; i >= 0; i-- { 165 for node.level[i].forward != nil && 166 (node.level[i].forward.Score < score || 167 (node.level[i].forward.Score == score && 168 node.level[i].forward.Member < member)) { 169 node = node.level[i].forward 170 } 171 update[i] = node 172 } 173 node = node.level[0].forward 174 if node != nil && score == node.Score && node.Member == member { 175 skiplist.removeNode(node, update) 176 // free x 177 return true 178 } 179 return false 180 } 181 182 /* 183 * return: 1 based rank, 0 means member not found 184 */ 185 func (skiplist *skiplist) getRank(member string, score float64) int64 { 186 var rank int64 = 0 187 x := skiplist.header 188 for i := skiplist.level - 1; i >= 0; i-- { 189 for x.level[i].forward != nil && 190 (x.level[i].forward.Score < score || 191 (x.level[i].forward.Score == score && 192 x.level[i].forward.Member <= member)) { 193 rank += x.level[i].span 194 x = x.level[i].forward 195 } 196 197 /* x might be equal to zsl->header, so test if obj is non-NULL */ 198 if x.Member == member { 199 return rank 200 } 201 } 202 return 0 203 } 204 205 /* 206 * 1-based rank 207 */ 208 func (skiplist *skiplist) getByRank(rank int64) *node { 209 var i int64 = 0 210 n := skiplist.header 211 // scan from top level 212 for level := skiplist.level - 1; level >= 0; level-- { 213 for n.level[level].forward != nil && (i+n.level[level].span) <= rank { 214 i += n.level[level].span 215 n = n.level[level].forward 216 } 217 if i == rank { 218 return n 219 } 220 } 221 return nil 222 } 223 224 func (skiplist *skiplist) hasInRange(min *ScoreBorder, max *ScoreBorder) bool { 225 // min & max = empty 226 if min.Value > max.Value || (min.Value == max.Value && (min.Exclude || max.Exclude)) { 227 return false 228 } 229 // min > tail 230 n := skiplist.tail 231 if n == nil || !min.less(n.Score) { 232 return false 233 } 234 // max < head 235 n = skiplist.header.level[0].forward 236 if n == nil || !max.greater(n.Score) { 237 return false 238 } 239 return true 240 } 241 242 func (skiplist *skiplist) getFirstInScoreRange(min *ScoreBorder, max *ScoreBorder) *node { 243 if !skiplist.hasInRange(min, max) { 244 return nil 245 } 246 n := skiplist.header 247 // scan from top level 248 for level := skiplist.level - 1; level >= 0; level-- { 249 // if forward is not in range than move forward 250 for n.level[level].forward != nil && !min.less(n.level[level].forward.Score) { 251 n = n.level[level].forward 252 } 253 } 254 /* This is an inner range, so the next node cannot be NULL. */ 255 n = n.level[0].forward 256 if !max.greater(n.Score) { 257 return nil 258 } 259 return n 260 } 261 262 func (skiplist *skiplist) getLastInScoreRange(min *ScoreBorder, max *ScoreBorder) *node { 263 if !skiplist.hasInRange(min, max) { 264 return nil 265 } 266 n := skiplist.header 267 // scan from top level 268 for level := skiplist.level - 1; level >= 0; level-- { 269 for n.level[level].forward != nil && max.greater(n.level[level].forward.Score) { 270 n = n.level[level].forward 271 } 272 } 273 if !min.less(n.Score) { 274 return nil 275 } 276 return n 277 } 278 279 /* 280 * return removed elements 281 */ 282 func (skiplist *skiplist) RemoveRangeByScore(min *ScoreBorder, max *ScoreBorder, limit int) (removed []*Element) { 283 update := make([]*node, maxLevel) 284 removed = make([]*Element, 0) 285 // find backward nodes (of target range) or last node of each level 286 node := skiplist.header 287 for i := skiplist.level - 1; i >= 0; i-- { 288 for node.level[i].forward != nil { 289 if min.less(node.level[i].forward.Score) { // already in range 290 break 291 } 292 node = node.level[i].forward 293 } 294 update[i] = node 295 } 296 297 // node is the first one within range 298 node = node.level[0].forward 299 300 // remove nodes in range 301 for node != nil { 302 if !max.greater(node.Score) { // already out of range 303 break 304 } 305 next := node.level[0].forward 306 removedElement := node.Element 307 removed = append(removed, &removedElement) 308 skiplist.removeNode(node, update) 309 if limit > 0 && len(removed) == limit { 310 break 311 } 312 node = next 313 } 314 return removed 315 } 316 317 // 1-based rank, including start, exclude stop 318 func (skiplist *skiplist) RemoveRangeByRank(start int64, stop int64) (removed []*Element) { 319 var i int64 = 0 // rank of iterator 320 update := make([]*node, maxLevel) 321 removed = make([]*Element, 0) 322 323 // scan from top level 324 node := skiplist.header 325 for level := skiplist.level - 1; level >= 0; level-- { 326 for node.level[level].forward != nil && (i+node.level[level].span) < start { 327 i += node.level[level].span 328 node = node.level[level].forward 329 } 330 update[level] = node 331 } 332 333 i++ 334 node = node.level[0].forward // first node in range 335 336 // remove nodes in range 337 for node != nil && i < stop { 338 next := node.level[0].forward 339 removedElement := node.Element 340 removed = append(removed, &removedElement) 341 skiplist.removeNode(node, update) 342 node = next 343 i++ 344 } 345 return removed 346 }