golot

module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2025 License: Apache-2.0

README

golot/stack

A generic, thread-safe, and performance-oriented LIFO (Last-In-First-Out) stack implementation for Go.

Overview

golot/stack provides a robust and easy-to-use stack data structure that leverages Go's generics for full type safety. It is designed for high-concurrency environments and includes advanced features for memory and performance tuning, such as pre-allocation and automatic memory shrinking.

Features

  • Type-Safe: Built with Go generics ([T any]) to ensure compile-time type safety.
  • Thread-Safe: All operations are safe for concurrent access, protected by sync.RWMutex.
  • Zero-Value Ready: A declared var s Stack[T] is an empty, usable stack with default settings.
  • Performance-Tuned: Includes NewWithCapacity to pre-allocate memory and avoid reallocations in performance-critical paths.
  • Memory-Efficient: Features a configurable, automatic memory shrinking strategy to release unused memory after usage peaks.
  • Clean API: Offers a simple and intuitive interface (Push, Pop, Peek, Size, IsEmpty).

Installation

go get codeberg.org/WIZARDELF/golot/stack

API and Usage

Interface

The stack implements the following interface:

type IStack[T any] interface {
    Size() int
    IsEmpty() bool
    Peek() (T, error)
    Push(element T)
    Pop() (T, error)
}
Basic Usage

Creating and using a stack is straightforward.

import "codeberg.org/WIZARDELF/golot/stack"

// Create a new stack for integers
s := stack.New[int]()

// Push elements onto the stack
s.Push(10)
s.Push(20)

// Peek at the top element
top, err := s.Peek()
// top: 20, err: nil

// Pop the top element
val, err := s.Pop()
// val: 20, err: nil

fmt.Printf("Stack size: %d\n", s.Size()) // "Stack size: 1"
Zero Value

The zero value of a Stack is a valid, empty stack ready for use.

var s stack.Stack[string] // No initialization needed

s.Push("hello")
val, _ := s.Pop() // val: "hello"

fmt.Println(s.IsEmpty()) // true
Performance: Pre-allocating Capacity

If you know the approximate number of elements you'll store, you can pre-allocate memory with NewWithCapacity to improve performance by preventing reallocations.

// Create a stack with an initial capacity for 100 elements
s := stack.NewWithCapacity[MyStruct](100)

for i := 0; i < 100; i++ {
    s.Push(MyStruct{...}) // These pushes will not trigger a memory reallocation
}
Advanced Configuration: Memory Shrinking

The stack automatically shrinks its underlying storage to conserve memory. This behavior can be tuned or disabled using the WithShrinkHeuristics functional option.

// Example 1: Create a stack with a more aggressive shrink policy
// Shrink when length is below 25% of capacity, and capacity is > 32.
s1 := stack.New[int](
    stack.WithShrinkHeuristics[int](0.25, 32),
)

// Example 2: Disable automatic shrinking entirely
// This can be useful in scenarios where performance is critical and memory
// usage patterns are predictable.
s2 := stack.New[int](
    stack.WithShrinkHeuristics[int](0, 0),
)
Concurrency

All methods are thread-safe. You can safely use a single stack instance across multiple goroutines.

s := stack.New[int]()
var wg sync.WaitGroup

// Producer goroutine
wg.Add(1)
go func() {
    defer wg.Done()
    for i := 0; i < 1000; i++ {
        s.Push(i)
    }
}()

// Consumer goroutine
wg.Add(1)
go func() {
    defer wg.Done()
    for i := 0; i < 1000; i++ {
        // Note: In a real-world scenario, you'd handle the error
        // and the possibility that the stack is empty.
        s.Pop()
    }
}()

wg.Wait()
fmt.Println("Done. Stack is empty:", s.IsEmpty())

Directories

Path Synopsis
Package stack provides a generic, thread-safe, last-in-first-out (LIFO) stack data structure.
Package stack provides a generic, thread-safe, last-in-first-out (LIFO) stack data structure.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL