Skip to content

Fast and customizable object pool, ideal for workloads that want to create less memory.

License

Notifications You must be signed in to change notification settings

AlexsanderHamir/GenPool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

263 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

Fast and customizable object pool, ideal for workloads that want to create less memory.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages