skiplist.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. // MIT License
  2. //
  3. // Copyright (c) 2018 Maurice Tollmien (maurice.tollmien@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. // SOFTWARE.
  22. // Package skiplist is an implementation of a skiplist to store elements in increasing order.
  23. // It allows finding, insertion and deletion operations in approximately O(n log(n)).
  24. // Additionally, there are methods for retrieving the next and previous element as well as changing the actual value
  25. // without the need for re-insertion (as long as the key stays the same!)
  26. // Skiplist is a fast alternative to a balanced tree.
  27. package skiplist
  28. import (
  29. "fmt"
  30. "math/bits"
  31. "math/rand"
  32. "time"
  33. )
  34. const (
  35. // maxLevel denotes the maximum height of the skiplist. This height will keep the skiplist
  36. // efficient for up to 34m entries. If there is a need for much more, please adjust this constant accordingly.
  37. maxLevel = 25
  38. eps = 0.00001
  39. )
  40. // ListElement is the interface to implement for elements that are inserted into the skiplist.
  41. type ListElement interface {
  42. // ExtractKey() returns a float64 representation of the key that is used for insertion/deletion/find. It needs to establish an order over all elements
  43. ExtractKey() int64
  44. // A string representation of the element. Can be used for pretty-printing the list. Otherwise just return an empty string.
  45. String() string
  46. }
  47. // SkipListElement represents one actual Node in the skiplist structure.
  48. // It saves the actual element, pointers to the next nodes and a pointer to one previous node.
  49. type SkipListElement struct {
  50. next [maxLevel]*SkipListElement
  51. level int
  52. key int64
  53. value ListElement
  54. prev *SkipListElement
  55. }
  56. // SkipList is the actual skiplist representation.
  57. // It saves all nodes accessible from the start and end and keeps track of element count, eps and levels.
  58. type SkipList struct {
  59. startLevels [maxLevel]*SkipListElement
  60. endLevels [maxLevel]*SkipListElement
  61. maxNewLevel int
  62. maxLevel int
  63. elementCount int
  64. eps float64
  65. releaseList []*SkipListElement
  66. }
  67. // NewSeedEps returns a new empty, initialized Skiplist.
  68. // Given a seed, a deterministic height/list behaviour can be achieved.
  69. // Eps is used to compare keys given by the ExtractKey() function on equality.
  70. func NewSeedEps(seed int64, eps float64) SkipList {
  71. // Initialize random number generator.
  72. rand.Seed(seed)
  73. //fmt.Printf("SkipList seed: %v\n", seed)
  74. list := SkipList{
  75. startLevels: [maxLevel]*SkipListElement{},
  76. endLevels: [maxLevel]*SkipListElement{},
  77. maxNewLevel: maxLevel,
  78. maxLevel: 0,
  79. elementCount: 0,
  80. eps: eps,
  81. releaseList: make([]*SkipListElement, 0),
  82. }
  83. return list
  84. }
  85. // NewEps returns a new empty, initialized Skiplist.
  86. // Eps is used to compare keys given by the ExtractKey() function on equality.
  87. func NewEps(eps float64) SkipList {
  88. return NewSeedEps(time.Now().UTC().UnixNano(), eps)
  89. }
  90. // NewSeed returns a new empty, initialized Skiplist.
  91. // Given a seed, a deterministic height/list behaviour can be achieved.
  92. func NewSeed(seed int64) SkipList {
  93. return NewSeedEps(seed, eps)
  94. }
  95. // New returns a new empty, initialized Skiplist.
  96. func New() SkipList {
  97. return NewSeedEps(time.Now().UTC().UnixNano(), eps)
  98. }
  99. // IsEmpty checks, if the skiplist is empty.
  100. func (t *SkipList) IsEmpty() bool {
  101. return t.startLevels[0] == nil
  102. }
  103. func (t *SkipList) generateLevel(maxLevel int) int {
  104. level := maxLevel - 1
  105. // First we apply some mask which makes sure that we don't get a level
  106. // above our desired level. Then we find the first set bit.
  107. var x uint64 = rand.Uint64() & ((1 << uint(maxLevel-1)) - 1)
  108. zeroes := bits.TrailingZeros64(x)
  109. if zeroes <= maxLevel {
  110. level = zeroes
  111. }
  112. return level
  113. }
  114. func (t *SkipList) findEntryIndex(key int64, level int) int {
  115. // Find good entry point so we don't accidentally skip half the list.
  116. for i := t.maxLevel; i >= 0; i-- {
  117. if t.startLevels[i] != nil && t.startLevels[i].key <= key || i <= level {
  118. return i
  119. }
  120. }
  121. return 0
  122. }
  123. func (t *SkipList) findExtended(key int64, findGreaterOrEqual bool) (foundElem *SkipListElement, ok bool) {
  124. foundElem = nil
  125. ok = false
  126. if t.IsEmpty() {
  127. return
  128. }
  129. index := t.findEntryIndex(key, 0)
  130. var currentNode *SkipListElement
  131. currentNode = t.startLevels[index]
  132. nextNode := currentNode
  133. // In case, that our first element is already greater-or-equal!
  134. if findGreaterOrEqual && currentNode.key > key {
  135. foundElem = currentNode
  136. ok = true
  137. return
  138. }
  139. for {
  140. if currentNode.key == key {
  141. foundElem = currentNode
  142. ok = true
  143. return
  144. }
  145. nextNode = currentNode.next[index]
  146. // Which direction are we continuing next time?
  147. if nextNode != nil && nextNode.key <= key {
  148. // Go right
  149. currentNode = nextNode
  150. } else {
  151. if index > 0 {
  152. // Early exit
  153. if currentNode.next[0] != nil && currentNode.next[0].key == key {
  154. foundElem = currentNode.next[0]
  155. ok = true
  156. return
  157. }
  158. // Go down
  159. index--
  160. } else {
  161. // Element is not found and we reached the bottom.
  162. if findGreaterOrEqual {
  163. foundElem = nextNode
  164. ok = nextNode != nil
  165. }
  166. return
  167. }
  168. }
  169. }
  170. }
  171. // Find tries to find an element in the skiplist based on the key from the given ListElement.
  172. // elem can be used, if ok is true.
  173. // Find runs in approx. O(log(n))
  174. func (t *SkipList) Find(e ListElement) (elem *SkipListElement, ok bool) {
  175. if t == nil || e == nil {
  176. return
  177. }
  178. elem, ok = t.findExtended(e.ExtractKey(), false)
  179. return
  180. }
  181. // FindGreaterOrEqual finds the first element, that is greater or equal to the given ListElement e.
  182. // The comparison is done on the keys (So on ExtractKey()).
  183. // FindGreaterOrEqual runs in approx. O(log(n))
  184. func (t *SkipList) FindGreaterOrEqual(e ListElement) (elem *SkipListElement, ok bool) {
  185. if t == nil || e == nil {
  186. return
  187. }
  188. elem, ok = t.findExtended(e.ExtractKey(), true)
  189. return
  190. }
  191. // Delete removes an element equal to e from the skiplist, if there is one.
  192. // If there are multiple entries with the same value, Delete will remove one of them
  193. // (Which one will change based on the actual skiplist layout)
  194. // Delete runs in approx. O(log(n))
  195. func (t *SkipList) Delete(e ListElement) {
  196. if t == nil || t.IsEmpty() || e == nil {
  197. return
  198. }
  199. key := e.ExtractKey()
  200. index := t.findEntryIndex(key, 0)
  201. var currentNode *SkipListElement
  202. nextNode := currentNode
  203. for {
  204. if currentNode == nil {
  205. nextNode = t.startLevels[index]
  206. } else {
  207. nextNode = currentNode.next[index]
  208. }
  209. // Found and remove!
  210. if nextNode != nil && nextNode.key == key {
  211. if currentNode != nil {
  212. currentNode.next[index] = nextNode.next[index]
  213. }
  214. if index == 0 {
  215. if nextNode.next[index] != nil {
  216. nextNode.next[index].prev = currentNode
  217. }
  218. t.elementCount--
  219. t.releaseList = append(t.releaseList, nextNode)
  220. }
  221. // Link from start needs readjustments.
  222. if t.startLevels[index] == nextNode {
  223. t.startLevels[index] = nextNode.next[index]
  224. // This was our currently highest node!
  225. if t.startLevels[index] == nil {
  226. t.maxLevel = index - 1
  227. }
  228. }
  229. // Link from end needs readjustments.
  230. if nextNode.next[index] == nil {
  231. t.endLevels[index] = currentNode
  232. }
  233. nextNode.next[index] = nil
  234. }
  235. if nextNode != nil && nextNode.key < key {
  236. // Go right
  237. currentNode = nextNode
  238. } else {
  239. // Go down
  240. index--
  241. if index < 0 {
  242. break
  243. }
  244. }
  245. }
  246. }
  247. // Insert inserts the given ListElement into the skiplist.
  248. // Insert runs in approx. O(log(n))
  249. func (t *SkipList) Insert(e ListElement) {
  250. if t == nil || e == nil {
  251. return
  252. }
  253. level := t.generateLevel(t.maxNewLevel)
  254. // Only grow the height of the skiplist by one at a time!
  255. if level > t.maxLevel {
  256. level = t.maxLevel + 1
  257. t.maxLevel = level
  258. }
  259. // elem := &SkipListElement{
  260. // next: [maxLevel]*SkipListElement{},
  261. // level: level,
  262. // key: e.ExtractKey(),
  263. // value: e,
  264. // }
  265. var elem *SkipListElement
  266. ct := len(t.releaseList)
  267. if ct > 0 {
  268. elem = t.releaseList[ct-1]
  269. t.releaseList = t.releaseList[:ct-1]
  270. for i := 0; i < maxLevel; i++ {
  271. elem.next[i] = nil
  272. }
  273. } else {
  274. elem = new(SkipListElement)
  275. elem.next = [maxLevel]*SkipListElement{}
  276. }
  277. elem.level = level
  278. elem.key = e.ExtractKey()
  279. elem.value = e
  280. t.elementCount++
  281. newFirst := true
  282. newLast := true
  283. if !t.IsEmpty() {
  284. newFirst = elem.key < t.startLevels[0].key
  285. newLast = elem.key > t.endLevels[0].key
  286. }
  287. normallyInserted := false
  288. if !newFirst && !newLast {
  289. normallyInserted = true
  290. index := t.findEntryIndex(elem.key, level)
  291. var currentNode *SkipListElement
  292. nextNode := t.startLevels[index]
  293. for {
  294. if currentNode == nil {
  295. nextNode = t.startLevels[index]
  296. } else {
  297. nextNode = currentNode.next[index]
  298. }
  299. // Connect node to next
  300. if index <= level && (nextNode == nil || nextNode.key > elem.key) {
  301. elem.next[index] = nextNode
  302. if currentNode != nil {
  303. currentNode.next[index] = elem
  304. }
  305. if index == 0 {
  306. elem.prev = currentNode
  307. if nextNode != nil {
  308. nextNode.prev = elem
  309. }
  310. }
  311. }
  312. if nextNode != nil && nextNode.key <= elem.key {
  313. // Go right
  314. currentNode = nextNode
  315. } else {
  316. // Go down
  317. index--
  318. if index < 0 {
  319. break
  320. }
  321. }
  322. }
  323. }
  324. // Where we have a left-most position that needs to be referenced!
  325. for i := level; i >= 0; i-- {
  326. didSomething := false
  327. if newFirst || normallyInserted {
  328. if t.startLevels[i] == nil || t.startLevels[i].key > elem.key {
  329. if i == 0 && t.startLevels[i] != nil {
  330. t.startLevels[i].prev = elem
  331. }
  332. elem.next[i] = t.startLevels[i]
  333. t.startLevels[i] = elem
  334. }
  335. // link the endLevels to this element!
  336. if elem.next[i] == nil {
  337. t.endLevels[i] = elem
  338. }
  339. didSomething = true
  340. }
  341. if newLast {
  342. // Places the element after the very last element on this level!
  343. // This is very important, so we are not linking the very first element (newFirst AND newLast) to itself!
  344. if !newFirst {
  345. if t.endLevels[i] != nil {
  346. t.endLevels[i].next[i] = elem
  347. }
  348. if i == 0 {
  349. elem.prev = t.endLevels[i]
  350. }
  351. t.endLevels[i] = elem
  352. }
  353. // Link the startLevels to this element!
  354. if t.startLevels[i] == nil || t.startLevels[i].key > elem.key {
  355. t.startLevels[i] = elem
  356. }
  357. didSomething = true
  358. }
  359. if !didSomething {
  360. break
  361. }
  362. }
  363. }
  364. func (e *SkipListElement) GetKey() int64 {
  365. return e.key
  366. }
  367. // GetValue extracts the ListElement value from a skiplist node.
  368. func (e *SkipListElement) GetValue() ListElement {
  369. return e.value
  370. }
  371. func (e *SkipListElement) ResetValue() {
  372. e.value = nil
  373. }
  374. // GetSmallestNode returns the very first/smallest node in the skiplist.
  375. // GetSmallestNode runs in O(1)
  376. func (t *SkipList) GetSmallestNode() *SkipListElement {
  377. return t.startLevels[0]
  378. }
  379. // GetLargestNode returns the very last/largest node in the skiplist.
  380. // GetLargestNode runs in O(1)
  381. func (t *SkipList) GetLargestNode() *SkipListElement {
  382. return t.endLevels[0]
  383. }
  384. // Next returns the next element based on the given node.
  385. // Next will loop around to the first node, if you call it on the last!
  386. func (t *SkipList) Next(e *SkipListElement) *SkipListElement {
  387. if e.next[0] == nil {
  388. return t.startLevels[0]
  389. }
  390. return e.next[0]
  391. }
  392. // Prev returns the previous element based on the given node.
  393. // Prev will loop around to the last node, if you call it on the first!
  394. func (t *SkipList) Prev(e *SkipListElement) *SkipListElement {
  395. if e.prev == nil {
  396. return t.endLevels[0]
  397. }
  398. return e.prev
  399. }
  400. // GetNodeCount returns the number of nodes currently in the skiplist.
  401. func (t *SkipList) GetNodeCount() int {
  402. return t.elementCount
  403. }
  404. // ChangeValue can be used to change the actual value of a node in the skiplist
  405. // without the need of Deleting and reinserting the node again.
  406. // Be advised, that ChangeValue only works, if the actual key from ExtractKey() will stay the same!
  407. // ok is an indicator, wether the value is actually changed.
  408. func (t *SkipList) ChangeValue(e *SkipListElement, newValue ListElement) (ok bool) {
  409. // The key needs to stay correct, so this is very important!
  410. if newValue.ExtractKey() == e.key {
  411. e.value = newValue
  412. ok = true
  413. } else {
  414. ok = false
  415. }
  416. return
  417. }
  418. // String returns a string format of the skiplist. Useful to get a graphical overview and/or debugging.
  419. func (t *SkipList) String() string {
  420. s := ""
  421. s += " --> "
  422. for i, l := range t.startLevels {
  423. if l == nil {
  424. break
  425. }
  426. if i > 0 {
  427. s += " -> "
  428. }
  429. next := "---"
  430. if l != nil {
  431. next = l.value.String()
  432. }
  433. s += fmt.Sprintf("[%v]", next)
  434. if i == 0 {
  435. s += " "
  436. }
  437. }
  438. s += "\n"
  439. node := t.startLevels[0]
  440. for node != nil {
  441. s += fmt.Sprintf("%v: ", node.value)
  442. for i := 0; i <= node.level; i++ {
  443. l := node.next[i]
  444. next := "---"
  445. if l != nil {
  446. next = l.value.String()
  447. }
  448. if i == 0 {
  449. prev := "---"
  450. if node.prev != nil {
  451. prev = node.prev.value.String()
  452. }
  453. s += fmt.Sprintf("[%v|%v]", prev, next)
  454. } else {
  455. s += fmt.Sprintf("[%v]", next)
  456. }
  457. if i < node.level {
  458. s += " -> "
  459. }
  460. }
  461. s += "\n"
  462. node = node.next[0]
  463. }
  464. s += " --> "
  465. for i, l := range t.endLevels {
  466. if l == nil {
  467. break
  468. }
  469. if i > 0 {
  470. s += " -> "
  471. }
  472. next := "---"
  473. if l != nil {
  474. next = l.value.String()
  475. }
  476. s += fmt.Sprintf("[%v]", next)
  477. if i == 0 {
  478. s += " "
  479. }
  480. }
  481. s += "\n"
  482. return s
  483. }