dispatch/vendor/github.com/ryszard/goskiplist/skiplist/skiplist.go

636 lines
16 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2012 Google Inc. All rights reserved.
// Author: Ric Szopa (Ryszard) <ryszard.szopa@gmail.com>
// Package skiplist implements skip list based maps and sets.
//
// Skip lists are a data structure that can be used in place of
// balanced trees. Skip lists use probabilistic balancing rather than
// strictly enforced balancing and as a result the algorithms for
// insertion and deletion in skip lists are much simpler and
// significantly faster than equivalent algorithms for balanced trees.
//
// Skip lists were first described in Pugh, William (June 1990). "Skip
// lists: a probabilistic alternative to balanced
// trees". Communications of the ACM 33 (6): 668676
package skiplist
import (
"math/rand"
)
// TODO(ryszard):
// - A separately seeded source of randomness
// p is the fraction of nodes with level i pointers that also have
// level i+1 pointers. p equal to 1/4 is a good value from the point
// of view of speed and space requirements. If variability of running
// times is a concern, 1/2 is a better value for p.
const p = 0.25
const DefaultMaxLevel = 32
// A node is a container for key-value pairs that are stored in a skip
// list.
type node struct {
forward []*node
backward *node
key, value interface{}
}
// next returns the next node in the skip list containing n.
func (n *node) next() *node {
if len(n.forward) == 0 {
return nil
}
return n.forward[0]
}
// previous returns the previous node in the skip list containing n.
func (n *node) previous() *node {
return n.backward
}
// hasNext returns true if n has a next node.
func (n *node) hasNext() bool {
return n.next() != nil
}
// hasPrevious returns true if n has a previous node.
func (n *node) hasPrevious() bool {
return n.previous() != nil
}
// A SkipList is a map-like data structure that maintains an ordered
// collection of key-value pairs. Insertion, lookup, and deletion are
// all O(log n) operations. A SkipList can efficiently store up to
// 2^MaxLevel items.
//
// To iterate over a skip list (where s is a
// *SkipList):
//
// for i := s.Iterator(); i.Next(); {
// // do something with i.Key() and i.Value()
// }
type SkipList struct {
lessThan func(l, r interface{}) bool
header *node
footer *node
length int
// MaxLevel determines how many items the SkipList can store
// efficiently (2^MaxLevel).
//
// It is safe to increase MaxLevel to accomodate more
// elements. If you decrease MaxLevel and the skip list
// already contains nodes on higer levels, the effective
// MaxLevel will be the greater of the new MaxLevel and the
// level of the highest node.
//
// A SkipList with MaxLevel equal to 0 is equivalent to a
// standard linked list and will not have any of the nice
// properties of skip lists (probably not what you want).
MaxLevel int
}
// Len returns the length of s.
func (s *SkipList) Len() int {
return s.length
}
// Iterator is an interface that you can use to iterate through the
// skip list (in its entirety or fragments). For an use example, see
// the documentation of SkipList.
//
// Key and Value return the key and the value of the current node.
type Iterator interface {
// Next returns true if the iterator contains subsequent elements
// and advances its state to the next element if that is possible.
Next() (ok bool)
// Previous returns true if the iterator contains previous elements
// and rewinds its state to the previous element if that is possible.
Previous() (ok bool)
// Key returns the current key.
Key() interface{}
// Value returns the current value.
Value() interface{}
// Seek reduces iterative seek costs for searching forward into the Skip List
// by remarking the range of keys over which it has scanned before. If the
// requested key occurs prior to the point, the Skip List will start searching
// as a safeguard. It returns true if the key is within the known range of
// the list.
Seek(key interface{}) (ok bool)
// Close this iterator to reap resources associated with it. While not
// strictly required, it will provide extra hints for the garbage collector.
Close()
}
type iter struct {
current *node
key interface{}
list *SkipList
value interface{}
}
func (i iter) Key() interface{} {
return i.key
}
func (i iter) Value() interface{} {
return i.value
}
func (i *iter) Next() bool {
if !i.current.hasNext() {
return false
}
i.current = i.current.next()
i.key = i.current.key
i.value = i.current.value
return true
}
func (i *iter) Previous() bool {
if !i.current.hasPrevious() {
return false
}
i.current = i.current.previous()
i.key = i.current.key
i.value = i.current.value
return true
}
func (i *iter) Seek(key interface{}) (ok bool) {
current := i.current
list := i.list
// If the existing iterator outside of the known key range, we should set the
// position back to the beginning of the list.
if current == nil {
current = list.header
}
// If the target key occurs before the current key, we cannot take advantage
// of the heretofore spent traversal cost to find it; resetting back to the
// beginning is the safest choice.
if current.key != nil && list.lessThan(key, current.key) {
current = list.header
}
// We should back up to the so that we can seek to our present value if that
// is requested for whatever reason.
if current.backward == nil {
current = list.header
} else {
current = current.backward
}
current = list.getPath(current, nil, key)
if current == nil {
return
}
i.current = current
i.key = current.key
i.value = current.value
return true
}
func (i *iter) Close() {
i.key = nil
i.value = nil
i.current = nil
i.list = nil
}
type rangeIterator struct {
iter
upperLimit interface{}
lowerLimit interface{}
}
func (i *rangeIterator) Next() bool {
if !i.current.hasNext() {
return false
}
next := i.current.next()
if !i.list.lessThan(next.key, i.upperLimit) {
return false
}
i.current = i.current.next()
i.key = i.current.key
i.value = i.current.value
return true
}
func (i *rangeIterator) Previous() bool {
if !i.current.hasPrevious() {
return false
}
previous := i.current.previous()
if i.list.lessThan(previous.key, i.lowerLimit) {
return false
}
i.current = i.current.previous()
i.key = i.current.key
i.value = i.current.value
return true
}
func (i *rangeIterator) Seek(key interface{}) (ok bool) {
if i.list.lessThan(key, i.lowerLimit) {
return
} else if !i.list.lessThan(key, i.upperLimit) {
return
}
return i.iter.Seek(key)
}
func (i *rangeIterator) Close() {
i.iter.Close()
i.upperLimit = nil
i.lowerLimit = nil
}
// Iterator returns an Iterator that will go through all elements s.
func (s *SkipList) Iterator() Iterator {
return &iter{
current: s.header,
list: s,
}
}
// Seek returns a bidirectional iterator starting with the first element whose
// key is greater or equal to key; otherwise, a nil iterator is returned.
func (s *SkipList) Seek(key interface{}) Iterator {
current := s.getPath(s.header, nil, key)
if current == nil {
return nil
}
return &iter{
current: current,
key: current.key,
list: s,
value: current.value,
}
}
// SeekToFirst returns a bidirectional iterator starting from the first element
// in the list if the list is populated; otherwise, a nil iterator is returned.
func (s *SkipList) SeekToFirst() Iterator {
if s.length == 0 {
return nil
}
current := s.header.next()
return &iter{
current: current,
key: current.key,
list: s,
value: current.value,
}
}
// SeekToLast returns a bidirectional iterator starting from the last element
// in the list if the list is populated; otherwise, a nil iterator is returned.
func (s *SkipList) SeekToLast() Iterator {
current := s.footer
if current == nil {
return nil
}
return &iter{
current: current,
key: current.key,
list: s,
value: current.value,
}
}
// Range returns an iterator that will go through all the
// elements of the skip list that are greater or equal than from, but
// less than to.
func (s *SkipList) Range(from, to interface{}) Iterator {
start := s.getPath(s.header, nil, from)
return &rangeIterator{
iter: iter{
current: &node{
forward: []*node{start},
backward: start,
},
list: s,
},
upperLimit: to,
lowerLimit: from,
}
}
func (s *SkipList) level() int {
return len(s.header.forward) - 1
}
func maxInt(x, y int) int {
if x > y {
return x
}
return y
}
func (s *SkipList) effectiveMaxLevel() int {
return maxInt(s.level(), s.MaxLevel)
}
// Returns a new random level.
func (s SkipList) randomLevel() (n int) {
for n = 0; n < s.effectiveMaxLevel() && rand.Float64() < p; n++ {
}
return
}
// Get returns the value associated with key from s (nil if the key is
// not present in s). The second return value is true when the key is
// present.
func (s *SkipList) Get(key interface{}) (value interface{}, ok bool) {
candidate := s.getPath(s.header, nil, key)
if candidate == nil || candidate.key != key {
return nil, false
}
return candidate.value, true
}
// GetGreaterOrEqual finds the node whose key is greater than or equal
// to min. It returns its value, its actual key, and whether such a
// node is present in the skip list.
func (s *SkipList) GetGreaterOrEqual(min interface{}) (actualKey, value interface{}, ok bool) {
candidate := s.getPath(s.header, nil, min)
if candidate != nil {
return candidate.key, candidate.value, true
}
return nil, nil, false
}
// getPath populates update with nodes that constitute the path to the
// node that may contain key. The candidate node will be returned. If
// update is nil, it will be left alone (the candidate node will still
// be returned). If update is not nil, but it doesn't have enough
// slots for all the nodes in the path, getPath will panic.
func (s *SkipList) getPath(current *node, update []*node, key interface{}) *node {
depth := len(current.forward) - 1
for i := depth; i >= 0; i-- {
for current.forward[i] != nil && s.lessThan(current.forward[i].key, key) {
current = current.forward[i]
}
if update != nil {
update[i] = current
}
}
return current.next()
}
// Sets set the value associated with key in s.
func (s *SkipList) Set(key, value interface{}) {
if key == nil {
panic("goskiplist: nil keys are not supported")
}
// s.level starts from 0, so we need to allocate one.
update := make([]*node, s.level()+1, s.effectiveMaxLevel()+1)
candidate := s.getPath(s.header, update, key)
if candidate != nil && candidate.key == key {
candidate.value = value
return
}
newLevel := s.randomLevel()
if currentLevel := s.level(); newLevel > currentLevel {
// there are no pointers for the higher levels in
// update. Header should be there. Also add higher
// level links to the header.
for i := currentLevel + 1; i <= newLevel; i++ {
update = append(update, s.header)
s.header.forward = append(s.header.forward, nil)
}
}
newNode := &node{
forward: make([]*node, newLevel+1, s.effectiveMaxLevel()+1),
key: key,
value: value,
}
if previous := update[0]; previous.key != nil {
newNode.backward = previous
}
for i := 0; i <= newLevel; i++ {
newNode.forward[i] = update[i].forward[i]
update[i].forward[i] = newNode
}
s.length++
if newNode.forward[0] != nil {
if newNode.forward[0].backward != newNode {
newNode.forward[0].backward = newNode
}
}
if s.footer == nil || s.lessThan(s.footer.key, key) {
s.footer = newNode
}
}
// Delete removes the node with the given key.
//
// It returns the old value and whether the node was present.
func (s *SkipList) Delete(key interface{}) (value interface{}, ok bool) {
if key == nil {
panic("goskiplist: nil keys are not supported")
}
update := make([]*node, s.level()+1, s.effectiveMaxLevel())
candidate := s.getPath(s.header, update, key)
if candidate == nil || candidate.key != key {
return nil, false
}
previous := candidate.backward
if s.footer == candidate {
s.footer = previous
}
next := candidate.next()
if next != nil {
next.backward = previous
}
for i := 0; i <= s.level() && update[i].forward[i] == candidate; i++ {
update[i].forward[i] = candidate.forward[i]
}
for s.level() > 0 && s.header.forward[s.level()] == nil {
s.header.forward = s.header.forward[:s.level()]
}
s.length--
return candidate.value, true
}
// NewCustomMap returns a new SkipList that will use lessThan as the
// comparison function. lessThan should define a linear order on keys
// you intend to use with the SkipList.
func NewCustomMap(lessThan func(l, r interface{}) bool) *SkipList {
return &SkipList{
lessThan: lessThan,
header: &node{
forward: []*node{nil},
},
MaxLevel: DefaultMaxLevel,
}
}
// Ordered is an interface which can be linearly ordered by the
// LessThan method, whereby this instance is deemed to be less than
// other. Additionally, Ordered instances should behave properly when
// compared using == and !=.
type Ordered interface {
LessThan(other Ordered) bool
}
// New returns a new SkipList.
//
// Its keys must implement the Ordered interface.
func New() *SkipList {
comparator := func(left, right interface{}) bool {
return left.(Ordered).LessThan(right.(Ordered))
}
return NewCustomMap(comparator)
}
// NewIntKey returns a SkipList that accepts int keys.
func NewIntMap() *SkipList {
return NewCustomMap(func(l, r interface{}) bool {
return l.(int) < r.(int)
})
}
// NewStringMap returns a SkipList that accepts string keys.
func NewStringMap() *SkipList {
return NewCustomMap(func(l, r interface{}) bool {
return l.(string) < r.(string)
})
}
// Set is an ordered set data structure.
//
// Its elements must implement the Ordered interface. It uses a
// SkipList for storage, and it gives you similar performance
// guarantees.
//
// To iterate over a set (where s is a *Set):
//
// for i := s.Iterator(); i.Next(); {
// // do something with i.Key().
// // i.Value() will be nil.
// }
type Set struct {
skiplist SkipList
}
// NewSet returns a new Set.
func NewSet() *Set {
comparator := func(left, right interface{}) bool {
return left.(Ordered).LessThan(right.(Ordered))
}
return NewCustomSet(comparator)
}
// NewCustomSet returns a new Set that will use lessThan as the
// comparison function. lessThan should define a linear order on
// elements you intend to use with the Set.
func NewCustomSet(lessThan func(l, r interface{}) bool) *Set {
return &Set{skiplist: SkipList{
lessThan: lessThan,
header: &node{
forward: []*node{nil},
},
MaxLevel: DefaultMaxLevel,
}}
}
// NewIntSet returns a new Set that accepts int elements.
func NewIntSet() *Set {
return NewCustomSet(func(l, r interface{}) bool {
return l.(int) < r.(int)
})
}
// NewStringSet returns a new Set that accepts string elements.
func NewStringSet() *Set {
return NewCustomSet(func(l, r interface{}) bool {
return l.(string) < r.(string)
})
}
// Add adds key to s.
func (s *Set) Add(key interface{}) {
s.skiplist.Set(key, nil)
}
// Remove tries to remove key from the set. It returns true if key was
// present.
func (s *Set) Remove(key interface{}) (ok bool) {
_, ok = s.skiplist.Delete(key)
return ok
}
// Len returns the length of the set.
func (s *Set) Len() int {
return s.skiplist.Len()
}
// Contains returns true if key is present in s.
func (s *Set) Contains(key interface{}) bool {
_, ok := s.skiplist.Get(key)
return ok
}
func (s *Set) Iterator() Iterator {
return s.skiplist.Iterator()
}
// Range returns an iterator that will go through all the elements of
// the set that are greater or equal than from, but less than to.
func (s *Set) Range(from, to interface{}) Iterator {
return s.skiplist.Range(from, to)
}
// SetMaxLevel sets MaxLevel in the underlying skip list.
func (s *Set) SetMaxLevel(newMaxLevel int) {
s.skiplist.MaxLevel = newMaxLevel
}
// GetMaxLevel returns MaxLevel fo the underlying skip list.
func (s *Set) GetMaxLevel() int {
return s.skiplist.MaxLevel
}