Implemented basic sparse array.

This commit is contained in:
Andrey Parhomenko 2023-02-17 18:08:25 +05:00
parent 28536eb2e0
commit eddf2c345c
4 changed files with 122 additions and 0 deletions

2
go.mod
View file

@ -1,3 +1,5 @@
module github.com/surdeus/godat
go 1.19
require golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect

2
go.sum Normal file
View file

@ -0,0 +1,2 @@
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w=
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=

23
src/cmd/sparse/main.go Normal file
View file

@ -0,0 +1,23 @@
package main
import (
"github.com/surdeus/godat/src/sparsex"
"fmt"
)
func main() {
unord := sparsex.New[int, string](true)
unord.Set(1, "suck")
unord.Set(-5, "cock")
unord.Set(-4, "die")
unord.Set(-1000, "withme")
for v := range unord.Vals() {
fmt.Println(v.K, v.V)
}
unord.Sort()
for v := range unord.Vals() {
fmt.Println(v.K, v.V)
}
}

95
src/sparsex/main.go Normal file
View file

@ -0,0 +1,95 @@
package sparsex
import (
"sort"
cons "golang.org/x/exp/constraints"
)
// The package implements a simple ordered map.
// In fact can be used as a sparse array so it is
// where the name comes from.
type Pair[K cons.Ordered, V any] struct {
K K
V V
}
type Sparse[K cons.Ordered, V any] struct {
store map[K] V
keys []K
shouldSort bool
}
// Returns new sparse array
func New[K cons.Ordered, V any](s bool) *Sparse[K, V] {
return &Sparse[K, V]{
store: make(map[K] V),
keys: []K{},
shouldSort: s,
}
}
func (s *Sparse[K, V]) Get(key K) (V, bool) {
val, ok := s.store[key]
return val, ok
}
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
}
func (s Sparse[K, V]) Del(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()
}
}
}
func (s *Sparse[K, V]) Vals(
) chan Pair[K, V] {
keys := s.keys
store := s.store
ret := make(chan Pair[K, V])
go func() {
for _, v := range keys {
ret <- Pair[K, V]{
v, store[v],
}
}
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]
})
}