-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic functions include Set, Get, Delete, Len and Keys.
- Loading branch information
0 parents
commit 02f2ded
Showing
6 changed files
with
498 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# 🔃 github.com/elliotchance/orderedmap [![GoDoc](https://godoc.org/github.com/elliotchance/orderedmap?status.svg)](https://godoc.org/github.com/elliotchance/orderedmap) | ||
|
||
The `orderedmap` package provides a high performance ordered map in Go: | ||
|
||
```go | ||
m := orderedmap.NewOrderedMap() | ||
|
||
m.Set("foo", "bar") | ||
m.Set("qux", 1.23) | ||
m.Set(123, true) | ||
|
||
m.Delete("qux") | ||
|
||
for _, key := range m.Keys() { | ||
value, _:= m.Get(key) | ||
fmt.Println(key, value) | ||
} | ||
``` | ||
|
||
Internally an `*OrderedMap` uses a combination of a map and linked list to | ||
maintain amortized O(1) for `Set`, `Get`, `Delete` and `Len`. | ||
|
||
See the full documentation at | ||
[https://godoc.org/github.com/elliotchance/orderedmap](https://godoc.org/github.com/elliotchance/orderedmap). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/elliotchance/orderedmap | ||
|
||
go 1.12 | ||
|
||
require github.com/stretchr/testify v1.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package orderedmap | ||
|
||
import "container/list" | ||
|
||
type orderedMapElement struct { | ||
key, value interface{} | ||
} | ||
|
||
type OrderedMap struct { | ||
kv map[interface{}]*list.Element | ||
ll *list.List | ||
} | ||
|
||
func NewOrderedMap() *OrderedMap { | ||
return &OrderedMap{ | ||
kv: make(map[interface{}]*list.Element), | ||
ll: list.New(), | ||
} | ||
} | ||
|
||
// Get returns the value for a key. If the key does not exist, the second return | ||
// parameter will be false and the value will be nil. | ||
func (m *OrderedMap) Get(key interface{}) (interface{}, bool) { | ||
value, ok := m.kv[key] | ||
if ok { | ||
return value.Value.(*orderedMapElement).value, true | ||
} | ||
|
||
return nil, false | ||
} | ||
|
||
// Set will set (or replace) a value for a key. If the key was new, then true | ||
// will be returned. The returned value will be false if the value was replaced | ||
// (even if the value was the same). | ||
func (m *OrderedMap) Set(key, value interface{}) bool { | ||
_, didExist := m.kv[key] | ||
|
||
if !didExist { | ||
element := m.ll.PushBack(&orderedMapElement{key, value}) | ||
m.kv[key] = element | ||
} else { | ||
m.kv[key].Value.(*orderedMapElement).value = value | ||
} | ||
|
||
return !didExist | ||
} | ||
|
||
// Len returns the number of elements in the map. | ||
func (m *OrderedMap) Len() int { | ||
return len(m.kv) | ||
} | ||
|
||
// Keys returns all of the keys in the order they were inserted. If a key was | ||
// replaced it will retain the same position. To ensure most recently set keys | ||
// are always at the end you must always Delete before Set. | ||
func (m *OrderedMap) Keys() (keys []interface{}) { | ||
keys = make([]interface{}, m.Len()) | ||
|
||
element := m.ll.Front() | ||
for i := 0; element != nil; i++ { | ||
keys[i] = element.Value.(*orderedMapElement).key | ||
element = element.Next() | ||
} | ||
|
||
return keys | ||
} | ||
|
||
// Delete will remove a key from the map. It will return true if the key was | ||
// removed (the key did exist). | ||
func (m *OrderedMap) Delete(key interface{}) (didDelete bool) { | ||
element, ok := m.kv[key] | ||
if ok { | ||
m.ll.Remove(element) | ||
delete(m.kv, key) | ||
} | ||
|
||
return ok | ||
} |
Oops, something went wrong.