sparse.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package maps
  2. import (
  3. "slices"
  4. "cmp"
  5. "fmt"
  6. )
  7. // The package implements sparse array structure.
  8. // You can make sparse matrices by assigning
  9. // the value type to another sparse array.
  10. // The sparse array type.
  11. // Does not sort by default on setting so by
  12. // default is not ordered for the Chan, Keys, KeyChan, Slice methods.
  13. // Its made for the optimization sakes because
  14. // initially the package was made for the gox (2D game engine) package use
  15. // to provide dynamic layering.
  16. // See *Sparse[K, V].ShouldSort method to change it.
  17. type mSparse[K cmp.Ordered, V any] struct {
  18. store map[K] V
  19. def V
  20. keys []K
  21. }
  22. // Return the new with the default implementation storing the values from the
  23. // map inside the structure. Is fast on creation and reading, but
  24. // slow on inserting and deleting. Takes only one or zero maps as input.
  25. // Panics otherwise.
  26. func NewSparse[K cmp.Ordered, V any](
  27. defval V,
  28. values ...map[K] V,
  29. ) Map[K, V] {
  30. var (
  31. store map[K] V
  32. keys []K
  33. vs map[K] V
  34. )
  35. if len(values) > 1 {
  36. panic("too many arguments")
  37. } else if len(values) == 1 {
  38. vs = values[0]
  39. }
  40. if vs == nil {
  41. store = map[K] V{}
  42. keys = []K{}
  43. } else {
  44. store = make(map[K] V, len(vs))
  45. keys = make([]K, len(vs))
  46. i := 0
  47. for k, v := range vs {
  48. keys[i] = k
  49. store[k] = v
  50. i++
  51. }
  52. slices.Sort(keys)
  53. }
  54. ret := &mSparse[K, V]{
  55. store: store,
  56. def: defval,
  57. keys: keys,
  58. }
  59. return ret
  60. }
  61. func (s *mSparse[K, V]) Size() int {
  62. return len(s.keys)
  63. }
  64. func (s *mSparse[K, V]) Clear() {
  65. s.store = map[K]V{}
  66. s.keys = []K{}
  67. }
  68. func (s *mSparse[K, V]) Has(key K) bool {
  69. _, ok := s.store[key]
  70. return ok
  71. }
  72. func (s *mSparse[K, V]) Get(key K) (V) {
  73. val, ok := s.store[key]
  74. if !ok {
  75. val = s.def
  76. }
  77. return val
  78. }
  79. func (s *mSparse[K, V]) Got(key K) (V, bool) {
  80. v, ok := s.store[key]
  81. if !ok {
  82. v = s.def
  83. }
  84. return v, ok
  85. }
  86. func (s *mSparse[K, V]) Set(k K, v V) {
  87. _, ok := s.store[k]
  88. if !ok {
  89. s.keys = append(s.keys, k)
  90. s.sort()
  91. }
  92. s.store[k] = v
  93. }
  94. func (s *mSparse[K, V]) Empty() bool {
  95. return len(s.keys) == 0
  96. }
  97. func (s *mSparse[K, V]) Del(k K) {
  98. delete(s.store, k)
  99. // To know if the loop was run.
  100. idx := -1
  101. for i, v := range s.keys {
  102. if v == k {
  103. idx = i
  104. break
  105. }
  106. }
  107. if idx != -1 {
  108. // Removing the key.
  109. s.keys = append(s.keys[:idx], s.keys[idx+1:]...)
  110. }
  111. }
  112. func (s *mSparse[K, V]) Chan(
  113. ) chan V {
  114. keys := s.keys
  115. store := s.store
  116. ret := make(chan V)
  117. go func() {
  118. for _, k := range keys {
  119. ret <- store[k]
  120. }
  121. close(ret)
  122. }()
  123. return ret
  124. }
  125. func (s *mSparse[K, V]) KeyChan() chan K {
  126. ret := make(chan K)
  127. go func() {
  128. for _, k := range s.keys {
  129. ret <- k
  130. }
  131. close(ret)
  132. }()
  133. return ret
  134. }
  135. func (s *mSparse[K, V]) Keys() []K {
  136. return s.keys
  137. }
  138. func (s *mSparse[K, V]) Values() []V {
  139. ret := []V{}
  140. for v := range s.Chan() {
  141. ret = append(ret, v)
  142. }
  143. return ret
  144. }
  145. func (s *mSparse[K, V]) String() string {
  146. return fmt.Sprintf("%#v", s.store)
  147. }
  148. func (s *mSparse[K, V]) sort() {
  149. slices.Sort(s.keys)
  150. }