File: generic.go

package info (click to toggle)
golang-github-gobwas-pool 0.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 116 kB
  • sloc: makefile: 2
file content (87 lines) | stat: -rw-r--r-- 2,193 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package pool

import (
	"sync"

	"github.com/gobwas/pool/internal/pmath"
)

var DefaultPool = New(128, 65536)

// Get pulls object whose generic size is at least of given size. It also
// returns a real size of x for further pass to Put(). It returns -1 as real
// size for nil x. Size >-1 does not mean that x is non-nil, so checks must be
// done.
//
// Note that size could be ceiled to the next power of two.
//
// Get is a wrapper around DefaultPool.Get().
func Get(size int) (interface{}, int) { return DefaultPool.Get(size) }

// Put takes x and its size for future reuse.
// Put is a wrapper around DefaultPool.Put().
func Put(x interface{}, size int) { DefaultPool.Put(x, size) }

// Pool contains logic of reusing objects distinguishable by size in generic
// way.
type Pool struct {
	pool map[int]*sync.Pool
	size func(int) int
}

// New creates new Pool that reuses objects which size is in logarithmic range
// [min, max].
//
// Note that it is a shortcut for Custom() constructor with Options provided by
// WithLogSizeMapping() and WithLogSizeRange(min, max) calls.
func New(min, max int) *Pool {
	return Custom(
		WithLogSizeMapping(),
		WithLogSizeRange(min, max),
	)
}

// Custom creates new Pool with given options.
func Custom(opts ...Option) *Pool {
	p := &Pool{
		pool: make(map[int]*sync.Pool),
		size: pmath.Identity,
	}

	c := (*poolConfig)(p)
	for _, opt := range opts {
		opt(c)
	}

	return p
}

// Get pulls object whose generic size is at least of given size.
// It also returns a real size of x for further pass to Put() even if x is nil.
// Note that size could be ceiled to the next power of two.
func (p *Pool) Get(size int) (interface{}, int) {
	n := p.size(size)
	if pool := p.pool[n]; pool != nil {
		return pool.Get(), n
	}
	return nil, size
}

// Put takes x and its size for future reuse.
func (p *Pool) Put(x interface{}, size int) {
	if pool := p.pool[size]; pool != nil {
		pool.Put(x)
	}
}

type poolConfig Pool

// AddSize adds size n to the map.
func (p *poolConfig) AddSize(n int) {
	p.pool[n] = new(sync.Pool)
}

// SetSizeMapping sets up incoming size mapping function.
func (p *poolConfig) SetSizeMapping(size func(int) int) {
	p.size = size
}