Move sparse to the maps.

This commit is contained in:
Andrey Parhomenko 2023-10-28 14:26:50 +03:00
parent c0031a3f71
commit 1c5fcf1da1
13 changed files with 386 additions and 304 deletions

View file

@ -1,12 +1,12 @@
package main
import (
"github.com/reklesio/gods/sparses"
"github.com/reklesio/gods/maps"
"fmt"
)
func main() {
arr := sparses.New[float32, string]("default", map[float32] string {
arr := maps.NewSparse[float32, string]("default", map[float32] string {
5: "something at 5",
12: "new shit 12",
50: "die 50",

144
maps/main.go Normal file
View file

@ -0,0 +1,144 @@
package maps
import (
"fmt"
"github.com/reklesio/gods"
)
// Generic map interface for all the maps.
type Map[K comparable, V any] interface {
gods.Container[V]
// Returns if the map has the key set.
Has(K) bool
// Get the value and if the key is not set panic.
Get(K) V
// The Go way to get values without panicing.
Got(K) (V, bool)
// Set the value or reset if it is already set.
Set(K, V)
// Delete the key no matter it exists or not.
Del(K)
// Returns slice of values.
// For the order look the comment
// for "Keys()".
Values() []V
// Get the values channel.
Chan() chan V
// Returns slice of keys.
// Order is not guaranteed if
// the is not specified otherwise
// like for the NewOrdered.
Keys() []K
KeyChan() chan K
// The function to range over the values
// with the keys.
/*Range() chan struct{
K K
V V
}*/
}
type lMap[K comparable, V any] struct {
store map[K] V
}
// Returns new basic map with the builtin Go type down there.
// Has all the features of the builtin Go maps and same performance.
func New[K comparable, V any]() Map[K, V] {
ret := &lMap[K, V]{}
ret.store = map[K]V{}
return ret
}
func (m *lMap[K, V]) Clear() {
m.store = map[K]V{}
}
func (m *lMap[K, V]) Keys() []K {
r := make([]K, len(m.store))
i := 0
for k := range m.store {
r[i] = k
i++
}
return r
}
func (m *lMap[K, V]) Empty() bool {
return len(m.store) == 0
}
func (m *lMap[K, V]) Del(key K) {
delete(m.store, key)
}
func (m *lMap[K, V]) Values() []V {
r := make([]V, len(m.store))
i := 0
for _, v := range m.store {
r[i] = v
i++
}
return r
}
func (m *lMap[K, V]) Chan() chan V {
ret := make(chan V)
go func() {
for _, v := range m.store {
ret <- v
}
close(ret)
}()
return ret
}
func (m *lMap[K, V]) Has(k K) bool {
_, ok := m.store[k]
return ok
}
func (m *lMap[K, V]) Set(k K, v V) {
m.store[k] = v
}
func (m *lMap[K, V]) Get(key K) V {
v, ok := m.store[key]
if !ok {
panic(fmt.Sprintf("there is no such key '%v'", key))
}
return v
}
func (m *lMap[K, V]) Got(key K) (V, bool) {
v, ok := m.store[key]
return v, ok
}
func (m *lMap[K, V]) Size() int {
return len(m.store)
}
func (m *lMap[K, V]) KeyChan() chan K {
ret := make(chan K)
go func() {
for k := range m.store {
ret <- k
}
close(ret)
}()
return ret
}

View file

@ -1,4 +1,4 @@
package mapx
package maps
func Reversed[K, V comparable](m map[K] V) map[V] K {
r := make(map[V] K)

103
maps/ordered.go Normal file
View file

@ -0,0 +1,103 @@
package maps
// The type makes the underlying map ordered,
// so every time you pass through all the values
// they will be in the same order.
type orderedMap[K comparable, V any] struct {
store map[K] V
keys []K
}
// Returns the new empty ordered map.
func NewOrdered[K comparable, V any]() Map[K, V] {
return &orderedMap[K, V]{
store: make(map[K] V),
}
}
func (m *orderedMap[K, V]) Clear() {
m.store = map[K]V{}
m.keys = []K{}
}
func (m *orderedMap[K, V]) Set(k K, v V) {
_, ok := m.store[k]
if !ok {
m.keys = append(m.keys, k)
}
m.store[k] = v
}
func (m *orderedMap[K, V]) Got(key K) (V, bool) {
v, ok := m.store[key]
return v, ok
}
func (m *orderedMap[K, V]) Has(k K) bool {
_, ok := m.store[k]
return ok
}
// Get the value from the map.
func (m *orderedMap[K, V]) Get(k K) (V) {
v := m.store[k]
return v
}
func (m *orderedMap[K, V]) Del(k K) {
delete(m.store, k)
for i, v := range m.keys {
if v == k {
m.keys = append(m.keys[:i], m.keys[i+1:]...)
}
}
}
// Get map keys slice.
func (m *orderedMap[K, V]) Keys() []K {
return m.keys
}
func (m *orderedMap[K, V]) Values() []V {
ret := make([]V, len(m.keys))
i := 0
for _, k := range m.keys {
ret[i] = m.store[k]
i++
}
return ret
}
func (m *orderedMap[K, V]) KeyChan() chan K {
chn := make(chan K)
go func() {
for _, v := range m.keys {
chn <- v
}
close(chn)
}()
return chn
}
// Return channel of ordered values.
func (m *orderedMap[K, V]) Chan() chan V {
chn := make(chan V)
go func(){
for _, k := range m.keys {
chn <- m.Get(k)
}
close(chn)
}()
return chn
}
func (m *orderedMap[K, V]) Empty() bool {
return len(m.keys) == 0
}
func (m *orderedMap[K, V]) Size() int {
return len(m.keys)
}

View file

@ -1,4 +1,4 @@
package sparses
package maps
import (
"slices"
@ -27,10 +27,10 @@ type mSparse[K cmp.Ordered, V any] struct {
// map inside the structure. Is fast on creation and reading, but
// slow on inserting and deleting. Takes only one or zero maps as input.
// Panics otherwise.
func New[K cmp.Ordered, V any](
func NewSparse[K cmp.Ordered, V any](
defval V,
values ...map[K] V,
) Sparse[K, V] {
) Map[K, V] {
var (
store map[K] V
@ -81,10 +81,6 @@ func (s *mSparse[K, V]) Has(key K) bool {
return ok
}
// Get the value by the key. The secound value
// represents whether the array contains the value.
// If the array does not contain the value then default one
// will be returned.
func (s *mSparse[K, V]) Get(key K) (V) {
val, ok := s.store[key]
if !ok {
@ -93,6 +89,14 @@ func (s *mSparse[K, V]) Get(key K) (V) {
return val
}
func (s *mSparse[K, V]) Got(key K) (V, bool) {
v, ok := s.store[key]
if !ok {
v = s.def
}
return v, ok
}
func (s *mSparse[K, V]) Set(k K, v V) {
_, ok := s.store[k]
if !ok {
@ -107,7 +111,6 @@ func (s *mSparse[K, V]) Empty() bool {
return len(s.keys) == 0
}
// Delete the value by the key.
func (s *mSparse[K, V]) Del(k K) {
delete(s.store, k)
@ -122,11 +125,11 @@ func (s *mSparse[K, V]) Del(k K) {
}
if idx != -1 {
// Removing the key.
s.keys = append(s.keys[:idx], s.keys[idx+1:]...)
}
}
// Returns channel of pairs.
func (s *mSparse[K, V]) Chan(
) chan V {
keys := s.keys
@ -143,6 +146,17 @@ func (s *mSparse[K, V]) Chan(
return ret
}
func (s *mSparse[K, V]) KeyChan() chan K {
ret := make(chan K)
go func() {
for _, k := range s.keys {
ret <- k
}
close(ret)
}()
return ret
}
func (s *mSparse[K, V]) Keys() []K {
return s.keys
}

113
maps/uniq.go Normal file
View file

@ -0,0 +1,113 @@
package maps
// The type describing unique map
// where you can quickly get both
// value by key and vice versa.
type Uniq[K, V comparable] interface {
Map[K, V]
GetByValue(V) K
}
type uniqMap[K, V comparable] struct {
store map[K] V
rstore map[V] K
}
// The function returns map type where
// you can get, set and delete by value
// since it store everything as ONLY entity
// both for keys and values way.
// Use only when you do not care about the order.
func NewUniq[K, V comparable]() Uniq[K, V] {
return &uniqMap[K, V]{
map[K] V{},
map[V] K{},
}
}
func (m *uniqMap[K, V]) Empty() bool {
return len(m.store) == 0
}
func (m *uniqMap[K, V]) Clear() {
m.store = map[K] V{}
m.rstore = map[V] K{}
}
func (m *uniqMap[K, V]) Has(k K) bool {
_, ok := m.store[k]
return ok
}
func (m *uniqMap[K, V]) Set(k K, v V) {
m.store[k] = v
m.rstore[v] = k
}
func (m *uniqMap[K, V]) Del(k K) {
v := m.store[k]
delete(m.store, k)
delete(m.rstore, v)
}
func (m *uniqMap[K, V]) Get(k K) (V) {
v := m.store[k]
return v
}
func (m *uniqMap[K, V]) Got(k K) (V, bool) {
v, ok := m.store[k]
return v, ok
}
func (m *uniqMap[K, V]) Chan() chan V {
ret := make(chan V)
go func() {
for _, v := range m.store {
ret <- v
}
close(ret)
}()
return ret
}
func (m *uniqMap[K, V]) Keys() []K {
ret := make([]K, len(m.store))
i := 0
for k := range m.store {
ret[i] = k
i++
}
return ret
}
func (m *uniqMap[K, V]) KeyChan() chan K {
ret := make(chan K)
go func() {
for k := range m.store {
ret <- k
}
close(ret)
}()
return ret
}
func (m *uniqMap[K, V]) Values() []V {
ret := make([]V, len(m.store))
i := 0
for _, v := range m.store {
ret[i] = v
i++
}
return ret
}
func (m *uniqMap[K, V]) Size() int {
return len(m.store)
}
func (m *uniqMap[K, V]) GetByValue(v V) (K) {
k := m.rstore[v]
return k
}

View file

@ -1,58 +0,0 @@
package mapx
import (
"fmt"
)
// The package implements some more specific
// map structures for special uses.
// Implemented mostly to be embedded to other structures.
// General map type, wrap for the built-in one.
type Map[K comparable, V any] map[K] V
// Returns new basic map.
func New[K comparable, V any]() Map[K, V] {
return make(Map[K, V])
}
// Returns slice of keys of the map.
func (m Map[K, V]) Keys() []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
// Returns slice of values of the map.
func (m Map[K, V]) Values(sm map[K] V) []V {
r := make([]V, 0, len(m))
for _, v := range m {
r = append(r, v)
}
return r
}
// Checks if the map contains the key.
func (m Map[K, V]) Has(k K) bool {
_, ok := m[k]
return ok
}
// Sets the new value by key or resets if it exists.
func (m Map[K, V]) Set(k K, v V) {
m[k] = v
}
// Returns the value by key. Panics if there is no such key.
func (m Map[K, V]) Get(k K) V {
v, ok := m[k]
if !ok {
panic(fmt.Sprintf("there is no such key '%v'", k))
}
return v
}

View file

@ -1,76 +0,0 @@
package mapx
// The type makes the underlying map ordered,
// so every time you pass through all the values
// they will be in the same order.
type OrderedMap[K comparable, V any] struct {
store map[K] V
keys []K
}
// Returns the new empty ordered map.
func NewOrdered[K comparable, V any]() *OrderedMap[K, V] {
return &OrderedMap[K, V]{
store: make(map[K] V),
}
}
// Set or reset the value in the map.
func (m *OrderedMap[K, V]) Set(k K, v V) {
_, ok := m.store[k]
if !ok {
m.keys = append(m.keys, k)
}
m.store[k] = v
}
func (m *OrderedMap[K, V]) Has(k K) bool {
_, ok := m.store[k]
return ok
}
// Get the value from the map.
func (m *OrderedMap[K, V]) Get(k K) (V) {
v := m.store[k]
return v
}
func (m *OrderedMap[K, V]) Del(k K) {
delete(m.store, k)
for i, v := range m.keys {
if v == k {
m.keys = append(m.keys[:i], m.keys[i+1:]...)
}
}
}
// Get map keys slice.
func (m *OrderedMap[K, V]) Keys() []K {
return m.keys
}
func (m *OrderedMap[K, V]) KeyChan() chan K {
chn := make(chan K)
go func() {
for _, v := range m.keys {
chn <- v
}
close(chn)
}()
return chn
}
// Return channel of ordered values.
func (m *OrderedMap[K, V]) Chan() chan V {
chn := make(chan V)
go func(){
for _, k := range m.keys {
chn <- m.Get(k)
}
close(chn)
}()
return chn
}

View file

@ -1,37 +0,0 @@
package mapx
// The type implements map type where
// you can get, set and delete by value
// since it store everything as ONLY entity
// both for keys and values way.
// Use only when you do not care about the order.
type UniqMap[K, V comparable] struct {
store map[K] V
rstore map[V] K
}
// Returns new empty UniqMap.
func NewUniq[K, V comparable]() *UniqMap[K, V] {
return &UniqMap[K, V]{
make(map[K] V),
make(map[V] K),
}
}
// Sets new value v for the k key.
func (m *UniqMap[K, V]) Set(k K, v V) {
m.store[k] = v
m.rstore[v] = k
}
// Get value by the k key.
func (m *UniqMap[K, V]) Get(k K) (V, bool) {
v, ok := m.store[k]
return v, ok
}
func (m *UniqMap[K, V]) GetByValue(v V) (K, bool) {
k, ok := m.rstore[v]
return k, ok
}

View file

@ -1,46 +0,0 @@
package poolx
import (
"github.com/mojosa-software/godat/src/llx"
"github.com/mojosa-software/godat/src/iterx"
)
// Ordered value-only based structure.
// Fast deleting by value.
// Cannot store multiple equal values.
type Pool[V comparable] struct {
store *llx.LinkedList[V]
}
// Return new empty pool.
func New[V comparable]() *Pool[V] {
return &Pool[V]{
store: llx.New[V](),
}
}
func (p *Pool[V]) Append(v V) {
p.store.Append(v)
}
// Deletes the first appearance of the value in the list.
func (p *Pool[V]) DeleteValue(v V) bool {
i := 0
ll := p.store
for e := ll.First() ; e != nil ; e = e.Next() {
if e.Value() == v {
ll.Delete(i)
return true
}
i++
}
return false
}
func (p *Pool[V]) Chan() iterx.PairChan[int, V] {
return p.store.Chan()
}

View file

@ -1,35 +0,0 @@
package slicex
func MakeMap[K comparable, V any](
values []V,
fn func([]V, int) (K),
) map[K] V {
var k K
r := make(map[K] V)
for i, _ := range values {
k = fn(values, i)
r[k] = values[i]
}
return r
}
func ConvStr[V1, V2 ~string](v1 []V1) []V2 {
ret := []V2{}
for i := range v1 {
ret = append(ret, V2(v1[i]))
}
return ret
}
func ConvInt[V1, V2 ~int](v1 []V1) []V2 {
ret := []V2{}
for i := range v1 {
ret = append(ret, V2(v1[i]))
}
return ret
}

View file

@ -1,15 +0,0 @@
package sparses
import (
"testing"
)
func TestNew(t *testing.T) {
s := New[int, string](0, nil)
if aVal := s.Empty() ; if aVal != true {
t.Errorf("Got %v expected %v", aVal, )
}
s = New[int, string]
}

View file

@ -1,25 +0,0 @@
package sparses
import (
"github.com/reklesio/gods"
"cmp"
)
// The general sparse array type.
type Sparse[K cmp.Ordered, V any] interface {
gods.Container[V]
// Returns slice of set values.
Values() []V
// Returns slice of set keys.
Keys() []K
// Set the key to the value.
Set(K, V)
// Get the value by the key.
Get(K) V
// Returns true if the key is set.
Has(K) bool
// Delete the value under the key.
Del(K)
// Returns channel of ordered values.
Chan() chan V
}