Skip to content

Colduction/boundedpool-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

boundedpool-go

Go Reference GitHub License

Generic, exact-capacity object pool for Go 1.26.5+.

TryGet and TryPut execute no caller callbacks, allocate no memory, start no goroutines, and use bounded atomic probes. Callers explicitly own creation, reset, rejection, and cleanup policy.

Install

go get github.com/colduction/boundedpool-go@latest

Quick start

package main

import (
	"bytes"
	"errors"

	"github.com/colduction/boundedpool-go"
)

func main() {
	pool, err := boundedpool.New[*bytes.Buffer](1024)
	if err != nil {
		panic(err)
	}

	buf, err := pool.TryGet()
	switch {
	case errors.Is(err, boundedpool.ErrUnavailable):
		buf = new(bytes.Buffer)
	case errors.Is(err, boundedpool.ErrClosed):
		return
	}

	buf.WriteString("hello")
	buf.Reset()
	switch err := pool.TryPut(buf); {
	case err == nil:
		// Pool owns buf.
	case errors.Is(err, boundedpool.ErrUnavailable), errors.Is(err, boundedpool.ErrClosed):
		// Caller still owns buf and may dispose or retry it.
	}

	items, first := pool.Close()
	if first {
		for _, item := range items {
			// Dispose retained items when T owns external resources.
			_ = item
		}
	}
}

Contract

Call Result
TryGet A nil error transfers one idle item to caller.
TryPut A nil error transfers item to pool. Rejection keeps caller ownership.
Close Seals storage and returns every retained item to winning caller.
Len Approximate idle count; zero once Closed reports true.
Cap Exact maximum retained item count.
Closed Whether new operations are rejected.

ErrUnavailable means no candidate won during one bounded scan. In a quiescent pool this means empty for TryGet or full for TryPut; concurrent ownership transfers can make that observation stale immediately. Retry, create, discard, or shed according to caller policy.

Close performs no callbacks. It marks every slot closed, waits only for an ownership transfer already holding a slot, compacts retained items in the existing backing array, then returns them without allocating. Concurrent losing Close calls wait for drain completion and return nil, false. Checked-out and rejected items remain caller-owned.

An operation overlapping Close may return a transfer that linearized first or ErrClosed; it cannot access returned storage after Close finishes.

Options

Option Default Purpose
WithShardFactor 2 Requests factor × GOMAXPROCS shards.
WithNumShards Requests explicit shard count; overrides factor.

Shard count is normalized to a power of two, capped by capacity, and raised when needed to keep each shard at most 64 slots. Every call probes at most Cap slots. This preserves deterministic capacity and ownership; stable empty/full scans are O(Cap) but never wait or allocate.

Never use an item after successful TryPut, put one item twice, or copy a pool after first use. Prefer pointers for values containing mutexes, atomics, or other non-copyable state.

Compared with sync.Pool

sync.Pool may discard cached values at any GC cycle. boundedpool-go retains idle items up to exact configured capacity until Close, then returns them to caller control.

License

GNU Lesser General Public License v2.1. See LICENSE.

About

A high-performance, thread-safe, bounded object pool implementation for Go, designed as a flexible alternative to "sync.Pool"

Resources

License

Stars

4 stars

Watchers

1 watching

Forks

Contributors

Languages