commit
cd5aa6cec7
10 changed files with 137 additions and 35 deletions
24
src/cmd/ll/main.go
Normal file
24
src/cmd/ll/main.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mojosa-software/godat/src/llx"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ll := llx.New[string]()
|
||||||
|
ll.Append("zero")
|
||||||
|
ll.Append("one")
|
||||||
|
ll.Append("two")
|
||||||
|
ll.Append("three")
|
||||||
|
ll.Append("four")
|
||||||
|
ll.Push("minus one")
|
||||||
|
|
||||||
|
ll.Swap(1, 3)
|
||||||
|
|
||||||
|
for p := range ll.Chan() {
|
||||||
|
fmt.Println(p.K, p.V)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
26
src/cmd/pool/main.go
Normal file
26
src/cmd/pool/main.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mojosa-software/godat/src/poolx"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
values := []string{
|
||||||
|
"zero", "one",
|
||||||
|
"should be deleted",
|
||||||
|
"two", "three",
|
||||||
|
}
|
||||||
|
pool := poolx.New[string]()
|
||||||
|
for _, v := range values {
|
||||||
|
pool.Append(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
pool.DeleteValue("should be deleted")
|
||||||
|
|
||||||
|
for p := range pool.Chan() {
|
||||||
|
fmt.Println(p.K, p.V)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,12 +12,12 @@ func main() {
|
||||||
unord.Set(-4, "die")
|
unord.Set(-4, "die")
|
||||||
unord.Set(-1000, "withme")
|
unord.Set(-1000, "withme")
|
||||||
|
|
||||||
for v := range unord.Vals() {
|
for p := range unord.Chan() {
|
||||||
fmt.Println(v.K, v.V)
|
fmt.Println(p.K, p.V)
|
||||||
}
|
}
|
||||||
|
|
||||||
unord.Sort()
|
unord.Sort()
|
||||||
for v := range unord.Vals() {
|
for p := range unord.Chan() {
|
||||||
fmt.Println(v.K, v.V)
|
fmt.Println(p.K, p.V)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/iterx/misc.go
Normal file
11
src/iterx/misc.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package iterx
|
||||||
|
|
||||||
|
func ChanToSlice[V any](c chan V) []V {
|
||||||
|
ret := []V{}
|
||||||
|
for v := range c {
|
||||||
|
ret = append(ret, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,11 @@ package llx
|
||||||
// linked list than in standard library since it uses
|
// linked list than in standard library since it uses
|
||||||
// the new conception of generics.
|
// the new conception of generics.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mojosa-software/godat/src/iterx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The type represents linked list data structure.
|
||||||
type LinkedList[V any] struct {
|
type LinkedList[V any] struct {
|
||||||
// First empty element (not used to store values).
|
// First empty element (not used to store values).
|
||||||
// For fast pushing.
|
// For fast pushing.
|
||||||
|
@ -15,17 +20,12 @@ type LinkedList[V any] struct {
|
||||||
ln int
|
ln int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The type represents element of the linked list.
|
||||||
type Element[V any] struct {
|
type Element[V any] struct {
|
||||||
next *Element[V]
|
next *Element[V]
|
||||||
value V
|
value V
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pair[V any] struct {
|
|
||||||
I int
|
|
||||||
V V
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns new empty linked list storing the V type.
|
// Returns new empty linked list storing the V type.
|
||||||
func New[V any]() *LinkedList[V] {
|
func New[V any]() *LinkedList[V] {
|
||||||
return &LinkedList[V]{
|
return &LinkedList[V]{
|
||||||
|
@ -36,7 +36,7 @@ func New[V any]() *LinkedList[V] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get length of the linked list.
|
// Get length of the linked list.
|
||||||
func (ll *LinkedList[V]) Len() int {
|
func (ll *LinkedList[V]) Length() int {
|
||||||
return ll.ln
|
return ll.ln
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,25 @@ func (ll *LinkedList[V]) Set(i int, v V) (bool) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ll *LinkedList[V]) Del(i int) (bool) {
|
func (ll *LinkedList[V]) Swap(i1, i2 int) {
|
||||||
|
if i1 == i2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
max := ll.ln - 1
|
||||||
|
if i1 < 0 || i2 < 0 || i1 > max || i2 > max {
|
||||||
|
panic("index out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
el1, _ := ll.GetEl(i1)
|
||||||
|
el2, _ := ll.GetEl(i2)
|
||||||
|
|
||||||
|
el1.value, el2.value =
|
||||||
|
el2.value, el1.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletes the element by its index.
|
||||||
|
func (ll *LinkedList[V]) Delete(i int) (bool) {
|
||||||
if ll.ln <= i {
|
if ll.ln <= i {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -133,32 +151,40 @@ func (ll *LinkedList[V]) Append(v V) {
|
||||||
ll.ln++
|
ll.ln++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the first element of the linked list.
|
||||||
func (ll *LinkedList[V]) First() *Element[V] {
|
func (ll *LinkedList[V]) First() *Element[V] {
|
||||||
return ll.before.next
|
return ll.before.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get elements value.
|
||||||
func (ll *Element[V]) Value() V {
|
func (ll *Element[V]) Value() V {
|
||||||
return ll.value
|
return ll.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the next element. If the returned value == nil,
|
||||||
|
// then it is the last element.
|
||||||
func (ll *Element[V]) Next() *Element[V] {
|
func (ll *Element[V]) Next() *Element[V] {
|
||||||
return ll.next
|
return ll.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the last element.
|
||||||
func (ll *LinkedList[V]) Last() *Element[V] {
|
func (ll *LinkedList[V]) Last() *Element[V] {
|
||||||
return ll.last
|
return ll.last
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a channel of Pair that contains index and the value.
|
// Returns a channel of Pair that contains index and the value.
|
||||||
func (ll *LinkedList[V]) Range() chan Pair[V] {
|
func (ll *LinkedList[V]) Chan() iterx.PairChan[int, V] {
|
||||||
chn := make(chan Pair[V])
|
chn := make(iterx.PairChan[int, V])
|
||||||
go func(){
|
go func(){
|
||||||
i := -1
|
i := -1
|
||||||
el := ll.before
|
el := ll.before
|
||||||
for el.next != nil {
|
for el.next != nil {
|
||||||
i++
|
i++
|
||||||
el = el.next
|
el = el.next
|
||||||
chn <- Pair[V]{i, el.value}
|
chn <- iterx.Pair[int, V]{
|
||||||
|
K: i,
|
||||||
|
V: el.value,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
close(chn)
|
close(chn)
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
// The package implements some more specific
|
// The package implements some more specific
|
||||||
// map structures for special uses.
|
// map structures for special uses.
|
||||||
|
// Implemented mostly to be embedded to other structures.
|
||||||
|
|
||||||
// General map type, wrap for the built-in one.
|
// General map type, wrap for the built-in one.
|
||||||
type Map[K comparable, V any] map[K] V
|
type Map[K comparable, V any] map[K] V
|
||||||
|
|
10
src/mapx/misc.go
Normal file
10
src/mapx/misc.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package mapx
|
||||||
|
|
||||||
|
func Reversed[K, V comparable](m map[K] V) map[V] K {
|
||||||
|
r := make(map[V] K)
|
||||||
|
for k, v := range m {
|
||||||
|
r[v] = k
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package poolx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mojosa-software/godat/src/llx"
|
"github.com/mojosa-software/godat/src/llx"
|
||||||
|
"github.com/mojosa-software/godat/src/iterx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ordered value-only based structure.
|
// Ordered value-only based structure.
|
||||||
|
@ -24,12 +25,12 @@ func (p *Pool[V]) Append(v V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes the first appearance of the value in the list.
|
// Deletes the first appearance of the value in the list.
|
||||||
func (p *Pool[V]) Del(v V) bool {
|
func (p *Pool[V]) DeleteValue(v V) bool {
|
||||||
i := 0
|
i := 0
|
||||||
ll := p.store
|
ll := p.store
|
||||||
for e := ll.First() ; e != nil ; e = e.Next() {
|
for e := ll.First() ; e != nil ; e = e.Next() {
|
||||||
if e.Value() == v {
|
if e.Value() == v {
|
||||||
ll.Del(i)
|
ll.Delete(i)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ func (p *Pool[V]) Del(v V) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool[V]) Range() chan llx.Pair[V] {
|
func (p *Pool[V]) Chan() iterx.PairChan[int, V] {
|
||||||
return p.store.Range()
|
return p.store.Chan()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,38 +3,38 @@ package sparsex
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
cons "golang.org/x/exp/constraints"
|
cons "golang.org/x/exp/constraints"
|
||||||
|
"github.com/mojosa-software/godat/src/iterx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The package implements a simple ordered map.
|
// The package implements a simple ordered map.
|
||||||
// In fact can be used as a sparse array so it is
|
// In fact can be used as a sparse array so it is
|
||||||
// where the name comes from.
|
// where the name comes from.
|
||||||
|
|
||||||
type Pair[K cons.Ordered, V any] struct {
|
// The sparse array type.
|
||||||
K K
|
|
||||||
V V
|
|
||||||
}
|
|
||||||
|
|
||||||
type Sparse[K cons.Ordered, V any] struct {
|
type Sparse[K cons.Ordered, V any] struct {
|
||||||
store map[K] V
|
store map[K] V
|
||||||
keys []K
|
keys []K
|
||||||
shouldSort bool
|
shouldSort bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns new sparse array
|
// Returns new sparse array.
|
||||||
func New[K cons.Ordered, V any](s bool) *Sparse[K, V] {
|
// If shouldSort == true then it will sort the array on
|
||||||
|
// each change.
|
||||||
|
func New[K cons.Ordered, V any](shouldSort bool) *Sparse[K, V] {
|
||||||
return &Sparse[K, V]{
|
return &Sparse[K, V]{
|
||||||
store: make(map[K] V),
|
store: make(map[K] V),
|
||||||
keys: []K{},
|
keys: []K{},
|
||||||
shouldSort: s,
|
shouldSort: shouldSort,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the value by the key.
|
||||||
func (s *Sparse[K, V]) Get(key K) (V, bool) {
|
func (s *Sparse[K, V]) Get(key K) (V, bool) {
|
||||||
val, ok := s.store[key]
|
val, ok := s.store[key]
|
||||||
return val, ok
|
return val, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the value to the key.
|
||||||
func (s *Sparse[K, V]) Set(k K, v V) {
|
func (s *Sparse[K, V]) Set(k K, v V) {
|
||||||
_, ok := s.store[k]
|
_, ok := s.store[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -47,7 +47,8 @@ func (s *Sparse[K, V]) Set(k K, v V) {
|
||||||
s.store[k] = v
|
s.store[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sparse[K, V]) Del(k K) {
|
// Delete the value by the key.
|
||||||
|
func (s Sparse[K, V]) Delete(k K) {
|
||||||
delete(s.store, k)
|
delete(s.store, k)
|
||||||
|
|
||||||
// To know if the loop was run.
|
// To know if the loop was run.
|
||||||
|
@ -68,16 +69,18 @@ func (s Sparse[K, V]) Del(k K) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sparse[K, V]) Vals(
|
// Returns channel of pairs.
|
||||||
) chan Pair[K, V] {
|
func (s *Sparse[K, V]) Chan(
|
||||||
|
) iterx.PairChan[K, V] {
|
||||||
keys := s.keys
|
keys := s.keys
|
||||||
store := s.store
|
store := s.store
|
||||||
ret := make(chan Pair[K, V])
|
ret := make(iterx.PairChan[K, V])
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for _, v := range keys {
|
for _, k := range keys {
|
||||||
ret <- Pair[K, V]{
|
ret <- iterx.Pair[K, V]{
|
||||||
v, store[v],
|
K: k,
|
||||||
|
V: store[k],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(ret)
|
close(ret)
|
||||||
|
|
Loading…
Reference in a new issue