gods/sparsex/main.go

98 lines
1.6 KiB
Go
Raw Normal View History

2023-02-17 16:08:25 +03:00
package sparsex
import (
"sort"
cons "golang.org/x/exp/constraints"
2023-07-21 19:00:09 +03:00
"github.com/mojosa-software/godat/src/iterx"
2023-02-17 16:08:25 +03:00
)
// The package implements a simple ordered map.
// In fact can be used as a sparse array so it is
// where the name comes from.
2023-07-21 19:00:09 +03:00
// The sparse array type.
2023-02-17 16:08:25 +03:00
type Sparse[K cons.Ordered, V any] struct {
store map[K] V
keys []K
shouldSort bool
}
2023-07-21 19:00:09 +03:00
// Returns new sparse array.
// If shouldSort == true then it will sort the array on
// each change.
2023-08-27 15:33:44 +03:00
func New[K cons.Ordered, V any]() *Sparse[K, V] {
2023-02-17 16:08:25 +03:00
return &Sparse[K, V]{
store: make(map[K] V),
keys: []K{},
}
}
2023-07-21 19:00:09 +03:00
// Get the value by the key.
2023-02-17 16:08:25 +03:00
func (s *Sparse[K, V]) Get(key K) (V, bool) {
val, ok := s.store[key]
return val, ok
}
2023-07-21 19:00:09 +03:00
// Set the value to the key.
2023-02-17 16:08:25 +03:00
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
}
2023-07-21 19:00:09 +03:00
// Delete the value by the key.
2023-07-22 01:45:24 +03:00
func (s Sparse[K, V]) Delete(k K) {
2023-02-17 16:08:25 +03:00
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()
}
}
}
2023-07-21 19:00:09 +03:00
// Returns channel of pairs.
func (s *Sparse[K, V]) Chan(
) iterx.PairChan[K, V] {
2023-02-17 16:08:25 +03:00
keys := s.keys
store := s.store
2023-07-21 19:00:09 +03:00
ret := make(iterx.PairChan[K, V])
2023-02-17 16:08:25 +03:00
go func() {
2023-07-21 19:00:09 +03:00
for _, k := range keys {
ret <- iterx.Pair[K, V]{
K: k,
V: store[k],
2023-02-17 16:08:25 +03:00
}
}
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]
})
}