ordered.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package mapx contains extra map types and functions.
  4. package mapx
  5. import (
  6. "iter"
  7. "slices"
  8. )
  9. // OrderedMap is a map that maintains the order of its keys.
  10. //
  11. // It is meant for maps that only grow or that are small;
  12. // is it not optimized for deleting keys.
  13. //
  14. // The zero value is ready to use.
  15. //
  16. // Locking-wise, it has the same rules as a regular Go map:
  17. // concurrent reads are safe, but not writes.
  18. type OrderedMap[K comparable, V any] struct {
  19. // m is the underlying map.
  20. m map[K]V
  21. // keys is the order of keys in the map.
  22. keys []K
  23. }
  24. func (m *OrderedMap[K, V]) init() {
  25. if m.m == nil {
  26. m.m = make(map[K]V)
  27. }
  28. }
  29. // Set sets the value for the given key in the map.
  30. //
  31. // If the key already exists, it updates the value and keeps the order.
  32. func (m *OrderedMap[K, V]) Set(key K, value V) {
  33. m.init()
  34. len0 := len(m.keys)
  35. m.m[key] = value
  36. if len(m.m) > len0 {
  37. // New key (not an update)
  38. m.keys = append(m.keys, key)
  39. }
  40. }
  41. // Get returns the value for the given key in the map.
  42. // If the key does not exist, it returns the zero value for V.
  43. func (m *OrderedMap[K, V]) Get(key K) V {
  44. return m.m[key]
  45. }
  46. // GetOk returns the value for the given key in the map
  47. // and whether it was present in the map.
  48. func (m *OrderedMap[K, V]) GetOk(key K) (_ V, ok bool) {
  49. v, ok := m.m[key]
  50. return v, ok
  51. }
  52. // Contains reports whether the map contains the given key.
  53. func (m *OrderedMap[K, V]) Contains(key K) bool {
  54. _, ok := m.m[key]
  55. return ok
  56. }
  57. // Delete removes the key from the map.
  58. //
  59. // The cost is O(n) in the number of keys in the map.
  60. func (m *OrderedMap[K, V]) Delete(key K) {
  61. len0 := len(m.m)
  62. delete(m.m, key)
  63. if len(m.m) == len0 {
  64. // Wasn't present; no need to adjust keys.
  65. return
  66. }
  67. was := m.keys
  68. m.keys = m.keys[:0]
  69. for _, k := range was {
  70. if k != key {
  71. m.keys = append(m.keys, k)
  72. }
  73. }
  74. }
  75. // All yields all the keys and values, in the order they were inserted.
  76. func (m *OrderedMap[K, V]) All() iter.Seq2[K, V] {
  77. return func(yield func(K, V) bool) {
  78. for _, k := range m.keys {
  79. if !yield(k, m.m[k]) {
  80. return
  81. }
  82. }
  83. }
  84. }
  85. // Keys yields the map keys, in the order they were inserted.
  86. func (m *OrderedMap[K, V]) Keys() iter.Seq[K] {
  87. return slices.Values(m.keys)
  88. }
  89. // Values yields the map values, in the order they were inserted.
  90. func (m *OrderedMap[K, V]) Values() iter.Seq[V] {
  91. return func(yield func(V) bool) {
  92. for _, k := range m.keys {
  93. if !yield(m.m[k]) {
  94. return
  95. }
  96. }
  97. }
  98. }