github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/skl/skl.go (about) 1 package skl 2 3 import ( 4 "math" 5 6 "github.com/zhiqiangxu/util" 7 ) 8 9 const ( 10 // DefaultMaxLevel for skl 11 DefaultMaxLevel int = 18 12 // DefaultProbability for skl 13 DefaultProbability float64 = 1 / math.E 14 ) 15 16 type link struct { 17 next *element 18 } 19 20 type element struct { 21 links []link 22 key int64 23 value interface{} 24 } 25 26 type skl struct { 27 links []link 28 maxLevel int 29 length int 30 probability float64 31 probTable []uint32 32 prevLinksCache []*link 33 } 34 35 // NewSkipList creates a new SkipList 36 func NewSkipList() SkipList { 37 return NewSkipListWithMaxLevel(DefaultMaxLevel) 38 } 39 40 // NewSkipListWithMaxLevel creates a new SkipList with specified maxLevel 41 func NewSkipListWithMaxLevel(maxLevel int) SkipList { 42 return &skl{ 43 links: make([]link, maxLevel), 44 maxLevel: maxLevel, 45 probability: DefaultProbability, 46 probTable: probabilityTable(DefaultProbability, maxLevel), 47 prevLinksCache: make([]*link, maxLevel), 48 } 49 } 50 51 func probabilityTable(probability float64, maxLevel int) (table []uint32) { 52 for i := 0; i < maxLevel; i++ { 53 prob := math.Pow(probability, float64(i)) 54 table = append(table, uint32(prob*math.MaxUint32)) 55 } 56 return table 57 } 58 59 func (s *skl) Add(key int64, value interface{}) { 60 // prev := s.links 61 // for i := s.maxLevel - 1; i >= 0; i-- { 62 // s.findSpliceForLevel(key, prev, i) 63 // } 64 65 prevs := s.getPrevLinks(key) 66 ele := prevs[0].next 67 if ele != nil && ele.key <= key { 68 ele.value = value 69 return 70 } 71 72 ele = &element{ 73 links: make([]link, s.randLevel()), 74 key: key, 75 value: value, 76 } 77 78 for i := range ele.links { 79 ele.links[i].next = prevs[i].next 80 prevs[i].next = ele 81 } 82 83 s.length++ 84 } 85 86 func (s *skl) Length() int { 87 return s.length 88 } 89 90 func (s *skl) randLevel() (level int) { 91 92 r := util.FastRand() 93 94 level = 1 95 for level < s.maxLevel && r < s.probTable[level] { 96 level++ 97 } 98 return 99 } 100 101 // 找到每一层上毗邻于该key对应元素之前的links 102 // 返回的是*link,所以可以原地更新 103 func (s *skl) getPrevLinks(key int64) []*link { 104 var prev = s.links 105 var current *element 106 107 prevs := s.prevLinksCache 108 for i := s.maxLevel - 1; i >= 0; i-- { 109 current = prev[i].next 110 111 for current != nil && current.key < key { 112 prev = current.links 113 current = prev[i].next 114 } 115 116 prevs[i] = &prev[i] 117 } 118 119 return prevs 120 } 121 122 // func (s *skl) findSpliceForLevel(key int64, prev []link, level0based int) (before, next *element) { 123 124 // current := prev[level0based].next 125 // for current != nil && current.key < key { 126 // prev = current.links 127 // current = prev[level0based].next 128 // } 129 130 // before = &prev[level0based] 131 132 // if current != nil { 133 // if current.key == key { 134 // next = before 135 // } else { 136 // next = ¤t.links[level0based] 137 // } 138 // } 139 140 // return 141 // } 142 143 func (s *skl) Get(key int64) (value interface{}, ok bool) { 144 prev := s.links 145 var current *element 146 for i := s.maxLevel - 1; i >= 0; i-- { 147 current = prev[i].next 148 for current != nil && current.key < key { 149 prev = current.links 150 current = current.links[i].next 151 } 152 } 153 154 if current != nil && current.key <= key { 155 return current.value, true 156 } 157 158 return nil, false 159 } 160 161 func (s *skl) Remove(key int64) { 162 prevs := s.getPrevLinks(key) 163 if ele := prevs[0].next; ele != nil && ele.key <= key { 164 165 for i, l := range ele.links { 166 prevs[i].next = l.next 167 } 168 s.length-- 169 } 170 } 171 172 func (s *skl) Head() (key int64, value interface{}, ok bool) { 173 nele := s.links[0].next 174 if nele != nil { 175 key = nele.key 176 value = nele.value 177 ok = true 178 } 179 return 180 } 181 182 func (s *skl) NewIterator() SkipListIterator { 183 return &sklIter{s: s} 184 }