193
vendor/github.com/wk8/go-ordered-map/orderedmap.go
generated
vendored
Normal file
193
vendor/github.com/wk8/go-ordered-map/orderedmap.go
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
// Package orderedmap implements an ordered map, i.e. a map that also keeps track of
|
||||
// the order in which keys were inserted.
|
||||
//
|
||||
// All operations are constant-time.
|
||||
//
|
||||
// Github repo: https://github.com/wk8/go-ordered-map
|
||||
//
|
||||
package orderedmap
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Pair struct {
|
||||
Key interface{}
|
||||
Value interface{}
|
||||
|
||||
element *list.Element
|
||||
}
|
||||
|
||||
type OrderedMap struct {
|
||||
pairs map[interface{}]*Pair
|
||||
list *list.List
|
||||
}
|
||||
|
||||
// New creates a new OrderedMap.
|
||||
func New() *OrderedMap {
|
||||
return &OrderedMap{
|
||||
pairs: make(map[interface{}]*Pair),
|
||||
list: list.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get looks for the given key, and returns the value associated with it,
|
||||
// or nil if not found. The boolean it returns says whether the key is present in the map.
|
||||
func (om *OrderedMap) Get(key interface{}) (interface{}, bool) {
|
||||
if pair, present := om.pairs[key]; present {
|
||||
return pair.Value, present
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Load is an alias for Get, mostly to present an API similar to `sync.Map`'s.
|
||||
func (om *OrderedMap) Load(key interface{}) (interface{}, bool) {
|
||||
return om.Get(key)
|
||||
}
|
||||
|
||||
// GetPair looks for the given key, and returns the pair associated with it,
|
||||
// or nil if not found. The Pair struct can then be used to iterate over the ordered map
|
||||
// from that point, either forward or backward.
|
||||
func (om *OrderedMap) GetPair(key interface{}) *Pair {
|
||||
return om.pairs[key]
|
||||
}
|
||||
|
||||
// Set sets the key-value pair, and returns what `Get` would have returned
|
||||
// on that key prior to the call to `Set`.
|
||||
func (om *OrderedMap) Set(key interface{}, value interface{}) (interface{}, bool) {
|
||||
if pair, present := om.pairs[key]; present {
|
||||
oldValue := pair.Value
|
||||
pair.Value = value
|
||||
return oldValue, true
|
||||
}
|
||||
|
||||
pair := &Pair{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}
|
||||
pair.element = om.list.PushBack(pair)
|
||||
om.pairs[key] = pair
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Store is an alias for Set, mostly to present an API similar to `sync.Map`'s.
|
||||
func (om *OrderedMap) Store(key interface{}, value interface{}) (interface{}, bool) {
|
||||
return om.Set(key, value)
|
||||
}
|
||||
|
||||
// Delete removes the key-value pair, and returns what `Get` would have returned
|
||||
// on that key prior to the call to `Delete`.
|
||||
func (om *OrderedMap) Delete(key interface{}) (interface{}, bool) {
|
||||
if pair, present := om.pairs[key]; present {
|
||||
om.list.Remove(pair.element)
|
||||
delete(om.pairs, key)
|
||||
return pair.Value, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Len returns the length of the ordered map.
|
||||
func (om *OrderedMap) Len() int {
|
||||
return len(om.pairs)
|
||||
}
|
||||
|
||||
// Oldest returns a pointer to the oldest pair. It's meant to be used to iterate on the ordered map's
|
||||
// pairs from the oldest to the newest, e.g.:
|
||||
// for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() { fmt.Printf("%v => %v\n", pair.Key, pair.Value) }
|
||||
func (om *OrderedMap) Oldest() *Pair {
|
||||
return listElementToPair(om.list.Front())
|
||||
}
|
||||
|
||||
// Newest returns a pointer to the newest pair. It's meant to be used to iterate on the ordered map's
|
||||
// pairs from the newest to the oldest, e.g.:
|
||||
// for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() { fmt.Printf("%v => %v\n", pair.Key, pair.Value) }
|
||||
func (om *OrderedMap) Newest() *Pair {
|
||||
return listElementToPair(om.list.Back())
|
||||
}
|
||||
|
||||
// Next returns a pointer to the next pair.
|
||||
func (p *Pair) Next() *Pair {
|
||||
return listElementToPair(p.element.Next())
|
||||
}
|
||||
|
||||
// Previous returns a pointer to the previous pair.
|
||||
func (p *Pair) Prev() *Pair {
|
||||
return listElementToPair(p.element.Prev())
|
||||
}
|
||||
|
||||
func listElementToPair(element *list.Element) *Pair {
|
||||
if element == nil {
|
||||
return nil
|
||||
}
|
||||
return element.Value.(*Pair)
|
||||
}
|
||||
|
||||
// KeyNotFoundError may be returned by functions in this package when they're called with keys that are not present
|
||||
// in the map.
|
||||
type KeyNotFoundError struct {
|
||||
MissingKey interface{}
|
||||
}
|
||||
|
||||
var _ error = &KeyNotFoundError{}
|
||||
|
||||
func (e *KeyNotFoundError) Error() string {
|
||||
return fmt.Sprintf("missing key: %v", e.MissingKey)
|
||||
}
|
||||
|
||||
// MoveAfter moves the value associated with key to its new position after the one associated with markKey.
|
||||
// Returns an error iff key or markKey are not present in the map.
|
||||
func (om *OrderedMap) MoveAfter(key, markKey interface{}) error {
|
||||
elements, err := om.getElements(key, markKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
om.list.MoveAfter(elements[0], elements[1])
|
||||
return nil
|
||||
}
|
||||
|
||||
// MoveBefore moves the value associated with key to its new position before the one associated with markKey.
|
||||
// Returns an error iff key or markKey are not present in the map.
|
||||
func (om *OrderedMap) MoveBefore(key, markKey interface{}) error {
|
||||
elements, err := om.getElements(key, markKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
om.list.MoveBefore(elements[0], elements[1])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (om *OrderedMap) getElements(keys ...interface{}) ([]*list.Element, error) {
|
||||
elements := make([]*list.Element, len(keys))
|
||||
for i, k := range keys {
|
||||
pair, present := om.pairs[k]
|
||||
if !present {
|
||||
return nil, &KeyNotFoundError{k}
|
||||
}
|
||||
elements[i] = pair.element
|
||||
}
|
||||
return elements, nil
|
||||
}
|
||||
|
||||
// MoveToBack moves the value associated with key to the back of the ordered map.
|
||||
// Returns an error iff key is not present in the map.
|
||||
func (om *OrderedMap) MoveToBack(key interface{}) error {
|
||||
pair, present := om.pairs[key]
|
||||
if !present {
|
||||
return &KeyNotFoundError{key}
|
||||
}
|
||||
om.list.MoveToBack(pair.element)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MoveToFront moves the value associated with key to the front of the ordered map.
|
||||
// Returns an error iff key is not present in the map.
|
||||
func (om *OrderedMap) MoveToFront(key interface{}) error {
|
||||
pair, present := om.pairs[key]
|
||||
if !present {
|
||||
return &KeyNotFoundError{key}
|
||||
}
|
||||
om.list.MoveToFront(pair.element)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user