Documentation
¶
Overview ¶
Package gds provides a collection of generic, zero-dependency data structures for Go 1.21+. All structures are not safe for concurrent use unless stated otherwise.
Available structures:
- Set — unordered collection of unique elements
- SortedSet — sorted unique elements with binary search
- OrderedMap — map that preserves insertion order
- MultiMap — map with multiple values per key
- Stack — LIFO stack
- Queue — FIFO queue with auto-compaction
- Deque — double-ended queue with O(1) amortized push/pop
- PriorityQueue — binary heap with custom comparator
- RingBuffer — fixed-capacity circular buffer
- LinkedList — doubly-linked list with node handles
Index ¶
- func MultiMapRemoveValue[K comparable, V comparable](mm *MultiMap[K, V], key K, value V) bool
- type Deque
- func (d *Deque[T]) Clear()
- func (d *Deque[T]) IsEmpty() bool
- func (d *Deque[T]) Len() int
- func (d *Deque[T]) PeekBack() (T, bool)
- func (d *Deque[T]) PeekFront() (T, bool)
- func (d *Deque[T]) PopBack() (T, bool)
- func (d *Deque[T]) PopFront() (T, bool)
- func (d *Deque[T]) PushBack(items ...T)
- func (d *Deque[T]) PushFront(items ...T)
- type LinkedList
- func (l *LinkedList[T]) Back() *ListNode[T]
- func (l *LinkedList[T]) Front() *ListNode[T]
- func (l *LinkedList[T]) InsertAfter(value T, at *ListNode[T]) *ListNode[T]
- func (l *LinkedList[T]) InsertBefore(value T, at *ListNode[T]) *ListNode[T]
- func (l *LinkedList[T]) IsEmpty() bool
- func (l *LinkedList[T]) Len() int
- func (l *LinkedList[T]) PushBack(value T) *ListNode[T]
- func (l *LinkedList[T]) PushFront(value T) *ListNode[T]
- func (l *LinkedList[T]) Remove(node *ListNode[T]) T
- type ListNode
- type MultiMap
- func (mm *MultiMap[K, V]) Add(key K, values ...V)
- func (mm *MultiMap[K, V]) Get(key K) ([]V, bool)
- func (mm *MultiMap[K, V]) Has(key K) bool
- func (mm *MultiMap[K, V]) IsEmpty() bool
- func (mm *MultiMap[K, V]) Keys() []K
- func (mm *MultiMap[K, V]) Len() int
- func (mm *MultiMap[K, V]) Range(fn func(K, []V) bool)
- func (mm *MultiMap[K, V]) Remove(key K) bool
- func (mm *MultiMap[K, V]) TotalValues() int
- type OrderedMap
- func (o *OrderedMap[K, V]) Delete(key K) bool
- func (o *OrderedMap[K, V]) Get(key K) (V, bool)
- func (o *OrderedMap[K, V]) Has(key K) bool
- func (o *OrderedMap[K, V]) IsEmpty() bool
- func (o *OrderedMap[K, V]) Keys() []K
- func (o *OrderedMap[K, V]) Len() int
- func (o *OrderedMap[K, V]) Range(fn func(K, V) bool)
- func (o *OrderedMap[K, V]) Set(key K, value V)
- func (o *OrderedMap[K, V]) Values() []V
- type PriorityQueue
- type Queue
- type RingBuffer
- type Set
- func (s *Set[T]) Add(items ...T)
- func (s *Set[T]) Clear()
- func (s *Set[T]) Clone() *Set[T]
- func (s *Set[T]) Contains(item T) bool
- func (s *Set[T]) Difference(other *Set[T]) *Set[T]
- func (s *Set[T]) Equal(other *Set[T]) bool
- func (s *Set[T]) Intersection(other *Set[T]) *Set[T]
- func (s *Set[T]) IsEmpty() bool
- func (s *Set[T]) IsSubset(other *Set[T]) bool
- func (s *Set[T]) Items() []T
- func (s *Set[T]) Len() int
- func (s *Set[T]) Remove(items ...T)
- func (s *Set[T]) Union(other *Set[T]) *Set[T]
- type SortedSet
- func (s *SortedSet[T]) Add(item T)
- func (s *SortedSet[T]) Clear()
- func (s *SortedSet[T]) Contains(item T) bool
- func (s *SortedSet[T]) IsEmpty() bool
- func (s *SortedSet[T]) Items() []T
- func (s *SortedSet[T]) Len() int
- func (s *SortedSet[T]) Max() (T, bool)
- func (s *SortedSet[T]) Min() (T, bool)
- func (s *SortedSet[T]) Range(fn func(T) bool)
- func (s *SortedSet[T]) Remove(item T) bool
- type Stack
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func MultiMapRemoveValue ¶
func MultiMapRemoveValue[K comparable, V comparable](mm *MultiMap[K, V], key K, value V) bool
MultiMapRemoveValue removes the first occurrence of value from the values associated with key. Reports whether a value was removed. This is a package-level function because it requires V to be comparable.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
mm := gds.NewMultiMap[string, string]()
mm.Add("fruits", "apple", "banana", "cherry")
gds.MultiMapRemoveValue(mm, "fruits", "banana")
vals, _ := mm.Get("fruits")
fmt.Println(vals)
}
Output: [apple cherry]
Types ¶
type Deque ¶
type Deque[T any] struct { // contains filtered or unexported fields }
Deque is a double-ended queue that supports O(1) amortized push and pop at both ends. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
d := gds.NewDeque[int]()
d.PushBack(1, 2, 3)
d.PushFront(0)
front, _ := d.PopFront()
back, _ := d.PopBack()
fmt.Println(front, back)
fmt.Println(d.Len())
}
Output: 0 3 2
func (*Deque[T]) PeekBack ¶
PeekBack returns the back element without removing it. Returns the zero value and false if the deque is empty.
func (*Deque[T]) PeekFront ¶
PeekFront returns the front element without removing it. Returns the zero value and false if the deque is empty.
func (*Deque[T]) PopBack ¶
PopBack removes and returns the back element. Returns the zero value and false if the deque is empty.
func (*Deque[T]) PopFront ¶
PopFront removes and returns the front element. Returns the zero value and false if the deque is empty.
type LinkedList ¶
type LinkedList[T any] struct { // contains filtered or unexported fields }
LinkedList is a doubly-linked list. The zero value is an empty list. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
l := gds.NewLinkedList[int]()
a := l.PushBack(1)
l.PushBack(3)
l.InsertAfter(2, a)
for n := l.Front(); n != nil; n = n.Next() {
fmt.Print(n.Value, " ")
}
fmt.Println()
}
Output: 1 2 3
func NewLinkedList ¶
func NewLinkedList[T any]() *LinkedList[T]
NewLinkedList returns an empty LinkedList.
func (*LinkedList[T]) Back ¶
func (l *LinkedList[T]) Back() *ListNode[T]
Back returns the last node or nil if the list is empty.
func (*LinkedList[T]) Front ¶
func (l *LinkedList[T]) Front() *ListNode[T]
Front returns the first node or nil if the list is empty.
func (*LinkedList[T]) InsertAfter ¶
func (l *LinkedList[T]) InsertAfter(value T, at *ListNode[T]) *ListNode[T]
InsertAfter inserts a new node with value immediately after at and returns it. at must belong to this list.
func (*LinkedList[T]) InsertBefore ¶
func (l *LinkedList[T]) InsertBefore(value T, at *ListNode[T]) *ListNode[T]
InsertBefore inserts a new node with value immediately before at and returns it. at must belong to this list.
func (*LinkedList[T]) IsEmpty ¶
func (l *LinkedList[T]) IsEmpty() bool
IsEmpty reports whether the list has no nodes.
func (*LinkedList[T]) PushBack ¶
func (l *LinkedList[T]) PushBack(value T) *ListNode[T]
PushBack inserts a new node with value at the back and returns it.
func (*LinkedList[T]) PushFront ¶
func (l *LinkedList[T]) PushFront(value T) *ListNode[T]
PushFront inserts a new node with value at the front and returns it.
func (*LinkedList[T]) Remove ¶
func (l *LinkedList[T]) Remove(node *ListNode[T]) T
Remove removes node from the list and returns its value. node must belong to this list.
type ListNode ¶
type ListNode[T any] struct { Value T // contains filtered or unexported fields }
ListNode is an element of a LinkedList.
type MultiMap ¶
type MultiMap[K comparable, V any] struct { // contains filtered or unexported fields }
MultiMap maps each key to a slice of values. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
mm := gds.NewMultiMap[string, string]()
mm.Add("fruits", "apple", "banana")
mm.Add("fruits", "cherry")
vals, _ := mm.Get("fruits")
fmt.Println(vals)
fmt.Println(mm.TotalValues())
}
Output: [apple banana cherry] 3
func NewMultiMap ¶
func NewMultiMap[K comparable, V any]() *MultiMap[K, V]
NewMultiMap returns an empty MultiMap.
func (*MultiMap[K, V]) Add ¶
func (mm *MultiMap[K, V]) Add(key K, values ...V)
Add appends one or more values to the given key.
func (*MultiMap[K, V]) Get ¶
Get returns the slice of values for key and whether the key was found. The returned slice must not be modified.
func (*MultiMap[K, V]) Keys ¶
func (mm *MultiMap[K, V]) Keys() []K
Keys returns all keys in an unordered slice.
func (*MultiMap[K, V]) Range ¶
Range calls fn for each key and its associated value slice in unspecified order. Iteration stops early if fn returns false.
func (*MultiMap[K, V]) Remove ¶
Remove deletes all values for the given key. Reports whether the key was present.
func (*MultiMap[K, V]) TotalValues ¶
TotalValues returns the total number of values across all keys.
type OrderedMap ¶
type OrderedMap[K comparable, V any] struct { // contains filtered or unexported fields }
OrderedMap is a map that remembers insertion order. Re-setting an existing key updates its value without changing its position. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
m := gds.NewOrderedMap[string, int]()
m.Set("b", 2)
m.Set("a", 1)
m.Set("c", 3)
fmt.Println(m.Keys()) // insertion order preserved
v, _ := m.Get("a")
fmt.Println(v)
}
Output: [b a c] 1
func NewOrderedMap ¶
func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V]
NewOrderedMap returns an empty OrderedMap.
func (*OrderedMap[K, V]) Delete ¶
func (o *OrderedMap[K, V]) Delete(key K) bool
Delete removes the key and its value. Reports whether the key was present.
func (*OrderedMap[K, V]) Get ¶
func (o *OrderedMap[K, V]) Get(key K) (V, bool)
Get returns the value for key and whether the key was found.
func (*OrderedMap[K, V]) Has ¶
func (o *OrderedMap[K, V]) Has(key K) bool
Has reports whether key exists in the map.
func (*OrderedMap[K, V]) IsEmpty ¶
func (o *OrderedMap[K, V]) IsEmpty() bool
IsEmpty reports whether the map has no entries.
func (*OrderedMap[K, V]) Keys ¶
func (o *OrderedMap[K, V]) Keys() []K
Keys returns all keys in insertion order.
func (*OrderedMap[K, V]) Len ¶
func (o *OrderedMap[K, V]) Len() int
Len returns the number of key-value pairs.
func (*OrderedMap[K, V]) Range ¶
func (o *OrderedMap[K, V]) Range(fn func(K, V) bool)
Range calls fn for each key-value pair in insertion order. Iteration stops early if fn returns false.
func (*OrderedMap[K, V]) Set ¶
func (o *OrderedMap[K, V]) Set(key K, value V)
Set inserts or updates the value for key. If key is new, it is appended at the end of the order.
func (*OrderedMap[K, V]) Values ¶
func (o *OrderedMap[K, V]) Values() []V
Values returns all values in insertion order.
type PriorityQueue ¶
type PriorityQueue[T any] struct { // contains filtered or unexported fields }
PriorityQueue is a binary heap where the element for which less(a, b) is true has the highest priority and is returned first by Pop.
To create a min-heap of ints:
pq := gds.NewPriorityQueue(func(a, b int) bool { return a < b })
To create a max-heap of ints:
pq := gds.NewPriorityQueue(func(a, b int) bool { return a > b })
It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
// min-heap
pq := gds.NewPriorityQueue(func(a, b int) bool { return a < b })
pq.Push(5, 1, 3, 2, 4)
for !pq.IsEmpty() {
v, _ := pq.Pop()
fmt.Print(v, " ")
}
fmt.Println()
}
Output: 1 2 3 4 5
func NewPriorityQueue ¶
func NewPriorityQueue[T any](less func(a, b T) bool) *PriorityQueue[T]
NewPriorityQueue returns an empty PriorityQueue. less(a, b) must return true when a has higher priority than b.
func (*PriorityQueue[T]) IsEmpty ¶
func (pq *PriorityQueue[T]) IsEmpty() bool
IsEmpty reports whether the queue has no elements.
func (*PriorityQueue[T]) Len ¶
func (pq *PriorityQueue[T]) Len() int
Len returns the number of elements in the queue.
func (*PriorityQueue[T]) Peek ¶
func (pq *PriorityQueue[T]) Peek() (T, bool)
Peek returns the highest-priority element without removing it. Returns the zero value and false if the queue is empty.
func (*PriorityQueue[T]) Pop ¶
func (pq *PriorityQueue[T]) Pop() (T, bool)
Pop removes and returns the highest-priority element. Returns the zero value and false if the queue is empty.
func (*PriorityQueue[T]) Push ¶
func (pq *PriorityQueue[T]) Push(items ...T)
Push adds one or more items to the queue.
type Queue ¶
type Queue[T any] struct { // contains filtered or unexported fields }
Queue is a FIFO (first-in, first-out) collection. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
q := gds.NewQueue[string]()
q.Enqueue("a", "b", "c")
front, _ := q.Dequeue()
fmt.Println(front) // FIFO: a
peek, _ := q.Peek()
fmt.Println(peek)
}
Output: a b
func (*Queue[T]) Dequeue ¶
Dequeue removes and returns the front element. Returns the zero value and false if the queue is empty.
func (*Queue[T]) Enqueue ¶
func (q *Queue[T]) Enqueue(items ...T)
Enqueue adds one or more items at the back of the queue.
type RingBuffer ¶
type RingBuffer[T any] struct { // contains filtered or unexported fields }
RingBuffer is a fixed-capacity circular buffer (FIFO). When full, Push returns false and the buffer is unchanged. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
r := gds.NewRingBuffer[int](3)
fmt.Println(r.Push(10)) // true
fmt.Println(r.Push(20)) // true
fmt.Println(r.Push(30)) // true
fmt.Println(r.Push(40)) // false — full
v, _ := r.Pop()
fmt.Println(v) // FIFO: 10
}
Output: true true true false 10
func NewRingBuffer ¶
func NewRingBuffer[T any](capacity int) *RingBuffer[T]
NewRingBuffer returns an empty RingBuffer with the given capacity. Panics if capacity is less than 1.
func (*RingBuffer[T]) Cap ¶
func (r *RingBuffer[T]) Cap() int
Cap returns the maximum number of elements the buffer can hold.
func (*RingBuffer[T]) Clear ¶
func (r *RingBuffer[T]) Clear()
Clear discards all elements and resets the buffer.
func (*RingBuffer[T]) IsEmpty ¶
func (r *RingBuffer[T]) IsEmpty() bool
IsEmpty reports whether the buffer has no elements.
func (*RingBuffer[T]) IsFull ¶
func (r *RingBuffer[T]) IsFull() bool
IsFull reports whether the buffer is at capacity.
func (*RingBuffer[T]) Len ¶
func (r *RingBuffer[T]) Len() int
Len returns the number of elements currently in the buffer.
func (*RingBuffer[T]) Peek ¶
func (r *RingBuffer[T]) Peek() (T, bool)
Peek returns the oldest element without removing it. Returns the zero value and false if the buffer is empty.
func (*RingBuffer[T]) Pop ¶
func (r *RingBuffer[T]) Pop() (T, bool)
Pop removes and returns the oldest element. Returns the zero value and false if the buffer is empty.
func (*RingBuffer[T]) Push ¶
func (r *RingBuffer[T]) Push(item T) bool
Push writes item to the buffer. Returns false without modifying the buffer if it is full.
type Set ¶
type Set[T comparable] struct { // contains filtered or unexported fields }
Set is an unordered collection of unique elements. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
s := gds.NewSet(1, 2, 3)
s.Add(4)
s.Remove(2)
fmt.Println(s.Contains(3)) // true
fmt.Println(s.Contains(2)) // false
fmt.Println(s.Len()) // 3
}
Output: true false 3
func NewSet ¶
func NewSet[T comparable](items ...T) *Set[T]
NewSet returns a Set pre-populated with the given items.
func (*Set[T]) Add ¶
func (s *Set[T]) Add(items ...T)
Add inserts one or more items. Duplicate items are silently ignored.
func (*Set[T]) Difference ¶
Difference returns a new set with elements in s that are not in other.
func (*Set[T]) Intersection ¶
Intersection returns a new set containing only elements present in both s and other.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
a := gds.NewSet(1, 2, 3)
b := gds.NewSet(2, 3, 4)
i := a.Intersection(b)
fmt.Println(i.Contains(2)) // true
fmt.Println(i.Contains(1)) // false
}
Output: true false
func (*Set[T]) Items ¶
func (s *Set[T]) Items() []T
Items returns all elements as an unordered slice.
func (*Set[T]) Remove ¶
func (s *Set[T]) Remove(items ...T)
Remove deletes one or more items. Missing items are silently ignored.
type SortedSet ¶
SortedSet is an ordered collection of unique elements maintained in ascending order. All operations preserve sorted order. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
s := gds.NewSortedSet(3, 1, 4, 1, 5, 9, 2, 6)
fmt.Println(s.Items()) // sorted, deduped
min, _ := s.Min()
max, _ := s.Max()
fmt.Println(min, max)
}
Output: [1 2 3 4 5 6 9] 1 9
func NewSortedSet ¶
NewSortedSet returns a SortedSet pre-populated with the given items. Duplicates are silently ignored.
func (*SortedSet[T]) Add ¶
func (s *SortedSet[T]) Add(item T)
Add inserts item in sorted order. If item already exists, it is not added again.
func (*SortedSet[T]) Items ¶
func (s *SortedSet[T]) Items() []T
Items returns all elements in ascending order.
type Stack ¶
type Stack[T any] struct { // contains filtered or unexported fields }
Stack is a LIFO (last-in, first-out) collection. It is not safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/renaldid/gds"
)
func main() {
s := gds.NewStack[int]()
s.Push(1, 2, 3)
top, _ := s.Pop()
fmt.Println(top) // LIFO: 3
peek, _ := s.Peek()
fmt.Println(peek)
}
Output: 3 2
func (*Stack[T]) Peek ¶
Peek returns the top element without removing it. Returns the zero value and false if the stack is empty.