blob: 2d90704cc9f969aad8c695c6d9634d7378c5760c [file] [log] [blame]
ss412g286ce412019-07-04 14:00:29 +03001package common
2
3import (
4 "sync/atomic"
5)
6
7type Pool struct {
8 New func() interface{}
9 Destroy func(interface{})
10 pool chan interface{}
11 created int32 //Number of objects created
12}
13
14/*
15NewPool creates thread safe Pool object and returns a pointer to it.
16poolSize int - sets the capacity of the pool
17newObj func - specifies a function to generate a value (pool element)
18destroyObj func - specifies a function to destroy a value (pool element)
19*/
20func NewPool(poolSize int, newObj func() interface{}, destroyObj func(interface{})) *Pool{
21 return &Pool{
22 New: newObj,
23 Destroy: destroyObj,
24 pool: make(chan interface{}, poolSize),
25 }
26}
27
28/*
29Retrieve an object from the pool.
30If the pool is empty and the number of used object is less than capacity, a new object is created by calling New.
31Otherwise, the method blocks until an object is returned to the pool.
32*/
33func (p *Pool) Get() interface{} {
34 select {
35 case obj := <-p.pool:
36 return obj
37 default:
38 if atomic.AddInt32(&p.created, 1) <= int32(cap(p.pool)) && p.New != nil {
39 p.pool <- p.New()
40 }
41 }
42 return <-p.pool //block waiting
43}
44
45/*
46Return an object to the pool.
47If capacity is exceeded the object is discarded after calling Destroy on it if Destroy is not nil.
48*/
49func (p *Pool) Put(obj interface{}) {
50 if obj != nil {
51 select {
52 case p.pool <- obj:
53 default:
54 if p.Destroy != nil {
55 p.Destroy(obj)
56 }
57 }
58 }
59}
60
61/*
62 Closes the pool and if Destroy is not nil, call Destroy on each object in the pool
63 The pool must not be used once this method is called.
64*/
65func (p *Pool) Close() {
66 close(p.pool)
67 available := len(p.pool)
68 if p.Destroy != nil {
69 for obj := range p.pool {
70 p.Destroy(obj)
71
72 }
73 }
74 atomic.AddInt32(&p.created, -int32(available))
75}
76/*
77Return statistics.
78available - the number of available instances
79created - the number of created instances
80*/
81func (p *Pool) Stats() (available int, created int) {
82 return len(p.pool), int(p.created)
83}