├── README.md ├── element.go ├── skiplist.go └── skiplist_test.go /README.md: -------------------------------------------------------------------------------- 1 | skiplist 2 | =============== 3 | 4 | reference from redis [zskiplist](https://github.com/antirez/redis) 5 | 6 | 7 | Usage 8 | =============== 9 | 10 | ~~~Go 11 | 12 | package main 13 | 14 | import ( 15 | "fmt" 16 | "github.com/gansidui/skiplist" 17 | "log" 18 | ) 19 | 20 | type User struct { 21 | score float64 22 | id string 23 | } 24 | 25 | func (u *User) Less(other interface{}) bool { 26 | if u.score > other.(*User).score { 27 | return true 28 | } 29 | if u.score == other.(*User).score && len(u.id) > len(other.(*User).id) { 30 | return true 31 | } 32 | return false 33 | } 34 | 35 | func main() { 36 | us := make([]*User, 7) 37 | us[0] = &User{6.6, "hi"} 38 | us[1] = &User{4.4, "hello"} 39 | us[2] = &User{2.2, "world"} 40 | us[3] = &User{3.3, "go"} 41 | us[4] = &User{1.1, "skip"} 42 | us[5] = &User{2.2, "list"} 43 | us[6] = &User{3.3, "lang"} 44 | 45 | // insert 46 | sl := skiplist.New() 47 | for i := 0; i < len(us); i++ { 48 | sl.Insert(us[i]) 49 | } 50 | 51 | // traverse 52 | for e := sl.Front(); e != nil; e = e.Next() { 53 | fmt.Println(e.Value.(*User).id, "-->", e.Value.(*User).score) 54 | } 55 | fmt.Println() 56 | 57 | // rank 58 | rank1 := sl.GetRank(&User{2.2, "list"}) 59 | rank2 := sl.GetRank(&User{6.6, "hi"}) 60 | if rank1 != 6 || rank2 != 1 { 61 | log.Fatal() 62 | } 63 | if e := sl.GetElementByRank(2); e.Value.(*User).score != 4.4 || e.Value.(*User).id != "hello" { 64 | log.Fatal() 65 | } 66 | } 67 | 68 | /* output: 69 | 70 | hi --> 6.6 71 | hello --> 4.4 72 | lang --> 3.3 73 | go --> 3.3 74 | world --> 2.2 75 | list --> 2.2 76 | skip --> 1.1 77 | 78 | */ 79 | 80 | ~~~ 81 | 82 | 83 | License 84 | =============== 85 | 86 | MIT -------------------------------------------------------------------------------- /element.go: -------------------------------------------------------------------------------- 1 | package skiplist 2 | 3 | import ( 4 | "math/rand" 5 | ) 6 | 7 | const SKIPLIST_MAXLEVEL = 32 8 | const SKIPLIST_BRANCH = 4 9 | 10 | type skiplistLevel struct { 11 | forward *Element 12 | span int 13 | } 14 | 15 | type Element struct { 16 | Value Interface 17 | backward *Element 18 | level []*skiplistLevel 19 | } 20 | 21 | // Next returns the next skiplist element or nil. 22 | func (e *Element) Next() *Element { 23 | return e.level[0].forward 24 | } 25 | 26 | // Prev returns the previous skiplist element of nil. 27 | func (e *Element) Prev() *Element { 28 | return e.backward 29 | } 30 | 31 | // newElement returns an initialized element. 32 | func newElement(level int, v Interface) *Element { 33 | slLevels := make([]*skiplistLevel, level) 34 | for i := 0; i < level; i++ { 35 | slLevels[i] = new(skiplistLevel) 36 | } 37 | 38 | return &Element{ 39 | Value: v, 40 | backward: nil, 41 | level: slLevels, 42 | } 43 | } 44 | 45 | // randomLevel returns a random level. 46 | func randomLevel() int { 47 | level := 1 48 | for (rand.Int31()&0xFFFF)%SKIPLIST_BRANCH == 0 { 49 | level += 1 50 | } 51 | 52 | if level < SKIPLIST_MAXLEVEL { 53 | return level 54 | } else { 55 | return SKIPLIST_MAXLEVEL 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /skiplist.go: -------------------------------------------------------------------------------- 1 | package skiplist 2 | 3 | type Interface interface { 4 | Less(other interface{}) bool 5 | } 6 | 7 | type SkipList struct { 8 | header *Element 9 | tail *Element 10 | update []*Element 11 | rank []int 12 | length int 13 | level int 14 | } 15 | 16 | // New returns an initialized skiplist. 17 | func New() *SkipList { 18 | return &SkipList{ 19 | header: newElement(SKIPLIST_MAXLEVEL, nil), 20 | tail: nil, 21 | update: make([]*Element, SKIPLIST_MAXLEVEL), 22 | rank: make([]int, SKIPLIST_MAXLEVEL), 23 | length: 0, 24 | level: 1, 25 | } 26 | } 27 | 28 | // Init initializes or clears skiplist sl. 29 | func (sl *SkipList) Init() *SkipList { 30 | sl.header = newElement(SKIPLIST_MAXLEVEL, nil) 31 | sl.tail = nil 32 | sl.update = make([]*Element, SKIPLIST_MAXLEVEL) 33 | sl.rank = make([]int, SKIPLIST_MAXLEVEL) 34 | sl.length = 0 35 | sl.level = 1 36 | return sl 37 | } 38 | 39 | // Front returns the first elements of skiplist sl or nil. 40 | func (sl *SkipList) Front() *Element { 41 | return sl.header.level[0].forward 42 | } 43 | 44 | // Back returns the last elements of skiplist sl or nil. 45 | func (sl *SkipList) Back() *Element { 46 | return sl.tail 47 | } 48 | 49 | // Len returns the numbler of elements of skiplist sl. 50 | func (sl *SkipList) Len() int { 51 | return sl.length 52 | } 53 | 54 | // Insert inserts v, increments sl.length, and returns a new element of wrap v. 55 | func (sl *SkipList) Insert(v Interface) *Element { 56 | x := sl.header 57 | for i := sl.level - 1; i >= 0; i-- { 58 | // store rank that is crossed to reach the insert position 59 | if i == sl.level-1 { 60 | sl.rank[i] = 0 61 | } else { 62 | sl.rank[i] = sl.rank[i+1] 63 | } 64 | for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { 65 | sl.rank[i] += x.level[i].span 66 | x = x.level[i].forward 67 | } 68 | sl.update[i] = x 69 | } 70 | 71 | // ensure that the v is unique, the re-insertion of v should never happen since the 72 | // caller of sl.Insert() should test in the hash table if the element is already inside or not. 73 | level := randomLevel() 74 | if level > sl.level { 75 | for i := sl.level; i < level; i++ { 76 | sl.rank[i] = 0 77 | sl.update[i] = sl.header 78 | sl.update[i].level[i].span = sl.length 79 | } 80 | sl.level = level 81 | } 82 | 83 | x = newElement(level, v) 84 | for i := 0; i < level; i++ { 85 | x.level[i].forward = sl.update[i].level[i].forward 86 | sl.update[i].level[i].forward = x 87 | 88 | // update span covered by update[i] as x is inserted here 89 | x.level[i].span = sl.update[i].level[i].span - sl.rank[0] + sl.rank[i] 90 | sl.update[i].level[i].span = sl.rank[0] - sl.rank[i] + 1 91 | } 92 | 93 | // increment span for untouched levels 94 | for i := level; i < sl.level; i++ { 95 | sl.update[i].level[i].span++ 96 | } 97 | 98 | if sl.update[0] == sl.header { 99 | x.backward = nil 100 | } else { 101 | x.backward = sl.update[0] 102 | } 103 | if x.level[0].forward != nil { 104 | x.level[0].forward.backward = x 105 | } else { 106 | sl.tail = x 107 | } 108 | sl.length++ 109 | 110 | return x 111 | } 112 | 113 | // deleteElement deletes e from its skiplist, and decrements sl.length. 114 | func (sl *SkipList) deleteElement(e *Element, update []*Element) { 115 | for i := 0; i < sl.level; i++ { 116 | if update[i].level[i].forward == e { 117 | update[i].level[i].span += e.level[i].span - 1 118 | update[i].level[i].forward = e.level[i].forward 119 | } else { 120 | update[i].level[i].span -= 1 121 | } 122 | } 123 | 124 | if e.level[0].forward != nil { 125 | e.level[0].forward.backward = e.backward 126 | } else { 127 | sl.tail = e.backward 128 | } 129 | 130 | for sl.level > 1 && sl.header.level[sl.level-1].forward == nil { 131 | sl.level-- 132 | } 133 | sl.length-- 134 | } 135 | 136 | // Remove removes e from sl if e is an element of skiplist sl. 137 | // It returns the element value e.Value. 138 | func (sl *SkipList) Remove(e *Element) interface{} { 139 | x := sl.find(e.Value) // x.Value >= e.Value 140 | if x == e && !e.Value.Less(x.Value) { // e.Value >= x.Value 141 | sl.deleteElement(x, sl.update) 142 | return x.Value 143 | } 144 | 145 | return nil 146 | } 147 | 148 | // Delete deletes an element e that e.Value == v, and returns e.Value or nil. 149 | func (sl *SkipList) Delete(v Interface) interface{} { 150 | x := sl.find(v) // x.Value >= v 151 | if x != nil && !v.Less(x.Value) { // v >= x.Value 152 | sl.deleteElement(x, sl.update) 153 | return x.Value 154 | } 155 | 156 | return nil 157 | } 158 | 159 | // Find finds an element e that e.Value == v, and returns e or nil. 160 | func (sl *SkipList) Find(v Interface) *Element { 161 | x := sl.find(v) // x.Value >= v 162 | if x != nil && !v.Less(x.Value) { // v >= x.Value 163 | return x 164 | } 165 | 166 | return nil 167 | } 168 | 169 | // find finds the first element e that e.Value >= v, and returns e or nil. 170 | func (sl *SkipList) find(v Interface) *Element { 171 | x := sl.header 172 | for i := sl.level - 1; i >= 0; i-- { 173 | for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { 174 | x = x.level[i].forward 175 | } 176 | sl.update[i] = x 177 | } 178 | 179 | return x.level[0].forward 180 | } 181 | 182 | // GetRank finds the rank for an element e that e.Value == v, 183 | // Returns 0 when the element cannot be found, rank otherwise. 184 | // Note that the rank is 1-based due to the span of sl.header to the first element. 185 | func (sl *SkipList) GetRank(v Interface) int { 186 | x := sl.header 187 | rank := 0 188 | for i := sl.level - 1; i >= 0; i-- { 189 | for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { 190 | rank += x.level[i].span 191 | x = x.level[i].forward 192 | } 193 | if x.level[i].forward != nil && !x.level[i].forward.Value.Less(v) && !v.Less(x.level[i].forward.Value) { 194 | rank += x.level[i].span 195 | return rank 196 | } 197 | } 198 | 199 | return 0 200 | } 201 | 202 | // GetElementByRank finds an element by ites rank. The rank argument needs bo be 1-based. 203 | // Note that is the first element e that GetRank(e.Value) == rank, and returns e or nil. 204 | func (sl *SkipList) GetElementByRank(rank int) *Element { 205 | x := sl.header 206 | traversed := 0 207 | for i := sl.level - 1; i >= 0; i-- { 208 | for x.level[i].forward != nil && traversed+x.level[i].span <= rank { 209 | traversed += x.level[i].span 210 | x = x.level[i].forward 211 | } 212 | if traversed == rank { 213 | return x 214 | } 215 | } 216 | 217 | return nil 218 | } 219 | -------------------------------------------------------------------------------- /skiplist_test.go: -------------------------------------------------------------------------------- 1 | package skiplist 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "sort" 7 | "testing" 8 | ) 9 | 10 | type Int int 11 | 12 | func (i Int) Less(other interface{}) bool { 13 | return i < other.(Int) 14 | } 15 | 16 | func TestInt(t *testing.T) { 17 | sl := New() 18 | if sl.Len() != 0 || sl.Front() != nil && sl.Back() != nil { 19 | t.Fatal() 20 | } 21 | 22 | testData := []Int{Int(1), Int(2), Int(3)} 23 | 24 | sl.Insert(testData[0]) 25 | if sl.Len() != 1 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[0] { 26 | t.Fatal() 27 | } 28 | 29 | sl.Insert(testData[2]) 30 | if sl.Len() != 2 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[2] { 31 | t.Fatal() 32 | } 33 | 34 | sl.Insert(testData[1]) 35 | if sl.Len() != 3 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[2] { 36 | t.Fatal() 37 | } 38 | 39 | sl.Insert(Int(-999)) 40 | sl.Insert(Int(-888)) 41 | sl.Insert(Int(888)) 42 | sl.Insert(Int(999)) 43 | sl.Insert(Int(1000)) 44 | 45 | expect := []Int{Int(-999), Int(-888), Int(1), Int(2), Int(3), Int(888), Int(999), Int(1000)} 46 | ret := make([]Int, 0) 47 | 48 | for e := sl.Front(); e != nil; e = e.Next() { 49 | ret = append(ret, e.Value.(Int)) 50 | } 51 | for i := 0; i < len(ret); i++ { 52 | if ret[i] != expect[i] { 53 | t.Fatal() 54 | } 55 | } 56 | 57 | e := sl.Find(Int(2)) 58 | if e == nil || e.Value.(Int) != 2 { 59 | t.Fatal() 60 | } 61 | 62 | ret = make([]Int, 0) 63 | for ; e != nil; e = e.Next() { 64 | ret = append(ret, e.Value.(Int)) 65 | } 66 | for i := 0; i < len(ret); i++ { 67 | if ret[i] != expect[i+3] { 68 | t.Fatal() 69 | } 70 | } 71 | 72 | sl.Remove(sl.Find(Int(2))) 73 | sl.Delete(Int(888)) 74 | sl.Delete(Int(1000)) 75 | 76 | expect = []Int{Int(-999), Int(-888), Int(1), Int(3), Int(999)} 77 | ret = make([]Int, 0) 78 | 79 | for e := sl.Back(); e != nil; e = e.Prev() { 80 | ret = append(ret, e.Value.(Int)) 81 | } 82 | 83 | for i := 0; i < len(ret); i++ { 84 | if ret[i] != expect[len(ret)-i-1] { 85 | t.Fatal() 86 | } 87 | } 88 | 89 | if sl.Front().Value.(Int) != -999 { 90 | t.Fatal() 91 | } 92 | 93 | sl.Remove(sl.Front()) 94 | if sl.Front().Value.(Int) != -888 || sl.Back().Value.(Int) != 999 { 95 | t.Fatal() 96 | } 97 | 98 | sl.Remove(sl.Back()) 99 | if sl.Front().Value.(Int) != -888 || sl.Back().Value.(Int) != 3 { 100 | t.Fatal() 101 | } 102 | 103 | if e = sl.Insert(Int(2)); e.Value.(Int) != 2 { 104 | t.Fatal() 105 | } 106 | sl.Delete(Int(-888)) 107 | 108 | if r := sl.Delete(Int(123)); r != nil { 109 | t.Fatal() 110 | } 111 | 112 | if sl.Len() != 3 { 113 | t.Fatal() 114 | } 115 | 116 | sl.Insert(Int(2)) 117 | sl.Insert(Int(2)) 118 | sl.Insert(Int(1)) 119 | 120 | if e = sl.Find(Int(2)); e == nil { 121 | t.Fatal() 122 | } 123 | 124 | expect = []Int{Int(2), Int(2), Int(2), Int(3)} 125 | ret = make([]Int, 0) 126 | for ; e != nil; e = e.Next() { 127 | ret = append(ret, e.Value.(Int)) 128 | } 129 | for i := 0; i < len(ret); i++ { 130 | if ret[i] != expect[i] { 131 | t.Fatal() 132 | } 133 | } 134 | 135 | sl2 := sl.Init() 136 | if sl.Len() != 0 || sl.Front() != nil || sl.Back() != nil || 137 | sl2.Len() != 0 || sl2.Front() != nil || sl2.Back() != nil { 138 | t.Fatal() 139 | } 140 | 141 | // for i := 0; i < 100; i++ { 142 | // sl.Insert(Int(rand.Intn(200))) 143 | // } 144 | // output(sl) 145 | } 146 | 147 | func TestRank(t *testing.T) { 148 | sl := New() 149 | 150 | for i := 1; i <= 10; i++ { 151 | sl.Insert(Int(i)) 152 | } 153 | 154 | for i := 1; i <= 10; i++ { 155 | if sl.GetRank(Int(i)) != i { 156 | t.Fatal() 157 | } 158 | } 159 | 160 | for i := 1; i <= 10; i++ { 161 | if sl.GetElementByRank(i).Value != Int(i) { 162 | t.Fatal() 163 | } 164 | } 165 | 166 | if sl.GetRank(Int(0)) != 0 || sl.GetRank(Int(11)) != 0 { 167 | t.Fatal() 168 | } 169 | 170 | if sl.GetElementByRank(11) != nil || sl.GetElementByRank(12) != nil { 171 | t.Fatal() 172 | } 173 | 174 | expect := []Int{Int(7), Int(8), Int(9), Int(10)} 175 | for e, i := sl.GetElementByRank(7), 0; e != nil; e, i = e.Next(), i+1 { 176 | if e.Value != expect[i] { 177 | t.Fatal() 178 | } 179 | } 180 | 181 | sl = sl.Init() 182 | mark := make(map[int]bool) 183 | ss := make([]int, 0) 184 | 185 | for i := 1; i <= 100000; i++ { 186 | x := rand.Int() 187 | if !mark[x] { 188 | mark[x] = true 189 | sl.Insert(Int(x)) 190 | ss = append(ss, x) 191 | } 192 | } 193 | sort.Ints(ss) 194 | 195 | for i := 0; i < len(ss); i++ { 196 | if sl.GetElementByRank(i+1).Value != Int(ss[i]) || sl.GetRank(Int(ss[i])) != i+1 { 197 | t.Fatal() 198 | } 199 | } 200 | 201 | // output(sl) 202 | } 203 | 204 | func BenchmarkIntInsertOrder(b *testing.B) { 205 | b.StopTimer() 206 | sl := New() 207 | b.StartTimer() 208 | 209 | for i := 0; i < b.N; i++ { 210 | sl.Insert(Int(i)) 211 | } 212 | } 213 | 214 | func BenchmarkIntInsertRandom(b *testing.B) { 215 | b.StopTimer() 216 | sl := New() 217 | b.StartTimer() 218 | 219 | for i := 0; i < b.N; i++ { 220 | sl.Insert(Int(rand.Int())) 221 | } 222 | } 223 | 224 | func BenchmarkIntDeleteOrder(b *testing.B) { 225 | b.StopTimer() 226 | sl := New() 227 | for i := 0; i < 1000000; i++ { 228 | sl.Insert(Int(i)) 229 | } 230 | b.StartTimer() 231 | 232 | for i := 0; i < b.N; i++ { 233 | sl.Delete(Int(i)) 234 | } 235 | } 236 | 237 | func BenchmarkIntDeleteRandome(b *testing.B) { 238 | b.StopTimer() 239 | sl := New() 240 | for i := 0; i < 1000000; i++ { 241 | sl.Insert(Int(rand.Int())) 242 | } 243 | b.StartTimer() 244 | 245 | for i := 0; i < b.N; i++ { 246 | sl.Delete(Int(rand.Int())) 247 | } 248 | } 249 | 250 | func BenchmarkIntFindOrder(b *testing.B) { 251 | b.StopTimer() 252 | sl := New() 253 | for i := 0; i < 1000000; i++ { 254 | sl.Insert(Int(i)) 255 | } 256 | b.StartTimer() 257 | 258 | for i := 0; i < b.N; i++ { 259 | sl.Find(Int(i)) 260 | } 261 | } 262 | 263 | func BenchmarkIntFindRandom(b *testing.B) { 264 | b.StopTimer() 265 | sl := New() 266 | for i := 0; i < 1000000; i++ { 267 | sl.Insert(Int(rand.Int())) 268 | } 269 | b.StartTimer() 270 | 271 | for i := 0; i < b.N; i++ { 272 | sl.Find(Int(rand.Int())) 273 | } 274 | } 275 | 276 | func BenchmarkIntRankOrder(b *testing.B) { 277 | b.StopTimer() 278 | sl := New() 279 | for i := 0; i < 1000000; i++ { 280 | sl.Insert(Int(i)) 281 | } 282 | b.StartTimer() 283 | 284 | for i := 0; i < b.N; i++ { 285 | sl.GetRank(Int(i)) 286 | } 287 | } 288 | 289 | func BenchmarkIntRankRandom(b *testing.B) { 290 | b.StopTimer() 291 | sl := New() 292 | for i := 0; i < 1000000; i++ { 293 | sl.Insert(Int(rand.Int())) 294 | } 295 | b.StartTimer() 296 | 297 | for i := 0; i < b.N; i++ { 298 | sl.GetRank(Int(rand.Int())) 299 | } 300 | } 301 | 302 | func output(sl *SkipList) { 303 | var x *Element 304 | for i := 0; i < SKIPLIST_MAXLEVEL; i++ { 305 | fmt.Printf("LEVEL[%v]: ", i) 306 | count := 0 307 | x = sl.header.level[i].forward 308 | for x != nil { 309 | // fmt.Printf("%v -> ", x.Value) 310 | count++ 311 | x = x.level[i].forward 312 | } 313 | // fmt.Println("NIL") 314 | fmt.Println("count==", count) 315 | } 316 | } 317 | --------------------------------------------------------------------------------