From 302da3ec078182823616b70832ced15e489e92fa Mon Sep 17 00:00:00 2001 From: surdeus Date: Fri, 28 Apr 2023 16:14:03 +0300 Subject: [PATCH] Started implementing structures for gox. --- src/cmd/test/main.go | 10 ++++ src/llx/main.go | 129 +++++++++++++++++++++++++++++++++++++++++++ src/mapx/main.go | 35 ++++++++++++ src/poolx/main.go | 25 +++++++++ 4 files changed, 199 insertions(+) create mode 100644 src/llx/main.go create mode 100644 src/poolx/main.go diff --git a/src/cmd/test/main.go b/src/cmd/test/main.go index 588b1ce..45c2ecf 100644 --- a/src/cmd/test/main.go +++ b/src/cmd/test/main.go @@ -3,6 +3,7 @@ package main import ( "github.com/surdeus/godat/src/mapx" "github.com/surdeus/godat/src/slicex" + "github.com/surdeus/godat/src/llx" "fmt" ) @@ -39,4 +40,13 @@ func main() { fmt.Printf("%q\n", mapx.Values(m)) fmt.Printf("%q\n", mapx.Reverse(m)) fmt.Printf("%v\n", mapx.Reverse(m1)) + + ll := llx.New[int]() + ll.Append(0) + ll.Append(1) + ll.Append(2) + ll.Set(1, 256) + for p := range ll.Range() { + fmt.Println(p) + } } diff --git a/src/llx/main.go b/src/llx/main.go new file mode 100644 index 0000000..f41a33c --- /dev/null +++ b/src/llx/main.go @@ -0,0 +1,129 @@ +package llx + +// Linked list X . +// The package implements better variation of +// linked list than in standard library since it uses +// the new conception of generics. + +type LinkedList[V any] struct { + // First empty element (not used to store values). + // For fast pushing. + before *Element[V] + // Points to the last for fast appending. + last *Element[V] + // Length. + ln int +} + +type Element[V any] struct { + prev *Element[V] + next *Element[V] + value V +} + +type Pair[V any] struct { + I int + V V +} + +// Returns new empty linked list storing the V type. +func New[V any]() *LinkedList[V] { + return &LinkedList[V]{ + &Element[V]{}, + nil, + 0, + } +} + +// Get length of the linked list. +func (ll *LinkedList[V]) Len() int { + return ll.ln +} + +// Get the index-indexed element itself. +func (ll *LinkedList[V]) GetEl(index int) (*Element[V], bool) { + if ll.ln <= index { + return nil, false + } + p := ll.before + for i := 0 ; i <= index ; i++ { + p = p.next + } + + return p, true +} + +// Get the value of index-indexed element. +func (ll *LinkedList[V]) Get(index int) (V, bool) { + el, ok := ll.GetEl(index) + var v V + if ok { + v = el.value + } + + return v, ok +} + +// Set the new value in i-indexed element. +func (ll *LinkedList[V]) Set(i int, v V) (bool) { + el, ok := ll.GetEl(i) + if !ok { + return false + } + + el.value = v + return true +} + +// Push in the beginning of the list. +func (ll *LinkedList[V]) Push(v V) { + prevNext := ll.before.next + nextNext := &Element[V]{ + next: prevNext, + prev: nil, + value: v, + } + ll.before.next = nextNext + + ll.ln++ + if ll.ln == 1 { + ll.last = ll.before.next + } +} + +// Append to the end of the list. +func (ll *LinkedList[V]) Append(v V) { + if ll.ln == 0 { + ll.Push(v) + return + } + + last := &Element[V]{ + next: nil, + prev: ll.last, + value: v, + } + + lastBuf := ll.last + lastBuf.next = last + ll.last = last + + ll.ln++ +} + +// Returns a channel of Pair that contains index and the value. +func (ll *LinkedList[V]) Range() chan Pair[V] { + chn := make(chan Pair[V]) + go func(){ + i := -1 + el := ll.before + for el.next != nil { + i++ + el = el.next + chn <- Pair[V]{i, el.value} + } + close(chn) + }() + return chn +} + diff --git a/src/mapx/main.go b/src/mapx/main.go index 19b60b8..52baf48 100644 --- a/src/mapx/main.go +++ b/src/mapx/main.go @@ -1,5 +1,40 @@ 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 +} + func Keys[K comparable, V any](m map[K] V) []K { r := make([]K, 0, len(m)) for k := range m { diff --git a/src/poolx/main.go b/src/poolx/main.go new file mode 100644 index 0000000..c43440b --- /dev/null +++ b/src/poolx/main.go @@ -0,0 +1,25 @@ +package poolx + +// The package implements ordered +// pool structure without any indexex. +// Should be used with only-one-value based +// structures. + +type Pool[V comparable] struct { + store map[V] uint64 + last uint64 +} + +// Returns new empty pool. +func New[V comparable]() *Pool { + return &Pool{ + make(map[V] uint64), + 0, + } +} + +func (p *Pool[V]) Push(v V) { + p.last++ + map[V] = p.last +} +