MCPcopy Index your code
hub / github.com/AlexsanderHamir/GenPool

github.com/AlexsanderHamir/GenPool @v1.6.8

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.6.8 ↗ · + Follow
103 symbols 485 edges 8 files 69 documented · 67%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

GenPool

A sharded, generic object pool for Go with configurable growth and cleanup. It outperforms sync.Pool when objects are held longer between Get and Put, at the cost of extra overhead when retention is very short.

GoDoc Build Go Report Card License: MIT


Table of Contents


Installation

go get github.com/AlexsanderHamir/GenPool

Quick Start

  1. Define a type that embeds pool.Fields[YourType] so it implements Poolable.
  2. Provide an allocator and a cleaner (called on each Put).
  3. Create the pool with NewPool or NewPoolWithConfig and call Get/Put.
package main

import (
    "github.com/AlexsanderHamir/GenPool/pool"
)

type Object struct {
    Name string
    Data []byte
    pool.Fields[Object]
}

func main() {
    allocator := func() *Object { return &Object{} }
    cleaner := func(obj *Object) { obj.Name = ""; obj.Data = obj.Data[:0] }

    p, err := pool.NewPool(allocator, cleaner)
    if err != nil {
        panic(err)
    }
    defer p.Close()

    obj := p.Get()
    obj.Name = "example"
    obj.Data = append(obj.Data, 1, 2, 3)
    p.Put(obj)
}

With custom cleanup and growth:

config := pool.Config[Object, *Object]{
    Cleanup:   pool.DefaultCleanupPolicy(pool.GcModerate),
    Allocator: allocator,
    Cleaner:   cleaner,
    Growth: pool.GrowthPolicy{
        Enable:      true,
        MaxPoolSize: 1000,
    },
}
p, err := pool.NewPoolWithConfig(config)

Concepts

  • Sharding — The pool is split into multiple shards, each with its own lock-free list to reduce contention; the number of shards is set via Config.NumShards (defaulting to runtime.GOMAXPROCS(0) at creation) and can be overridden with a positive value for testing or tuning.
  • Growth — Without a growth policy, the pool grows unbounded. With GrowthPolicy.Enable and MaxPoolSize, Get returns nil when the cap is reached.
  • Cleanup — Optional background goroutine that periodically evicts objects whose usage count is below MinUsageCount. Disabled by default; enable via CleanupPolicy or DefaultCleanupPolicy(level).

Configuration

Cleanup policy

Level Interval MinUsageCount Use case
GcDisable No automatic cleanup
GcLow 10m 1 High reuse, low churn
GcModerate 2m 2 Default balance
GcAggressive 30s 3 Memory-sensitive / bursty
Cleanup: pool.DefaultCleanupPolicy(pool.GcModerate)

Or build a policy manually:

Cleanup: pool.CleanupPolicy{
    Enabled:       true,
    Interval:      2 * time.Minute,
    MinUsageCount: 2,
}

Growth policy

Limit pool size so Get returns nil when full:

Growth: pool.GrowthPolicy{
    Enable:      true,
    MaxPoolSize: 5000,
}

If Enable is false, the pool has no size limit and relies on cleanup (if enabled) for reclaiming memory.

Performance

Benchmarks (darwin/arm64, Apple M1) show GenPool ahead when objects are held longer; sync.Pool can win when retention is very short.

Tip: Keep pool.Fields[Object] on its own cache line (e.g. add padding) to reduce false sharing under contention.

Docs: Design · Cleanup

Manual Control

Disable automatic cleanup with GcDisable. You can then implement custom eviction by using the exported ShardedPool.Shards and each Shard's Head (and Single) to traverse or clear lists. The pool does not lock these; coordinate with Get/Put usage as needed.

Contributing

  • Go 1.24+ required.
  • Run tests and benchmarks before changing behavior: go test ./... and go test -bench=. ./....
  • Add tests for new behavior and update docs for user-facing changes.
  • All CI checks must pass for PRs to be merged.
git clone https://github.com/AlexsanderHamir/GenPool.git
cd GenPool
go test -v ./...
golangci-lint run  # optional

License

MIT. See LICENSE.

Extension points exported contracts — how you extend this code

Allocator (FuncType)
Allocator creates new objects for the pool.
pool/poolable.go
Cleaner (FuncType)
Cleaner prepares an object before it is returned to the pool.
pool/poolable.go
Poolable (Interface)
Poolable is the interface required to store objects in the pool.
pool/poolable.go

Core symbols most depended-on inside this repo

Get
called by 58
pool/pool.go
Close
called by 34
pool/pool.go
Put
called by 33
pool/pool.go
IncrementUsage
called by 27
pool/poolable.go
SetNext
called by 24
pool/poolable.go
NewPool
called by 18
pool/pool.go
NewPoolWithConfig
called by 17
pool/pool.go
GetUsageCount
called by 14
pool/poolable.go

Shape

Function 62
Method 26
Struct 11
FuncType 2
Interface 1
TypeAlias 1

Languages

Go100%

Modules by API surface

pool/unit_test.go37 symbols
pool/poolable.go18 symbols
pool/pool.go11 symbols
pool/reported_issues/contract_test.go10 symbols
pool/config.go8 symbols
test/blackbox_test.go7 symbols
test/pool_benchmark_test.go6 symbols
pool/cleanup.go6 symbols

For agents

$ claude mcp add GenPool \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact