97 lines
1.6 KiB
Go
97 lines
1.6 KiB
Go
package sparsex
|
|
|
|
import (
|
|
"sort"
|
|
cons "golang.org/x/exp/constraints"
|
|
"github.com/mojosa-software/godat/src/iterx"
|
|
)
|
|
|
|
// The package implements a simple ordered map.
|
|
// In fact can be used as a sparse array so it is
|
|
// where the name comes from.
|
|
|
|
// The sparse array type.
|
|
type Sparse[K cons.Ordered, V any] struct {
|
|
store map[K] V
|
|
keys []K
|
|
shouldSort bool
|
|
}
|
|
|
|
// Returns new sparse array.
|
|
// If shouldSort == true then it will sort the array on
|
|
// each change.
|
|
func New[K cons.Ordered, V any]() *Sparse[K, V] {
|
|
return &Sparse[K, V]{
|
|
store: make(map[K] V),
|
|
keys: []K{},
|
|
}
|
|
}
|
|
|
|
// Get the value by the key.
|
|
func (s *Sparse[K, V]) Get(key K) (V, bool) {
|
|
val, ok := s.store[key]
|
|
return val, ok
|
|
}
|
|
|
|
// Set the value to the key.
|
|
func (s *Sparse[K, V]) Set(k K, v V) {
|
|
_, ok := s.store[k]
|
|
if !ok {
|
|
s.keys = append(s.keys, k)
|
|
if s.shouldSort {
|
|
s.Sort()
|
|
}
|
|
}
|
|
|
|
s.store[k] = v
|
|
}
|
|
|
|
// Delete the value by the key.
|
|
func (s Sparse[K, V]) Delete(k K) {
|
|
delete(s.store, k)
|
|
|
|
// To know if the loop was run.
|
|
idx := -1
|
|
|
|
for i, v := range s.keys {
|
|
if v == k {
|
|
idx = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if idx != -1 {
|
|
s.keys = append(s.keys[:idx], s.keys[idx+1:]...)
|
|
if s.shouldSort {
|
|
s.Sort()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns channel of pairs.
|
|
func (s *Sparse[K, V]) Chan(
|
|
) iterx.PairChan[K, V] {
|
|
keys := s.keys
|
|
store := s.store
|
|
ret := make(iterx.PairChan[K, V])
|
|
|
|
go func() {
|
|
for _, k := range keys {
|
|
ret <- iterx.Pair[K, V]{
|
|
K: k,
|
|
V: store[k],
|
|
}
|
|
}
|
|
close(ret)
|
|
}()
|
|
|
|
return ret
|
|
}
|
|
|
|
// Sort the keys.
|
|
func (s *Sparse[K, V]) Sort() {
|
|
sort.Slice(s.keys, func(i, j int) bool {
|
|
return s.keys[i] < s.keys[j]
|
|
})
|
|
}
|
|
|