pax_global_header00006660000000000000000000000064147355341640014526gustar00rootroot0000000000000052 comment=9d80274286972e4b495b38de2923a4d5f9758c8d orderedmap-1.8.0/000077500000000000000000000000001473553416400136565ustar00rootroot00000000000000orderedmap-1.8.0/.editorconfig000066400000000000000000000002561473553416400163360ustar00rootroot00000000000000root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.go] indent_style = tab indent_size = 4 max_line_length = 80 orderedmap-1.8.0/.github/000077500000000000000000000000001473553416400152165ustar00rootroot00000000000000orderedmap-1.8.0/.github/workflows/000077500000000000000000000000001473553416400172535ustar00rootroot00000000000000orderedmap-1.8.0/.github/workflows/ci.yaml000066400000000000000000000011011473553416400205230ustar00rootroot00000000000000name: CI on: push: pull_request: jobs: unit-tests-v2: strategy: matrix: go: - '=1.18' - '^1.23' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: ${{ matrix.go }} - run: go test -v ./... - run: cd v2 && go test -v ./... unit-tests-v3: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: '^1.23' - run: cd v3 && go test -v ./... orderedmap-1.8.0/.gitignore000066400000000000000000000000071473553416400156430ustar00rootroot00000000000000/.idea orderedmap-1.8.0/LICENSE000066400000000000000000000020561473553416400146660ustar00rootroot00000000000000MIT License Copyright (c) 2020 Elliot Chance Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. orderedmap-1.8.0/README.md000066400000000000000000000043271473553416400151430ustar00rootroot00000000000000# 🔃 github.com/elliotchance/orderedmap/v3 [![GoDoc](https://godoc.org/github.com/elliotchance/orderedmap/v3?status.svg)](https://godoc.org/github.com/elliotchance/orderedmap/v3) ## Basic Usage An `*OrderedMap` is a high performance ordered map that maintains amortized O(1) for `Set`, `Get`, `Delete` and `Len`: ```go import "github.com/elliotchance/orderedmap/v3" func main() { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", "bar") m.Set("qux", 1.23) m.Set("123", true) m.Delete("qux") } ``` > [!NOTE] > > - _v3 requires Go v1.23_ - If you need to support Go 1.18-1.22, you can use v2. > - _v2 requires Go v1.18 for generics_ - If you need to support Go 1.17 or below, you can use v1. Internally an `*OrderedMap` uses the composite type [map](https://go.dev/blog/maps) combined with a trimmed down linked list to maintain the order. ## Iterating The following methods all return [iterators](https://go.dev/doc/go1.23#iterators) that can be used to loop over elements in an ordered map: - `AllFromFront()` - `AllFromBack()` - `Keys()` - `Values()` ```go // Iterate through all elements from oldest to newest: for key, value := range m.AllFromFront() { fmt.Println(key, value) } ``` Iterators are safe to use bidirectionally, and will return `nil` once it goes beyond the first or last item. If the map is changing while the iteration is in-flight it may produce unexpected behavior. If you want to get a slice of the map keys or values, you can use the standard `slices.Collect` method with the iterator returned from `Keys()` or `Values()`: ```go fmt.Println(slices.Collect(m.Keys()) // [A B C] ``` Likewise, calling `maps.Collect` on the iterator returned from `AllFromFront()` will create a regular unordered map from the ordered one: ```go fmt.Println(maps.Collect(m.AllFromFront()) // [A:1 B:2 C:3] ``` If you don't want to use iterators, you can also manually loop over the elements using `Front()` or `Back()` with `Next()`: ```go // Iterate through all elements from oldest to newest: for el := m.Front(); el != nil; el = el.Next() { fmt.Println(el.Key, el.Value) } // You can also use Back and Prev to iterate in reverse: for el := m.Back(); el != nil; el = el.Prev() { fmt.Println(el.Key, el.Value) } ``` orderedmap-1.8.0/go.mod000066400000000000000000000001371473553416400147650ustar00rootroot00000000000000module github.com/elliotchance/orderedmap go 1.12 require github.com/stretchr/testify v1.7.0 orderedmap-1.8.0/go.sum000066400000000000000000000025041473553416400150120ustar00rootroot00000000000000github.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= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= orderedmap-1.8.0/list.go000066400000000000000000000047051473553416400151660ustar00rootroot00000000000000package orderedmap // Element is an element of a null terminated (non circular) intrusive doubly linked list that contains the key of the correspondent element in the ordered map too. type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). next, prev *Element // The key that corresponds to this element in the ordered map. Key interface{} // The value stored with this element. Value interface{} } // Next returns the next list element or nil. func (e *Element) Next() *Element { return e.next } // Prev returns the previous list element or nil. func (e *Element) Prev() *Element { return e.prev } // list represents a null terminated (non circular) intrusive doubly linked list. // The list is immediately usable after instantiation without the need of a dedicated initialization. type list struct { root Element // list head and tail } func (l *list) IsEmpty() bool { return l.root.next == nil } // Front returns the first element of list l or nil if the list is empty. func (l *list) Front() *Element { return l.root.next } // Back returns the last element of list l or nil if the list is empty. func (l *list) Back() *Element { return l.root.prev } // Remove removes e from its list func (l *list) Remove(e *Element) { if e.prev == nil { l.root.next = e.next } else { e.prev.next = e.next } if e.next == nil { l.root.prev = e.prev } else { e.next.prev = e.prev } e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks } // PushFront inserts a new element e with value v at the front of list l and returns e. func (l *list) PushFront(key interface{}, value interface{}) *Element { e := &Element{Key: key, Value: value} if l.root.next == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.next = l.root.next l.root.next.prev = e l.root.next = e return e } // PushBack inserts a new element e with value v at the back of list l and returns e. func (l *list) PushBack(key interface{}, value interface{}) *Element { e := &Element{Key: key, Value: value} if l.root.prev == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.prev = l.root.prev l.root.prev.next = e l.root.prev = e return e } orderedmap-1.8.0/orderedmap.go000066400000000000000000000062621473553416400163350ustar00rootroot00000000000000package orderedmap type OrderedMap struct { kv map[interface{}]*Element ll list } func NewOrderedMap() *OrderedMap { return &OrderedMap{ kv: make(map[interface{}]*Element), } } // NewOrderedMapWithCapacity creates a map with enough pre-allocated space to // hold the specified number of elements. func NewOrderedMapWithCapacity(capacity int) *OrderedMap { return &OrderedMap{ kv: make(map[interface{}]*Element, capacity), } } // 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) { element, ok := m.kv[key] if ok { return element.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 { _, alreadyExist := m.kv[key] if alreadyExist { m.kv[key].Value = value return false } element := m.ll.PushBack(key, value) m.kv[key] = element return true } // GetOrDefault returns the value for a key. If the key does not exist, returns // the default value instead. func (m *OrderedMap) GetOrDefault(key, defaultValue interface{}) interface{} { if element, ok := m.kv[key]; ok { return element.Value } return defaultValue } // GetElement returns the element for a key. If the key does not exist, the // pointer will be nil. func (m *OrderedMap) GetElement(key interface{}) *Element { element, ok := m.kv[key] if ok { return element } return nil } // 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{}, 0, m.Len()) for el := m.Front(); el != nil; el = el.Next() { keys = append(keys, el.Key) } 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 } // Front will return the element that is the first (oldest Set element). If // there are no elements this will return nil. func (m *OrderedMap) Front() *Element { return m.ll.Front() } // Back will return the element that is the last (most recent Set element). If // there are no elements this will return nil. func (m *OrderedMap) Back() *Element { return m.ll.Back() } // Copy returns a new OrderedMap with the same elements. // Using Copy while there are concurrent writes may mangle the result. func (m *OrderedMap) Copy() *OrderedMap { m2 := NewOrderedMapWithCapacity(m.Len()) for el := m.Front(); el != nil; el = el.Next() { m2.Set(el.Key, el.Value) } return m2 } // Has checks if a key exists in the map. func (m *OrderedMap) Has(key interface{}) bool { _, exists := m.kv[key] return exists } orderedmap-1.8.0/orderedmap_test.go000066400000000000000000000664501473553416400174010ustar00rootroot00000000000000package orderedmap_test import ( "fmt" "strconv" "testing" "github.com/elliotchance/orderedmap" "github.com/stretchr/testify/assert" ) func TestNewOrderedMap(t *testing.T) { m := orderedmap.NewOrderedMap() assert.IsType(t, &orderedmap.OrderedMap{}, m) } func TestGet(t *testing.T) { t.Run("ReturnsNotOKIfStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap() _, ok := m.Get("foo") assert.False(t, ok) }) t.Run("ReturnsNotOKIfNonStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap() _, ok := m.Get(123) assert.False(t, ok) }) t.Run("ReturnsOKIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") _, ok := m.Get("foo") assert.True(t, ok) }) t.Run("ReturnsValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") value, _ := m.Get("foo") assert.Equal(t, "bar", value) }) t.Run("ReturnsDynamicValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "baz") value, _ := m.Get("foo") assert.Equal(t, "baz", value) }) t.Run("KeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "baz") _, ok := m.Get("bar") assert.False(t, ok) }) t.Run("ValueForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "baz") value, _ := m.Get("bar") assert.Nil(t, value) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_Get(100)) res4 := testing.Benchmark(benchmarkOrderedMap_Get(400)) // O(1) would mean that res4 should take about the same time as res1, // because we are accessing the same amount of elements, just on // different sized maps. assert.InDelta(t, res1.NsPerOp(), res4.NsPerOp(), 0.5*float64(res1.NsPerOp())) }) } func TestSet(t *testing.T) { t.Run("ReturnsTrueIfStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap() ok := m.Set("foo", "bar") assert.True(t, ok) }) t.Run("ReturnsTrueIfNonStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap() ok := m.Set(123, "bar") assert.True(t, ok) }) t.Run("ValueCanBeNonString", func(t *testing.T) { m := orderedmap.NewOrderedMap() ok := m.Set(123, true) assert.True(t, ok) }) t.Run("ReturnsFalseIfKeyIsNotNew", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") ok := m.Set("foo", "bar") assert.False(t, ok) }) t.Run("SetThreeDifferentKeys", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") m.Set("baz", "qux") ok := m.Set("quux", "corge") assert.True(t, ok) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_Set(100)) res4 := testing.Benchmark(benchmarkOrderedMap_Set(400)) // O(1) would mean that res4 should take about 4 times longer than res1 // because we are doing 4 times the amount of Set operations. Allow for // a wide margin, but not too wide that it would permit the inflection // to O(n^2). assert.InDelta(t, 4*res1.NsPerOp(), res4.NsPerOp(), 2*float64(res1.NsPerOp())) }) } func TestLen(t *testing.T) { t.Run("EmptyMapIsZeroLen", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.Equal(t, 0, m.Len()) }) t.Run("SingleElementIsLenOne", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set(123, true) assert.Equal(t, 1, m.Len()) }) t.Run("ThreeElements", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set(1, true) m.Set(2, true) m.Set(3, true) assert.Equal(t, 3, m.Len()) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_Len(100)) res4 := testing.Benchmark(benchmarkOrderedMap_Len(400)) // O(1) would mean that res4 should take about the same time as res1, // because we are accessing the same amount of elements, just on // different sized maps. assert.InDelta(t, res1.NsPerOp(), res4.NsPerOp(), 0.5*float64(res1.NsPerOp())) }) } func TestKeys(t *testing.T) { t.Run("EmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.Empty(t, m.Keys()) }) t.Run("OneElement", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set(1, true) assert.Equal(t, []interface{}{1}, m.Keys()) }) t.Run("RetainsOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap() for i := 1; i < 10; i++ { m.Set(i, true) } assert.Equal(t, []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}, m.Keys()) }) t.Run("ReplacingKeyDoesntChangeOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", true) m.Set("bar", true) m.Set("foo", false) assert.Equal(t, []interface{}{"foo", "bar"}, m.Keys()) }) t.Run("KeysAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", true) m.Set("bar", true) m.Delete("foo") assert.Equal(t, []interface{}{"bar"}, m.Keys()) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_Keys(100)) res4 := testing.Benchmark(benchmarkOrderedMap_Keys(400)) // O(1) would mean that res4 should take about 4 times longer than res1 // because we are doing 4 times the amount of Set/Delete operations. // Allow for a wide margin, but not too wide that it would permit the // inflection to O(n^2). assert.InDelta(t, 4*res1.NsPerOp(), res4.NsPerOp(), float64(res4.NsPerOp())) }) } func TestDelete(t *testing.T) { t.Run("KeyDoesntExistReturnsFalse", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.False(t, m.Delete("foo")) }) t.Run("KeyDoesExist", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", nil) assert.True(t, m.Delete("foo")) }) t.Run("KeyNoLongerExists", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", nil) m.Delete("foo") _, exists := m.Get("foo") assert.False(t, exists) }) t.Run("KeyDeleteIsIsolated", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", nil) m.Set("bar", nil) m.Delete("foo") _, exists := m.Get("bar") assert.True(t, exists) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_Delete(100)) res4 := testing.Benchmark(benchmarkOrderedMap_Delete(400)) // O(1) would mean that res4 should take about 4 times longer than res1 // because we are doing 4 times the amount of Set/Delete operations. // Allow for a wide margin, but not too wide that it would permit the // inflection to O(n^2). assert.InDelta(t, 4*res1.NsPerOp(), res4.NsPerOp(), float64(res4.NsPerOp())) }) } func TestOrderedMap_Front(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.Nil(t, m.Front()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set(1, true) assert.NotNil(t, m.Front()) }) } func TestOrderedMap_Back(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.Nil(t, m.Back()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set(1, true) assert.NotNil(t, m.Back()) }) } func TestOrderedMap_Copy(t *testing.T) { t.Run("ReturnsEqualButNotSame", func(t *testing.T) { key, value := 1, "a value" m := orderedmap.NewOrderedMap() m.Set(key, value) m2 := m.Copy() m2.Set(key, "a different value") assert.Equal(t, m.Len(), m2.Len(), "not all elements are copied") assert.Equal(t, value, m.GetElement(key).Value) }) } func TestGetElement(t *testing.T) { t.Run("ReturnsElementForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") var results []interface{} element := m.GetElement("foo") if element != nil { results = append(results, element.Key, element.Value) } assert.Equal(t, []interface{}{"foo", "bar"}, results) }) t.Run("ElementForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "baz") element := m.GetElement("bar") assert.Nil(t, element) }) t.Run("Performance", func(t *testing.T) { if testing.Short() { t.Skip("performance test skipped in short mode") } res1 := testing.Benchmark(benchmarkOrderedMap_GetElement(100)) res4 := testing.Benchmark(benchmarkOrderedMap_GetElement(400)) // O(1) would mean that res4 should take about the same time as res1, // because we are accessing the same amount of elements, just on // different sized maps. assert.InDelta(t, res1.NsPerOp(), res4.NsPerOp(), 0.5*float64(res1.NsPerOp())) }) } func TestOrderedMap_Has(t *testing.T) { t.Run("ReturnsFalseIfKeyDoesNotExist", func(t *testing.T) { m := orderedmap.NewOrderedMap() assert.False(t, m.Has("foo")) }) t.Run("ReturnsTrueIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") assert.True(t, m.Has("foo")) }) t.Run("KeyDoesNotExistAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap() m.Set("foo", "bar") m.Delete("foo") assert.False(t, m.Has("foo")) }) } func benchmarkMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } } } func BenchmarkMap_Set(b *testing.B) { benchmarkMap_Set(1)(b) } func benchmarkOrderedMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } } } func BenchmarkOrderedMap_Set(b *testing.B) { benchmarkOrderedMap_Set(1)(b) } func benchmarkMap_Get(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Get(b *testing.B) { benchmarkMap_Get(1)(b) } func benchmarkOrderedMap_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Get(b *testing.B) { benchmarkOrderedMap_Get(1)(b) } func benchmarkOrderedMap_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_GetElement(b *testing.B) { benchmarkOrderedMap_GetElement(1)(b) } var tempInt int func benchmarkOrderedMap_Len(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { var temp int for i := 0; i < b.N; i++ { temp = m.Len() } // prevent compiler from optimising Len away. tempInt = temp } } func BenchmarkOrderedMap_Len(b *testing.B) { benchmarkOrderedMap_Len(1)(b) } func benchmarkMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } for i := 0; i < b.N; i++ { delete(m, i) } } } func BenchmarkMap_Delete(b *testing.B) { benchmarkMap_Delete(1)(b) } func benchmarkOrderedMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } for i := 0; i < b.N; i++ { m.Delete(i) } } } func BenchmarkOrderedMap_Delete(b *testing.B) { benchmarkOrderedMap_Delete(1)(b) } func benchmarkMap_Iterate(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMap_Iterate(b *testing.B) { benchmarkMap_Iterate(1)(b) } func benchmarkOrderedMap_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func benchmarkMap_Has(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Has(b *testing.B) { benchmarkMap_Has(1)(b) } func benchmarkOrderedMap_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Has(b *testing.B) { benchmarkOrderedMap_Has(1)(b) } func BenchmarkOrderedMap_Iterate(b *testing.B) { benchmarkOrderedMap_Iterate(1)(b) } func benchmarkOrderedMap_Keys(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Keys() } } } func benchmarkMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } } } func BenchmarkMapString_Set(b *testing.B) { benchmarkMapString_Set(1)(b) } func benchmarkOrderedMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } } } func BenchmarkOrderedMapString_Set(b *testing.B) { benchmarkOrderedMapString_Set(1)(b) } func benchmarkMapString_Get(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Get(b *testing.B) { benchmarkMapString_Get(1)(b) } func benchmarkOrderedMapString_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Get(b *testing.B) { benchmarkOrderedMapString_Get(1)(b) } func benchmarkOrderedMapString_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_GetElement(b *testing.B) { benchmarkOrderedMapString_GetElement(1)(b) } func benchmarkMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } for i := 0; i < b.N; i++ { delete(m, a+strconv.Itoa(i)) } } } func BenchmarkMapString_Delete(b *testing.B) { benchmarkMapString_Delete(1)(b) } func benchmarkOrderedMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } for i := 0; i < b.N; i++ { m.Delete(a + strconv.Itoa(i)) } } } func BenchmarkOrderedMapString_Delete(b *testing.B) { benchmarkOrderedMapString_Delete(1)(b) } func benchmarkMapString_Iterate(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMapString_Iterate(b *testing.B) { benchmarkMapString_Iterate(1)(b) } func benchmarkOrderedMapString_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkOrderedMapString_Iterate(b *testing.B) { benchmarkOrderedMapString_Iterate(1)(b) } func benchmarkMapString_Has(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Has(b *testing.B) { benchmarkMapString_Has(1)(b) } func benchmarkOrderedMapString_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Has(b *testing.B) { benchmarkOrderedMapString_Has(1)(b) } func BenchmarkOrderedMap_Keys(b *testing.B) { benchmarkOrderedMap_Keys(1)(b) } func ExampleNewOrderedMap() { 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) } } func ExampleOrderedMap_Front() { m := orderedmap.NewOrderedMap() m.Set(1, true) m.Set(2, true) for el := m.Front(); el != nil; el = el.Next() { fmt.Println(el) } } func nothing(v interface{}) { v = false } func benchmarkBigMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } } } } func BenchmarkBigMap_Set(b *testing.B) { benchmarkBigMap_Set()(b) } func benchmarkBigOrderedMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigOrderedMap_Set(b *testing.B) { benchmarkBigOrderedMap_Set()(b) } func benchmarkBigMapWithCapacity_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMapWithCapacity(10000000) for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigMapWithCapacity_Set(b *testing.B) { benchmarkBigMapWithCapacity_Set()(b) } func benchmarkBigMap_Get() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Get(b *testing.B) { benchmarkBigMap_Get()(b) } func benchmarkBigOrderedMap_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(i) } } } } func BenchmarkBigOrderedMap_Get(b *testing.B) { benchmarkBigOrderedMap_Get()(b) } func benchmarkBigOrderedMap_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(i) } } } } func BenchmarkBigOrderedMap_GetElement(b *testing.B) { benchmarkBigOrderedMap_GetElement()(b) } func benchmarkBigMap_Iterate() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMap_Iterate(b *testing.B) { benchmarkBigMap_Iterate()(b) } func benchmarkBigOrderedMap_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMap_Iterate(b *testing.B) { benchmarkBigOrderedMap_Iterate()(b) } func benchmarkBigMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } } } } func benchmarkBigMap_Has() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Has(b *testing.B) { benchmarkBigMap_Has()(b) } func benchmarkBigOrderedMap_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(i) } } } } func BenchmarkBigOrderedMap_Has(b *testing.B) { benchmarkBigOrderedMap_Has()(b) } func BenchmarkBigMapString_Set(b *testing.B) { benchmarkBigMapString_Set()(b) } func benchmarkBigOrderedMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } } } } func BenchmarkBigOrderedMapString_Set(b *testing.B) { benchmarkBigOrderedMapString_Set()(b) } func benchmarkBigMapString_Get() func(b *testing.B) { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Get(b *testing.B) { benchmarkBigMapString_Get()(b) } func benchmarkBigOrderedMapString_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_Get(b *testing.B) { benchmarkBigOrderedMapString_Get()(b) } func benchmarkBigOrderedMapString_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_GetElement(b *testing.B) { benchmarkBigOrderedMapString_GetElement()(b) } func benchmarkBigMapString_Iterate() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMapString_Iterate(b *testing.B) { benchmarkBigMapString_Iterate()(b) } func benchmarkBigOrderedMapString_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap() a := "12345678" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMapString_Iterate(b *testing.B) { benchmarkBigOrderedMapString_Iterate()(b) } func benchmarkBigMapString_Has() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Has(b *testing.B) { benchmarkBigMapString_Has()(b) } func benchmarkBigOrderedMapString_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(i) } } } } func BenchmarkBigOrderedMapString_Has(b *testing.B) { benchmarkBigOrderedMapString_Has()(b) } func BenchmarkAll(b *testing.B) { b.Run("BenchmarkOrderedMap_Keys", BenchmarkOrderedMap_Keys) b.Run("BenchmarkOrderedMap_Set", BenchmarkOrderedMap_Set) b.Run("BenchmarkMap_Set", BenchmarkMap_Set) b.Run("BenchmarkOrderedMap_Get", BenchmarkOrderedMap_Get) b.Run("BenchmarkMap_Get", BenchmarkMap_Get) b.Run("BenchmarkOrderedMap_GetElement", BenchmarkOrderedMap_GetElement) b.Run("BenchmarkOrderedMap_Delete", BenchmarkOrderedMap_Delete) b.Run("BenchmarkMap_Delete", BenchmarkMap_Delete) b.Run("BenchmarkOrderedMap_Iterate", BenchmarkOrderedMap_Iterate) b.Run("BenchmarkMap_Iterate", BenchmarkMap_Iterate) b.Run("BenchmarkOrderedMap_Has", BenchmarkOrderedMap_Has) b.Run("BenchmarkMap_Has", BenchmarkMap_Has) b.Run("BenchmarkBigMap_Set", BenchmarkBigMap_Set) b.Run("BenchmarkBigOrderedMap_Set", BenchmarkBigOrderedMap_Set) b.Run("BenchmarkBigMap_Get", BenchmarkBigMap_Get) b.Run("BenchmarkBigOrderedMap_Get", BenchmarkBigOrderedMap_Get) b.Run("BenchmarkBigOrderedMap_GetElement", BenchmarkBigOrderedMap_GetElement) b.Run("BenchmarkBigOrderedMap_Iterate", BenchmarkBigOrderedMap_Iterate) b.Run("BenchmarkBigMap_Iterate", BenchmarkBigMap_Iterate) b.Run("BenchmarkBigMap_Has", BenchmarkBigMap_Has) b.Run("BenchmarkBigOrderedMap_Has", BenchmarkBigOrderedMap_Has) b.Run("BenchmarkOrderedMapString_Set", BenchmarkOrderedMapString_Set) b.Run("BenchmarkMapString_Set", BenchmarkMapString_Set) b.Run("BenchmarkOrderedMapString_Get", BenchmarkOrderedMapString_Get) b.Run("BenchmarkMapString_Get", BenchmarkMapString_Get) b.Run("BenchmarkOrderedMapString_GetElement", BenchmarkOrderedMapString_GetElement) b.Run("BenchmarkOrderedMapString_Delete", BenchmarkOrderedMapString_Delete) b.Run("BenchmarkMapString_Delete", BenchmarkMapString_Delete) b.Run("BenchmarkOrderedMapString_Iterate", BenchmarkOrderedMapString_Iterate) b.Run("BenchmarkMapString_Iterate", BenchmarkMapString_Iterate) b.Run("BenchmarkMapString_Has", BenchmarkMapString_Has) b.Run("BenchmarkOrderedMapString_Has", BenchmarkOrderedMapString_Has) b.Run("BenchmarkBigMapString_Set", BenchmarkBigMapString_Set) b.Run("BenchmarkBigOrderedMapString_Set", BenchmarkBigOrderedMapString_Set) b.Run("BenchmarkBigMapString_Get", BenchmarkBigMapString_Get) b.Run("BenchmarkBigOrderedMapString_Get", BenchmarkBigOrderedMapString_Get) b.Run("BenchmarkBigOrderedMapString_GetElement", BenchmarkBigOrderedMapString_GetElement) b.Run("BenchmarkBigOrderedMapString_Iterate", BenchmarkBigOrderedMapString_Iterate) b.Run("BenchmarkBigMapString_Iterate", BenchmarkBigMapString_Iterate) b.Run("BenchmarkBigMapString_Has", BenchmarkBigMapString_Has) b.Run("BenchmarkBigOrderedMapString_Has", BenchmarkBigOrderedMapString_Has) } orderedmap-1.8.0/v2/000077500000000000000000000000001473553416400142055ustar00rootroot00000000000000orderedmap-1.8.0/v2/go.mod000066400000000000000000000005261473553416400153160ustar00rootroot00000000000000module github.com/elliotchance/orderedmap/v2 go 1.18 require ( github.com/davecgh/go-spew v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.7.1 // indirect golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) orderedmap-1.8.0/v2/go.sum000066400000000000000000000021521473553416400153400ustar00rootroot00000000000000github.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.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 h1:ba9YlqfDGTTQ5aZ2fwOoQ1hf32QySyQkR6ODGDzHlnE= golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= orderedmap-1.8.0/v2/iterator.go000066400000000000000000000007701473553416400163710ustar00rootroot00000000000000//go:build go1.23 // +build go1.23 package orderedmap import "iter" func (m *OrderedMap[K, V]) Iterator() iter.Seq2[K, V] { return func(yield func(key K, value V) bool) { for el := m.Front(); el != nil; el = el.Next() { if !yield(el.Key, el.Value) { return } } } } func (m *OrderedMap[K, V]) ReverseIterator() iter.Seq2[K, V] { return func(yield func(key K, value V) bool) { for el := m.Back(); el != nil; el = el.Prev() { if !yield(el.Key, el.Value) { return } } } } orderedmap-1.8.0/v2/iterator_test.go000066400000000000000000000015041473553416400174240ustar00rootroot00000000000000//go:build go1.23 // +build go1.23 package orderedmap_test import ( "testing" "github.com/elliotchance/orderedmap/v2" "github.com/stretchr/testify/assert" ) func TestIterators(t *testing.T) { type Element struct { Key int Value bool } m := orderedmap.NewOrderedMap[int, bool]() expected := []Element{{5, true}, {3, false}, {1, false}, {4, true}} for _, v := range expected { m.Set(v.Key, v.Value) } t.Run("Iterator", func(t *testing.T) { i := 0 for key, value := range m.Iterator() { assert.Equal(t, expected[i].Key, key) assert.Equal(t, expected[i].Value, value) i++ } }) t.Run("ReverseIterator", func(t *testing.T) { i := len(expected) - 1 for key, value := range m.ReverseIterator() { assert.Equal(t, expected[i].Key, key) assert.Equal(t, expected[i].Value, value) i-- } }) } orderedmap-1.8.0/v2/list.go000066400000000000000000000050451473553416400155130ustar00rootroot00000000000000package orderedmap // Element is an element of a null terminated (non circular) intrusive doubly linked list that contains the key of the correspondent element in the ordered map too. type Element[K comparable, V any] struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). next, prev *Element[K, V] // The key that corresponds to this element in the ordered map. Key K // The value stored with this element. Value V } // Next returns the next list element or nil. func (e *Element[K, V]) Next() *Element[K, V] { return e.next } // Prev returns the previous list element or nil. func (e *Element[K, V]) Prev() *Element[K, V] { return e.prev } // list represents a null terminated (non circular) intrusive doubly linked list. // The list is immediately usable after instantiation without the need of a dedicated initialization. type list[K comparable, V any] struct { root Element[K, V] // list head and tail } func (l *list[K, V]) IsEmpty() bool { return l.root.next == nil } // Front returns the first element of list l or nil if the list is empty. func (l *list[K, V]) Front() *Element[K, V] { return l.root.next } // Back returns the last element of list l or nil if the list is empty. func (l *list[K, V]) Back() *Element[K, V] { return l.root.prev } // Remove removes e from its list func (l *list[K, V]) Remove(e *Element[K, V]) { if e.prev == nil { l.root.next = e.next } else { e.prev.next = e.next } if e.next == nil { l.root.prev = e.prev } else { e.next.prev = e.prev } e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks } // PushFront inserts a new element e with value v at the front of list l and returns e. func (l *list[K, V]) PushFront(key K, value V) *Element[K, V] { e := &Element[K, V]{Key: key, Value: value} if l.root.next == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.next = l.root.next l.root.next.prev = e l.root.next = e return e } // PushBack inserts a new element e with value v at the back of list l and returns e. func (l *list[K, V]) PushBack(key K, value V) *Element[K, V] { e := &Element[K, V]{Key: key, Value: value} if l.root.prev == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.prev = l.root.prev l.root.prev.next = e l.root.prev = e return e } orderedmap-1.8.0/v2/orderedmap.go000066400000000000000000000077511473553416400166700ustar00rootroot00000000000000package orderedmap type OrderedMap[K comparable, V any] struct { kv map[K]*Element[K, V] ll list[K, V] } func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V] { return &OrderedMap[K, V]{ kv: make(map[K]*Element[K, V]), } } // NewOrderedMapWithCapacity creates a map with enough pre-allocated space to // hold the specified number of elements. func NewOrderedMapWithCapacity[K comparable, V any](capacity int) *OrderedMap[K, V] { return &OrderedMap[K, V]{ kv: make(map[K]*Element[K, V], capacity), } } func NewOrderedMapWithElements[K comparable, V any](els ...*Element[K, V]) *OrderedMap[K, V] { om := NewOrderedMapWithCapacity[K, V](len(els)) for _, el := range els { om.Set(el.Key, el.Value) } return om } // 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[K, V]) Get(key K) (value V, ok bool) { v, ok := m.kv[key] if ok { value = v.Value } return } // 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[K, V]) Set(key K, value V) bool { _, alreadyExist := m.kv[key] if alreadyExist { m.kv[key].Value = value return false } element := m.ll.PushBack(key, value) m.kv[key] = element return true } // ReplaceKey replaces an existing key with a new key while preserving order of // the value. This function will return true if the operation was successful, or // false if 'originalKey' is not found OR 'newKey' already exists (which would be an overwrite). func (m *OrderedMap[K, V]) ReplaceKey(originalKey, newKey K) bool { element, originalExists := m.kv[originalKey] _, newKeyExists := m.kv[newKey] if originalExists && !newKeyExists { delete(m.kv, originalKey) m.kv[newKey] = element element.Key = newKey return true } return false } // GetOrDefault returns the value for a key. If the key does not exist, returns // the default value instead. func (m *OrderedMap[K, V]) GetOrDefault(key K, defaultValue V) V { if value, ok := m.kv[key]; ok { return value.Value } return defaultValue } // GetElement returns the element for a key. If the key does not exist, the // pointer will be nil. func (m *OrderedMap[K, V]) GetElement(key K) *Element[K, V] { element, ok := m.kv[key] if ok { return element } return nil } // Len returns the number of elements in the map. func (m *OrderedMap[K, V]) 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[K, V]) Keys() (keys []K) { keys = make([]K, 0, m.Len()) for el := m.Front(); el != nil; el = el.Next() { keys = append(keys, el.Key) } 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[K, V]) Delete(key K) (didDelete bool) { element, ok := m.kv[key] if ok { m.ll.Remove(element) delete(m.kv, key) } return ok } // Front will return the element that is the first (oldest Set element). If // there are no elements this will return nil. func (m *OrderedMap[K, V]) Front() *Element[K, V] { return m.ll.Front() } // Back will return the element that is the last (most recent Set element). If // there are no elements this will return nil. func (m *OrderedMap[K, V]) Back() *Element[K, V] { return m.ll.Back() } // Copy returns a new OrderedMap with the same elements. // Using Copy while there are concurrent writes may mangle the result. func (m *OrderedMap[K, V]) Copy() *OrderedMap[K, V] { m2 := NewOrderedMapWithCapacity[K, V](m.Len()) for el := m.Front(); el != nil; el = el.Next() { m2.Set(el.Key, el.Value) } return m2 } // Has checks if a key exists in the map. func (m *OrderedMap[K, V]) Has(key K) bool { _, exists := m.kv[key] return exists } orderedmap-1.8.0/v2/orderedmap_test.go000066400000000000000000000661601473553416400177260ustar00rootroot00000000000000package orderedmap_test import ( "strconv" "testing" "github.com/elliotchance/orderedmap/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewOrderedMap(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() assert.IsType(t, &orderedmap.OrderedMap[int, string]{}, m) } func TestGet(t *testing.T) { t.Run("ReturnsNotOKIfStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() _, ok := m.Get("foo") assert.False(t, ok) }) t.Run("ReturnsNotOKIfNonStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() _, ok := m.Get(123) assert.False(t, ok) }) t.Run("ReturnsOKIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") _, ok := m.Get("foo") assert.True(t, ok) }) t.Run("ReturnsValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") value, _ := m.Get("foo") assert.Equal(t, "bar", value) }) t.Run("ReturnsDynamicValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") value, _ := m.Get("foo") assert.Equal(t, "baz", value) }) t.Run("KeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") _, ok := m.Get("bar") assert.False(t, ok) }) t.Run("ValueForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") value, _ := m.Get("bar") assert.Empty(t, value) }) } func TestSet(t *testing.T) { t.Run("ReturnsTrueIfStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() ok := m.Set("foo", "bar") assert.True(t, ok) }) t.Run("ReturnsTrueIfNonStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() ok := m.Set(123, "bar") assert.True(t, ok) }) t.Run("ValueCanBeNonString", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() ok := m.Set(123, true) assert.True(t, ok) }) t.Run("ReturnsFalseIfKeyIsNotNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") ok := m.Set("foo", "bar") assert.False(t, ok) }) t.Run("SetThreeDifferentKeys", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Set("baz", "qux") ok := m.Set("quux", "corge") assert.True(t, ok) }) } func TestReplaceKey(t *testing.T) { t.Run("ReturnsFalseIfOriginalKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.ReplaceKey("foo", "bar")) }) t.Run("ReturnsFalseIfNewKeyAlreadyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Set("baz", "qux") assert.False(t, m.ReplaceKey("foo", "baz")) assert.Equal(t, []string{"foo", "baz"}, m.Keys()) }) t.Run("ReturnsTrueIfOnlyOriginalKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") assert.True(t, m.ReplaceKey("foo", "baz")) // Now validate the "replacement" was a success. el := m.GetElement("baz") require.NotNil(t, el) assert.Equal(t, "bar", el.Value) assert.Equal(t, "baz", el.Key) v, ok := m.Get("baz") assert.True(t, ok) assert.Equal(t, "bar", v) assert.Equal(t, []string{"baz"}, m.Keys()) assert.Equal(t, 1, m.Len()) _, ok = m.Get("foo") // original key assert.False(t, ok) }) t.Run("KeyMaintainsOrderWhenReplaced", func(t *testing.T) { count := 100 // Build a larger map to help validate that the order is not coincidental. m := orderedmap.NewOrderedMap[int, int]() for i := 0; i < count; i++ { m.Set(i, i) } // Rename the middle 50-60 elements to 100+ current for i := 50; i < 60; i++ { assert.True(t, m.ReplaceKey(i, i+100)) } // ensure length is maintained assert.Equal(t, count, m.Len()) // Validate the order is maintained. keys := m.Keys() for i, key := range keys { if i >= 50 && i < 60 { assert.Equal(t, i+100, key) } else { assert.Equal(t, i, key) } } }) } func TestLen(t *testing.T) { t.Run("EmptyMapIsZeroLen", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.Equal(t, 0, m.Len()) }) t.Run("SingleElementIsLenOne", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(123, true) assert.Equal(t, 1, m.Len()) }) t.Run("ThreeElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) m.Set(2, true) m.Set(3, true) assert.Equal(t, 3, m.Len()) }) } func TestKeys(t *testing.T) { t.Run("EmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Empty(t, m.Keys()) }) t.Run("OneElement", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.Equal(t, []int{1}, m.Keys()) }) t.Run("RetainsOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() for i := 1; i < 10; i++ { m.Set(i, true) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9}, m.Keys()) }) t.Run("ReplacingKeyDoesntChangeOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, bool]() m.Set("foo", true) m.Set("bar", true) m.Set("foo", false) assert.Equal(t, []string{"foo", "bar"}, m.Keys()) }) t.Run("KeysAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, bool]() m.Set("foo", true) m.Set("bar", true) m.Delete("foo") assert.Equal(t, []string{"bar"}, m.Keys()) }) } func TestDelete(t *testing.T) { t.Run("KeyDoesntExistReturnsFalse", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.Delete("foo")) }) t.Run("KeyDoesExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) assert.True(t, m.Delete("foo")) }) t.Run("KeyNoLongerExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) m.Delete("foo") _, exists := m.Get("foo") assert.False(t, exists) }) t.Run("KeyDeleteIsIsolated", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) m.Set("bar", nil) m.Delete("foo") _, exists := m.Get("bar") assert.True(t, exists) }) } func TestOrderedMap_Front(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Nil(t, m.Front()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.NotNil(t, m.Front()) }) } func TestOrderedMap_Back(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Nil(t, m.Back()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.NotNil(t, m.Back()) }) } func TestOrderedMap_Copy(t *testing.T) { t.Run("ReturnsEqualButNotSame", func(t *testing.T) { key, value := 1, "a value" m := orderedmap.NewOrderedMap[int, string]() m.Set(key, value) m2 := m.Copy() m2.Set(key, "a different value") assert.Equal(t, m.Len(), m2.Len(), "not all elements are copied") assert.Equal(t, value, m.GetElement(key).Value) }) } func TestGetElement(t *testing.T) { t.Run("ReturnsElementForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") var results []any element := m.GetElement("foo") if element != nil { results = append(results, element.Key, element.Value) } assert.Equal(t, []any{"foo", "bar"}, results) }) t.Run("ElementForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") element := m.GetElement("bar") assert.Nil(t, element) }) } func TestSetAndGet(t *testing.T) { t.Run("FourBoolElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() expected := map[int]bool{1: true, 3: false, 5: false, 4: true} for k, v := range expected { m.Set(k, v) } for k, v := range expected { w, ok := m.Get(k) assert.True(t, ok) assert.Equal(t, v, w) } }) } func TestIterations(t *testing.T) { type Element struct { Key int Value bool } t.Run("FourBoolElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() expected := []Element{{5, true}, {3, false}, {1, false}, {4, true}} for _, v := range expected { m.Set(v.Key, v.Value) } element := m.Front() for i := 0; i < len(expected); i++ { assert.NotNil(t, element) assert.Equal(t, expected[i].Key, element.Key) assert.Equal(t, expected[i].Value, element.Value) element = element.Next() } assert.Nil(t, element) }) } func TestOrderedMap_Has(t *testing.T) { t.Run("ReturnsFalseIfKeyDoesNotExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.Has("foo")) }) t.Run("ReturnsTrueIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") assert.True(t, m.Has("foo")) }) t.Run("KeyDoesNotExistAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Delete("foo") assert.False(t, m.Has("foo")) }) } func benchmarkMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } } } func BenchmarkMap_Set(b *testing.B) { benchmarkMap_Set(1)(b) } func benchmarkOrderedMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } } } func BenchmarkOrderedMap_Set(b *testing.B) { benchmarkOrderedMap_Set(1)(b) } func benchmarkMap_Get(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Get(b *testing.B) { benchmarkMap_Get(1)(b) } func benchmarkOrderedMap_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Get(b *testing.B) { benchmarkOrderedMap_Get(1)(b) } func benchmarkOrderedMap_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_GetElement(b *testing.B) { benchmarkOrderedMap_GetElement(1)(b) } var tempInt int func benchmarkOrderedMap_Len(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { var temp int for i := 0; i < b.N; i++ { temp = m.Len() } // prevent compiler from optimising Len away. tempInt = temp } } func BenchmarkOrderedMap_Len(b *testing.B) { benchmarkOrderedMap_Len(1)(b) } func benchmarkMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } for i := 0; i < b.N; i++ { delete(m, i) } } } func BenchmarkMap_Delete(b *testing.B) { benchmarkMap_Delete(1)(b) } func benchmarkOrderedMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } for i := 0; i < b.N; i++ { m.Delete(i) } } } func BenchmarkOrderedMap_Delete(b *testing.B) { benchmarkOrderedMap_Delete(1)(b) } func benchmarkMap_Iterate(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMap_Iterate(b *testing.B) { benchmarkMap_Iterate(1)(b) } func benchmarkOrderedMap_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkOrderedMap_Iterate(b *testing.B) { benchmarkOrderedMap_Iterate(1)(b) } func benchmarkMap_Has(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Has(b *testing.B) { benchmarkMap_Has(1)(b) } func benchmarkOrderedMap_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Has(b *testing.B) { benchmarkOrderedMap_Has(1)(b) } func benchmarkOrderedMap_Keys(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Keys() } } } func benchmarkMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } } } func BenchmarkMapString_Set(b *testing.B) { benchmarkMapString_Set(1)(b) } func benchmarkOrderedMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } } } func BenchmarkOrderedMapString_Set(b *testing.B) { benchmarkOrderedMapString_Set(1)(b) } func benchmarkMapString_Get(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Get(b *testing.B) { benchmarkMapString_Get(1)(b) } func benchmarkOrderedMapString_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Get(b *testing.B) { benchmarkOrderedMapString_Get(1)(b) } func benchmarkOrderedMapString_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_GetElement(b *testing.B) { benchmarkOrderedMapString_GetElement(1)(b) } func benchmarkMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } for i := 0; i < b.N; i++ { delete(m, a+strconv.Itoa(i)) } } } func BenchmarkMapString_Delete(b *testing.B) { benchmarkMapString_Delete(1)(b) } func benchmarkOrderedMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } for i := 0; i < b.N; i++ { m.Delete(a + strconv.Itoa(i)) } } } func BenchmarkOrderedMapString_Delete(b *testing.B) { benchmarkOrderedMapString_Delete(1)(b) } func benchmarkMapString_Iterate(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMapString_Iterate(b *testing.B) { benchmarkMapString_Iterate(1)(b) } func benchmarkOrderedMapString_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkOrderedMapString_Iterate(b *testing.B) { benchmarkOrderedMapString_Iterate(1)(b) } func benchmarkMapString_Has(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Has(b *testing.B) { benchmarkMapString_Has(1)(b) } func benchmarkOrderedMapString_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Has(b *testing.B) { benchmarkOrderedMapString_Has(1)(b) } func BenchmarkOrderedMap_Keys(b *testing.B) { benchmarkOrderedMap_Keys(1)(b) } func nothing(v interface{}) { v = false } func benchmarkBigMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } } } } func BenchmarkBigMap_Set(b *testing.B) { benchmarkBigMap_Set()(b) } func benchmarkBigOrderedMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigOrderedMap_Set(b *testing.B) { benchmarkBigOrderedMap_Set()(b) } func benchmarkBigMapWithCapacity_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMapWithCapacity[int, bool](10000000) for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigMapWithCapacity_Set(b *testing.B) { benchmarkBigMapWithCapacity_Set()(b) } func benchmarkBigMap_Get() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Get(b *testing.B) { benchmarkBigMap_Get()(b) } func benchmarkBigOrderedMap_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(i) } } } } func BenchmarkBigOrderedMap_Get(b *testing.B) { benchmarkBigOrderedMap_Get()(b) } func benchmarkBigOrderedMap_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(i) } } } } func BenchmarkBigOrderedMap_GetElement(b *testing.B) { benchmarkBigOrderedMap_GetElement()(b) } func benchmarkBigMap_Iterate() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMap_Iterate(b *testing.B) { benchmarkBigMap_Iterate()(b) } func benchmarkBigOrderedMap_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMap_Iterate(b *testing.B) { benchmarkBigOrderedMap_Iterate()(b) } func benchmarkBigMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } } } } func benchmarkBigMap_Has() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Has(b *testing.B) { benchmarkBigMap_Has()(b) } func benchmarkBigOrderedMap_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(i) } } } } func BenchmarkBigOrderedMap_Has(b *testing.B) { benchmarkBigOrderedMap_Has()(b) } func BenchmarkBigMapString_Set(b *testing.B) { benchmarkBigMapString_Set()(b) } func benchmarkBigOrderedMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } } } } func BenchmarkBigOrderedMapString_Set(b *testing.B) { benchmarkBigOrderedMapString_Set()(b) } func benchmarkBigMapString_Get() func(b *testing.B) { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Get(b *testing.B) { benchmarkBigMapString_Get()(b) } func benchmarkBigOrderedMapString_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_Get(b *testing.B) { benchmarkBigOrderedMapString_Get()(b) } func benchmarkBigOrderedMapString_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_GetElement(b *testing.B) { benchmarkBigOrderedMapString_GetElement()(b) } func benchmarkBigMapString_Iterate() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMapString_Iterate(b *testing.B) { benchmarkBigMapString_Iterate()(b) } func benchmarkBigOrderedMapString_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range m.Keys() { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMapString_Iterate(b *testing.B) { benchmarkBigOrderedMapString_Iterate()(b) } func benchmarkBigMapString_Has() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Has(b *testing.B) { benchmarkBigMapString_Has()(b) } func benchmarkBigOrderedMapString_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_Has(b *testing.B) { benchmarkBigOrderedMapString_Has()(b) } func BenchmarkAll(b *testing.B) { b.Run("BenchmarkOrderedMap_Keys", BenchmarkOrderedMap_Keys) b.Run("BenchmarkOrderedMap_Set", BenchmarkOrderedMap_Set) b.Run("BenchmarkMap_Set", BenchmarkMap_Set) b.Run("BenchmarkOrderedMap_Get", BenchmarkOrderedMap_Get) b.Run("BenchmarkMap_Get", BenchmarkMap_Get) b.Run("BenchmarkOrderedMap_GetElement", BenchmarkOrderedMap_GetElement) b.Run("BenchmarkOrderedMap_Delete", BenchmarkOrderedMap_Delete) b.Run("BenchmarkMap_Delete", BenchmarkMap_Delete) b.Run("BenchmarkOrderedMap_Iterate", BenchmarkOrderedMap_Iterate) b.Run("BenchmarkMap_Iterate", BenchmarkMap_Iterate) b.Run("BenchmarkOrderedMap_Has", BenchmarkOrderedMap_Has) b.Run("BenchmarkMap_Has", BenchmarkMap_Has) b.Run("BenchmarkBigMap_Set", BenchmarkBigMap_Set) b.Run("BenchmarkBigOrderedMap_Set", BenchmarkBigOrderedMap_Set) b.Run("BenchmarkBigMap_Get", BenchmarkBigMap_Get) b.Run("BenchmarkBigOrderedMap_Get", BenchmarkBigOrderedMap_Get) b.Run("BenchmarkBigOrderedMap_GetElement", BenchmarkBigOrderedMap_GetElement) b.Run("BenchmarkBigOrderedMap_Iterate", BenchmarkBigOrderedMap_Iterate) b.Run("BenchmarkBigMap_Iterate", BenchmarkBigMap_Iterate) b.Run("BenchmarkBigMap_Has", BenchmarkBigMap_Has) b.Run("BenchmarkBigOrderedMap_Has", BenchmarkBigOrderedMap_Has) b.Run("BenchmarkOrderedMapString_Set", BenchmarkOrderedMapString_Set) b.Run("BenchmarkMapString_Set", BenchmarkMapString_Set) b.Run("BenchmarkOrderedMapString_Get", BenchmarkOrderedMapString_Get) b.Run("BenchmarkMapString_Get", BenchmarkMapString_Get) b.Run("BenchmarkOrderedMapString_GetElement", BenchmarkOrderedMapString_GetElement) b.Run("BenchmarkOrderedMapString_Delete", BenchmarkOrderedMapString_Delete) b.Run("BenchmarkMapString_Delete", BenchmarkMapString_Delete) b.Run("BenchmarkOrderedMapString_Iterate", BenchmarkOrderedMapString_Iterate) b.Run("BenchmarkMapString_Iterate", BenchmarkMapString_Iterate) b.Run("BenchmarkMapString_Has", BenchmarkMapString_Has) b.Run("BenchmarkOrderedMapString_Has", BenchmarkOrderedMapString_Has) b.Run("BenchmarkBigMapString_Set", BenchmarkBigMapString_Set) b.Run("BenchmarkBigOrderedMapString_Set", BenchmarkBigOrderedMapString_Set) b.Run("BenchmarkBigMapString_Get", BenchmarkBigMapString_Get) b.Run("BenchmarkBigOrderedMapString_Get", BenchmarkBigOrderedMapString_Get) b.Run("BenchmarkBigOrderedMapString_GetElement", BenchmarkBigOrderedMapString_GetElement) b.Run("BenchmarkBigOrderedMapString_Iterate", BenchmarkBigOrderedMapString_Iterate) b.Run("BenchmarkBigMapString_Iterate", BenchmarkBigMapString_Iterate) b.Run("BenchmarkBigMapString_Has", BenchmarkBigMapString_Has) b.Run("BenchmarkBigOrderedMapString_Has", BenchmarkBigOrderedMapString_Has) } orderedmap-1.8.0/v3/000077500000000000000000000000001473553416400142065ustar00rootroot00000000000000orderedmap-1.8.0/v3/go.mod000066400000000000000000000004231473553416400153130ustar00rootroot00000000000000module github.com/elliotchance/orderedmap/v3 go 1.23.0 require github.com/stretchr/testify v1.7.1 require ( github.com/davecgh/go-spew v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) orderedmap-1.8.0/v3/go.sum000066400000000000000000000020001473553416400153310ustar00rootroot00000000000000github.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.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= orderedmap-1.8.0/v3/list.go000066400000000000000000000050451473553416400155140ustar00rootroot00000000000000package orderedmap // Element is an element of a null terminated (non circular) intrusive doubly linked list that contains the key of the correspondent element in the ordered map too. type Element[K comparable, V any] struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). next, prev *Element[K, V] // The key that corresponds to this element in the ordered map. Key K // The value stored with this element. Value V } // Next returns the next list element or nil. func (e *Element[K, V]) Next() *Element[K, V] { return e.next } // Prev returns the previous list element or nil. func (e *Element[K, V]) Prev() *Element[K, V] { return e.prev } // list represents a null terminated (non circular) intrusive doubly linked list. // The list is immediately usable after instantiation without the need of a dedicated initialization. type list[K comparable, V any] struct { root Element[K, V] // list head and tail } func (l *list[K, V]) IsEmpty() bool { return l.root.next == nil } // Front returns the first element of list l or nil if the list is empty. func (l *list[K, V]) Front() *Element[K, V] { return l.root.next } // Back returns the last element of list l or nil if the list is empty. func (l *list[K, V]) Back() *Element[K, V] { return l.root.prev } // Remove removes e from its list func (l *list[K, V]) Remove(e *Element[K, V]) { if e.prev == nil { l.root.next = e.next } else { e.prev.next = e.next } if e.next == nil { l.root.prev = e.prev } else { e.next.prev = e.prev } e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks } // PushFront inserts a new element e with value v at the front of list l and returns e. func (l *list[K, V]) PushFront(key K, value V) *Element[K, V] { e := &Element[K, V]{Key: key, Value: value} if l.root.next == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.next = l.root.next l.root.next.prev = e l.root.next = e return e } // PushBack inserts a new element e with value v at the back of list l and returns e. func (l *list[K, V]) PushBack(key K, value V) *Element[K, V] { e := &Element[K, V]{Key: key, Value: value} if l.root.prev == nil { // It's the first element l.root.next = e l.root.prev = e return e } e.prev = l.root.prev l.root.prev.next = e l.root.prev = e return e } orderedmap-1.8.0/v3/orderedmap.go000066400000000000000000000121121473553416400166540ustar00rootroot00000000000000package orderedmap import "iter" type OrderedMap[K comparable, V any] struct { kv map[K]*Element[K, V] ll list[K, V] } func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V] { return &OrderedMap[K, V]{ kv: make(map[K]*Element[K, V]), } } // NewOrderedMapWithCapacity creates a map with enough pre-allocated space to // hold the specified number of elements. func NewOrderedMapWithCapacity[K comparable, V any](capacity int) *OrderedMap[K, V] { return &OrderedMap[K, V]{ kv: make(map[K]*Element[K, V], capacity), } } func NewOrderedMapWithElements[K comparable, V any](els ...*Element[K, V]) *OrderedMap[K, V] { om := NewOrderedMapWithCapacity[K, V](len(els)) for _, el := range els { om.Set(el.Key, el.Value) } return om } // 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[K, V]) Get(key K) (value V, ok bool) { v, ok := m.kv[key] if ok { value = v.Value } return } // 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[K, V]) Set(key K, value V) bool { _, alreadyExist := m.kv[key] if alreadyExist { m.kv[key].Value = value return false } element := m.ll.PushBack(key, value) m.kv[key] = element return true } // ReplaceKey replaces an existing key with a new key while preserving order of // the value. This function will return true if the operation was successful, or // false if 'originalKey' is not found OR 'newKey' already exists (which would be an overwrite). func (m *OrderedMap[K, V]) ReplaceKey(originalKey, newKey K) bool { element, originalExists := m.kv[originalKey] _, newKeyExists := m.kv[newKey] if originalExists && !newKeyExists { delete(m.kv, originalKey) m.kv[newKey] = element element.Key = newKey return true } return false } // GetOrDefault returns the value for a key. If the key does not exist, returns // the default value instead. func (m *OrderedMap[K, V]) GetOrDefault(key K, defaultValue V) V { if value, ok := m.kv[key]; ok { return value.Value } return defaultValue } // GetElement returns the element for a key. If the key does not exist, the // pointer will be nil. func (m *OrderedMap[K, V]) GetElement(key K) *Element[K, V] { element, ok := m.kv[key] if ok { return element } return nil } // Len returns the number of elements in the map. func (m *OrderedMap[K, V]) Len() int { return len(m.kv) } // AllFromFront returns an iterator that yields all elements in the map starting // at the front (oldest Set element). func (m *OrderedMap[K, V]) AllFromFront() iter.Seq2[K, V] { return func(yield func(key K, value V) bool) { for el := m.Front(); el != nil; el = el.Next() { if !yield(el.Key, el.Value) { return } } } } // AllFromBack returns an iterator that yields all elements in the map starting // at the back (most recent Set element). func (m *OrderedMap[K, V]) AllFromBack() iter.Seq2[K, V] { return func(yield func(key K, value V) bool) { for el := m.Back(); el != nil; el = el.Prev() { if !yield(el.Key, el.Value) { return } } } } // Keys returns an iterator that yields all the keys in the map starting at the // front (oldest Set element). To create a slice containing all the map keys, // use the slices.Collect function on the returned iterator. func (m *OrderedMap[K, V]) Keys() iter.Seq[K] { return func(yield func(key K) bool) { for el := m.Front(); el != nil; el = el.Next() { if !yield(el.Key) { return } } } } // Values returns an iterator that yields all the values in the map starting at // the front (oldest Set element). To create a slice containing all the map // values, use the slices.Collect function on the returned iterator. func (m *OrderedMap[K, V]) Values() iter.Seq[V] { return func(yield func(value V) bool) { for el := m.Front(); el != nil; el = el.Next() { if !yield(el.Value) { return } } } } // Delete will remove a key from the map. It will return true if the key was // removed (the key did exist). func (m *OrderedMap[K, V]) Delete(key K) (didDelete bool) { element, ok := m.kv[key] if ok { m.ll.Remove(element) delete(m.kv, key) } return ok } // Front will return the element that is the first (oldest Set element). If // there are no elements this will return nil. func (m *OrderedMap[K, V]) Front() *Element[K, V] { return m.ll.Front() } // Back will return the element that is the last (most recent Set element). If // there are no elements this will return nil. func (m *OrderedMap[K, V]) Back() *Element[K, V] { return m.ll.Back() } // Copy returns a new OrderedMap with the same elements. // Using Copy while there are concurrent writes may mangle the result. func (m *OrderedMap[K, V]) Copy() *OrderedMap[K, V] { m2 := NewOrderedMapWithCapacity[K, V](m.Len()) for el := m.Front(); el != nil; el = el.Next() { m2.Set(el.Key, el.Value) } return m2 } // Has checks if a key exists in the map. func (m *OrderedMap[K, V]) Has(key K) bool { _, exists := m.kv[key] return exists } orderedmap-1.8.0/v3/orderedmap_test.go000066400000000000000000000671051473553416400177270ustar00rootroot00000000000000package orderedmap_test import ( "slices" "strconv" "testing" "github.com/elliotchance/orderedmap/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewOrderedMap(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() assert.IsType(t, &orderedmap.OrderedMap[int, string]{}, m) } func TestGet(t *testing.T) { t.Run("ReturnsNotOKIfStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() _, ok := m.Get("foo") assert.False(t, ok) }) t.Run("ReturnsNotOKIfNonStringKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() _, ok := m.Get(123) assert.False(t, ok) }) t.Run("ReturnsOKIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") _, ok := m.Get("foo") assert.True(t, ok) }) t.Run("ReturnsValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") value, _ := m.Get("foo") assert.Equal(t, "bar", value) }) t.Run("ReturnsDynamicValueForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") value, _ := m.Get("foo") assert.Equal(t, "baz", value) }) t.Run("KeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") _, ok := m.Get("bar") assert.False(t, ok) }) t.Run("ValueForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") value, _ := m.Get("bar") assert.Empty(t, value) }) } func TestSet(t *testing.T) { t.Run("ReturnsTrueIfStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() ok := m.Set("foo", "bar") assert.True(t, ok) }) t.Run("ReturnsTrueIfNonStringKeyIsNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, string]() ok := m.Set(123, "bar") assert.True(t, ok) }) t.Run("ValueCanBeNonString", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() ok := m.Set(123, true) assert.True(t, ok) }) t.Run("ReturnsFalseIfKeyIsNotNew", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") ok := m.Set("foo", "bar") assert.False(t, ok) }) t.Run("SetThreeDifferentKeys", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Set("baz", "qux") ok := m.Set("quux", "corge") assert.True(t, ok) }) } func TestReplaceKey(t *testing.T) { t.Run("ReturnsFalseIfOriginalKeyDoesntExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.ReplaceKey("foo", "bar")) }) t.Run("ReturnsFalseIfNewKeyAlreadyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Set("baz", "qux") assert.False(t, m.ReplaceKey("foo", "baz")) assert.Equal(t, []string{"foo", "baz"}, slices.Collect(m.Keys())) }) t.Run("ReturnsTrueIfOnlyOriginalKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") assert.True(t, m.ReplaceKey("foo", "baz")) // Now validate the "replacement" was a success. el := m.GetElement("baz") require.NotNil(t, el) assert.Equal(t, "bar", el.Value) assert.Equal(t, "baz", el.Key) v, ok := m.Get("baz") assert.True(t, ok) assert.Equal(t, "bar", v) assert.Equal(t, []string{"baz"}, slices.Collect(m.Keys())) assert.Equal(t, 1, m.Len()) _, ok = m.Get("foo") // original key assert.False(t, ok) }) t.Run("KeyMaintainsOrderWhenReplaced", func(t *testing.T) { count := 100 // Build a larger map to help validate that the order is not coincidental. m := orderedmap.NewOrderedMap[int, int]() for i := 0; i < count; i++ { m.Set(i, i) } // Rename the middle 50-60 elements to 100+ current for i := 50; i < 60; i++ { assert.True(t, m.ReplaceKey(i, i+100)) } // ensure length is maintained assert.Equal(t, count, m.Len()) // Validate the order is maintained. for i, key := range slices.Collect(m.Keys()) { if i >= 50 && i < 60 { assert.Equal(t, i+100, key) } else { assert.Equal(t, i, key) } } }) } func TestLen(t *testing.T) { t.Run("EmptyMapIsZeroLen", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.Equal(t, 0, m.Len()) }) t.Run("SingleElementIsLenOne", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(123, true) assert.Equal(t, 1, m.Len()) }) t.Run("ThreeElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) m.Set(2, true) m.Set(3, true) assert.Equal(t, 3, m.Len()) }) } func TestKeys(t *testing.T) { t.Run("EmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Empty(t, slices.Collect(m.Keys())) }) t.Run("OneElement", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.Equal(t, []int{1}, slices.Collect(m.Keys())) }) t.Run("RetainsOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() for i := 1; i < 10; i++ { m.Set(i, true) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9}, slices.Collect(m.Keys())) }) t.Run("ReplacingKeyDoesntChangeOrder", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, bool]() m.Set("foo", true) m.Set("bar", true) m.Set("foo", false) assert.Equal(t, []string{"foo", "bar"}, slices.Collect(m.Keys())) }) t.Run("KeysAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, bool]() m.Set("foo", true) m.Set("bar", true) m.Delete("foo") assert.Equal(t, []string{"bar"}, slices.Collect(m.Keys())) }) } func TestDelete(t *testing.T) { t.Run("KeyDoesntExistReturnsFalse", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.Delete("foo")) }) t.Run("KeyDoesExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) assert.True(t, m.Delete("foo")) }) t.Run("KeyNoLongerExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) m.Delete("foo") _, exists := m.Get("foo") assert.False(t, exists) }) t.Run("KeyDeleteIsIsolated", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, any]() m.Set("foo", nil) m.Set("bar", nil) m.Delete("foo") _, exists := m.Get("bar") assert.True(t, exists) }) } func TestOrderedMap_Front(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Nil(t, m.Front()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.NotNil(t, m.Front()) }) } func TestOrderedMap_Back(t *testing.T) { t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() assert.Nil(t, m.Back()) }) t.Run("NilOnEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() m.Set(1, true) assert.NotNil(t, m.Back()) }) } func TestOrderedMap_Copy(t *testing.T) { t.Run("ReturnsEqualButNotSame", func(t *testing.T) { key, value := 1, "a value" m := orderedmap.NewOrderedMap[int, string]() m.Set(key, value) m2 := m.Copy() m2.Set(key, "a different value") assert.Equal(t, m.Len(), m2.Len(), "not all elements are copied") assert.Equal(t, value, m.GetElement(key).Value) }) } func TestGetElement(t *testing.T) { t.Run("ReturnsElementForKey", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") var results []any element := m.GetElement("foo") if element != nil { results = append(results, element.Key, element.Value) } assert.Equal(t, []any{"foo", "bar"}, results) }) t.Run("ElementForKeyDoesntExistOnNonEmptyMap", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "baz") element := m.GetElement("bar") assert.Nil(t, element) }) } func TestSetAndGet(t *testing.T) { t.Run("FourBoolElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() expected := map[int]bool{1: true, 3: false, 5: false, 4: true} for k, v := range expected { m.Set(k, v) } for k, v := range expected { w, ok := m.Get(k) assert.True(t, ok) assert.Equal(t, v, w) } }) } func TestIterations(t *testing.T) { type Element struct { Key int Value bool } t.Run("FourBoolElements", func(t *testing.T) { m := orderedmap.NewOrderedMap[int, bool]() expected := []Element{{5, true}, {3, false}, {1, false}, {4, true}} for _, v := range expected { m.Set(v.Key, v.Value) } element := m.Front() for i := 0; i < len(expected); i++ { assert.NotNil(t, element) assert.Equal(t, expected[i].Key, element.Key) assert.Equal(t, expected[i].Value, element.Value) element = element.Next() } assert.Nil(t, element) }) } func TestIterators(t *testing.T) { type Element struct { Key int Value bool } m := orderedmap.NewOrderedMap[int, bool]() expected := []Element{{5, true}, {3, false}, {1, false}, {4, true}} for _, v := range expected { m.Set(v.Key, v.Value) } t.Run("Iterator", func(t *testing.T) { i := 0 for key, value := range m.AllFromFront() { assert.Equal(t, expected[i].Key, key) assert.Equal(t, expected[i].Value, value) i++ } }) t.Run("ReverseIterator", func(t *testing.T) { i := len(expected) - 1 for key, value := range m.AllFromBack() { assert.Equal(t, expected[i].Key, key) assert.Equal(t, expected[i].Value, value) i-- } }) } func TestOrderedMap_Has(t *testing.T) { t.Run("ReturnsFalseIfKeyDoesNotExist", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() assert.False(t, m.Has("foo")) }) t.Run("ReturnsTrueIfKeyExists", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") assert.True(t, m.Has("foo")) }) t.Run("KeyDoesNotExistAfterDelete", func(t *testing.T) { m := orderedmap.NewOrderedMap[string, string]() m.Set("foo", "bar") m.Delete("foo") assert.False(t, m.Has("foo")) }) } func benchmarkMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } } } func BenchmarkMap_Set(b *testing.B) { benchmarkMap_Set(1)(b) } func benchmarkOrderedMap_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } } } func BenchmarkOrderedMap_Set(b *testing.B) { benchmarkOrderedMap_Set(1)(b) } func benchmarkMap_Get(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Get(b *testing.B) { benchmarkMap_Get(1)(b) } func benchmarkOrderedMap_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Get(b *testing.B) { benchmarkOrderedMap_Get(1)(b) } func benchmarkOrderedMap_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_GetElement(b *testing.B) { benchmarkOrderedMap_GetElement(1)(b) } var tempInt int func benchmarkOrderedMap_Len(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { var temp int for i := 0; i < b.N; i++ { temp = m.Len() } // prevent compiler from optimising Len away. tempInt = temp } } func BenchmarkOrderedMap_Len(b *testing.B) { benchmarkOrderedMap_Len(1)(b) } func benchmarkMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[int]bool) for i := 0; i < b.N*multiplier; i++ { m[i] = true } for i := 0; i < b.N; i++ { delete(m, i) } } } func BenchmarkMap_Delete(b *testing.B) { benchmarkMap_Delete(1)(b) } func benchmarkOrderedMap_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < b.N*multiplier; i++ { m.Set(i, true) } for i := 0; i < b.N; i++ { m.Delete(i) } } } func BenchmarkOrderedMap_Delete(b *testing.B) { benchmarkOrderedMap_Delete(1)(b) } func benchmarkMap_Iterate(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMap_Iterate(b *testing.B) { benchmarkMap_Iterate(1)(b) } func benchmarkOrderedMap_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range slices.Collect(m.Keys()) { _, v := m.Get(key) nothing(v) } } } } func BenchmarkOrderedMap_Iterate(b *testing.B) { benchmarkOrderedMap_Iterate(1)(b) } func benchmarkMap_Has(multiplier int) func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 1000*multiplier; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[i%1000*multiplier] } } } func BenchmarkMap_Has(b *testing.B) { benchmarkMap_Has(1)(b) } func benchmarkOrderedMap_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 1000*multiplier; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(i % 1000 * multiplier) } } } func BenchmarkOrderedMap_Has(b *testing.B) { benchmarkOrderedMap_Has(1)(b) } func benchmarkMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } } } func BenchmarkMapString_Set(b *testing.B) { benchmarkMapString_Set(1)(b) } func benchmarkOrderedMapString_Set(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } } } func BenchmarkOrderedMapString_Set(b *testing.B) { benchmarkOrderedMapString_Set(1)(b) } func benchmarkMapString_Get(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Get(b *testing.B) { benchmarkMapString_Get(1)(b) } func benchmarkOrderedMapString_Get(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Get(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Get(b *testing.B) { benchmarkOrderedMapString_Get(1)(b) } func benchmarkOrderedMapString_GetElement(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.GetElement(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_GetElement(b *testing.B) { benchmarkOrderedMapString_GetElement(1)(b) } func benchmarkMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < b.N*multiplier; i++ { m[a+strconv.Itoa(i)] = true } for i := 0; i < b.N; i++ { delete(m, a+strconv.Itoa(i)) } } } func BenchmarkMapString_Delete(b *testing.B) { benchmarkMapString_Delete(1)(b) } func benchmarkOrderedMapString_Delete(multiplier int) func(b *testing.B) { return func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < b.N*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } for i := 0; i < b.N; i++ { m.Delete(a + strconv.Itoa(i)) } } } func BenchmarkOrderedMapString_Delete(b *testing.B) { benchmarkOrderedMapString_Delete(1)(b) } func benchmarkMapString_Iterate(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkMapString_Iterate(b *testing.B) { benchmarkMapString_Iterate(1)(b) } func benchmarkOrderedMapString_Iterate(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range slices.Collect(m.Keys()) { _, v := m.Get(key) nothing(v) } } } } func BenchmarkOrderedMapString_Iterate(b *testing.B) { benchmarkOrderedMapString_Iterate(1)(b) } func benchmarkMapString_Has(multiplier int) func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 1000*multiplier; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { _ = m[a+strconv.Itoa(i%1000*multiplier)] } } } func BenchmarkMapString_Has(b *testing.B) { benchmarkMapString_Has(1)(b) } func benchmarkOrderedMapString_Has(multiplier int) func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 1000*multiplier; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { m.Has(a + strconv.Itoa(i%1000*multiplier)) } } } func BenchmarkOrderedMapString_Has(b *testing.B) { benchmarkOrderedMapString_Has(1)(b) } func nothing(v interface{}) { v = false } func benchmarkBigMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } } } } func BenchmarkBigMap_Set(b *testing.B) { benchmarkBigMap_Set()(b) } func benchmarkBigOrderedMap_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigOrderedMap_Set(b *testing.B) { benchmarkBigOrderedMap_Set()(b) } func benchmarkBigMapWithCapacity_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMapWithCapacity[int, bool](10000000) for i := 0; i < 10000000; i++ { m.Set(i, true) } } } } func BenchmarkBigMapWithCapacity_Set(b *testing.B) { benchmarkBigMapWithCapacity_Set()(b) } func benchmarkBigMap_Get() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Get(b *testing.B) { benchmarkBigMap_Get()(b) } func benchmarkBigOrderedMap_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(i) } } } } func BenchmarkBigOrderedMap_Get(b *testing.B) { benchmarkBigOrderedMap_Get()(b) } func benchmarkBigOrderedMap_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(i) } } } } func BenchmarkBigOrderedMap_GetElement(b *testing.B) { benchmarkBigOrderedMap_GetElement()(b) } func benchmarkBigMap_Iterate() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMap_Iterate(b *testing.B) { benchmarkBigMap_Iterate()(b) } func benchmarkBigOrderedMap_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range slices.Collect(m.Keys()) { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMap_Iterate(b *testing.B) { benchmarkBigOrderedMap_Iterate()(b) } func benchmarkBigMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } } } } func benchmarkBigMap_Has() func(b *testing.B) { m := make(map[int]bool) for i := 0; i < 10000000; i++ { m[i] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[i] } } } } func BenchmarkBigMap_Has(b *testing.B) { benchmarkBigMap_Has()(b) } func benchmarkBigOrderedMap_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap[int, bool]() for i := 0; i < 10000000; i++ { m.Set(i, true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(i) } } } } func BenchmarkBigOrderedMap_Has(b *testing.B) { benchmarkBigOrderedMap_Has()(b) } func BenchmarkBigMapString_Set(b *testing.B) { benchmarkBigMapString_Set()(b) } func benchmarkBigOrderedMapString_Set() func(b *testing.B) { return func(b *testing.B) { for j := 0; j < b.N; j++ { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } } } } func BenchmarkBigOrderedMapString_Set(b *testing.B) { benchmarkBigOrderedMapString_Set()(b) } func benchmarkBigMapString_Get() func(b *testing.B) { m := make(map[string]bool) a := "1234567" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Get(b *testing.B) { benchmarkBigMapString_Get()(b) } func benchmarkBigOrderedMapString_Get() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Get(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_Get(b *testing.B) { benchmarkBigOrderedMapString_Get()(b) } func benchmarkBigOrderedMapString_GetElement() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "1234567" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.GetElement(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_GetElement(b *testing.B) { benchmarkBigOrderedMapString_GetElement()(b) } func benchmarkBigMapString_Iterate() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, v := range m { nothing(v) } } } } func BenchmarkBigMapString_Iterate(b *testing.B) { benchmarkBigMapString_Iterate()(b) } func benchmarkBigOrderedMapString_Iterate() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range slices.Collect(m.Keys()) { _, v := m.Get(key) nothing(v) } } } } func BenchmarkBigOrderedMapString_Iterate(b *testing.B) { benchmarkBigOrderedMapString_Iterate()(b) } func benchmarkBigMapString_Has() func(b *testing.B) { m := make(map[string]bool) a := "12345678" for i := 0; i < 10000000; i++ { m[a+strconv.Itoa(i)] = true } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { _ = m[a+strconv.Itoa(i)] } } } } func BenchmarkBigMapString_Has(b *testing.B) { benchmarkBigMapString_Has()(b) } func benchmarkBigOrderedMapString_Has() func(b *testing.B) { m := orderedmap.NewOrderedMap[string, bool]() a := "12345678" for i := 0; i < 10000000; i++ { m.Set(a+strconv.Itoa(i), true) } return func(b *testing.B) { for j := 0; j < b.N; j++ { for i := 0; i < 10000000; i++ { m.Has(a + strconv.Itoa(i)) } } } } func BenchmarkBigOrderedMapString_Has(b *testing.B) { benchmarkBigOrderedMapString_Has()(b) } func BenchmarkAll(b *testing.B) { b.Run("BenchmarkOrderedMap_Set", BenchmarkOrderedMap_Set) b.Run("BenchmarkMap_Set", BenchmarkMap_Set) b.Run("BenchmarkOrderedMap_Get", BenchmarkOrderedMap_Get) b.Run("BenchmarkMap_Get", BenchmarkMap_Get) b.Run("BenchmarkOrderedMap_GetElement", BenchmarkOrderedMap_GetElement) b.Run("BenchmarkOrderedMap_Delete", BenchmarkOrderedMap_Delete) b.Run("BenchmarkMap_Delete", BenchmarkMap_Delete) b.Run("BenchmarkOrderedMap_Iterate", BenchmarkOrderedMap_Iterate) b.Run("BenchmarkMap_Iterate", BenchmarkMap_Iterate) b.Run("BenchmarkOrderedMap_Has", BenchmarkOrderedMap_Has) b.Run("BenchmarkMap_Has", BenchmarkMap_Has) b.Run("BenchmarkBigMap_Set", BenchmarkBigMap_Set) b.Run("BenchmarkBigOrderedMap_Set", BenchmarkBigOrderedMap_Set) b.Run("BenchmarkBigMap_Get", BenchmarkBigMap_Get) b.Run("BenchmarkBigOrderedMap_Get", BenchmarkBigOrderedMap_Get) b.Run("BenchmarkBigOrderedMap_GetElement", BenchmarkBigOrderedMap_GetElement) b.Run("BenchmarkBigOrderedMap_Iterate", BenchmarkBigOrderedMap_Iterate) b.Run("BenchmarkBigMap_Iterate", BenchmarkBigMap_Iterate) b.Run("BenchmarkBigMap_Has", BenchmarkBigMap_Has) b.Run("BenchmarkBigOrderedMap_Has", BenchmarkBigOrderedMap_Has) b.Run("BenchmarkOrderedMapString_Set", BenchmarkOrderedMapString_Set) b.Run("BenchmarkMapString_Set", BenchmarkMapString_Set) b.Run("BenchmarkOrderedMapString_Get", BenchmarkOrderedMapString_Get) b.Run("BenchmarkMapString_Get", BenchmarkMapString_Get) b.Run("BenchmarkOrderedMapString_GetElement", BenchmarkOrderedMapString_GetElement) b.Run("BenchmarkOrderedMapString_Delete", BenchmarkOrderedMapString_Delete) b.Run("BenchmarkMapString_Delete", BenchmarkMapString_Delete) b.Run("BenchmarkOrderedMapString_Iterate", BenchmarkOrderedMapString_Iterate) b.Run("BenchmarkMapString_Iterate", BenchmarkMapString_Iterate) b.Run("BenchmarkMapString_Has", BenchmarkMapString_Has) b.Run("BenchmarkOrderedMapString_Has", BenchmarkOrderedMapString_Has) b.Run("BenchmarkBigMapString_Set", BenchmarkBigMapString_Set) b.Run("BenchmarkBigOrderedMapString_Set", BenchmarkBigOrderedMapString_Set) b.Run("BenchmarkBigMapString_Get", BenchmarkBigMapString_Get) b.Run("BenchmarkBigOrderedMapString_Get", BenchmarkBigOrderedMapString_Get) b.Run("BenchmarkBigOrderedMapString_GetElement", BenchmarkBigOrderedMapString_GetElement) b.Run("BenchmarkBigOrderedMapString_Iterate", BenchmarkBigOrderedMapString_Iterate) b.Run("BenchmarkBigMapString_Iterate", BenchmarkBigMapString_Iterate) b.Run("BenchmarkBigMapString_Has", BenchmarkBigMapString_Has) b.Run("BenchmarkBigOrderedMapString_Has", BenchmarkBigOrderedMapString_Has) }