[RICPLT-1783] Add ValidateAndBuildRanLoadInformationKey | Fix dependencies | Reformat...
[ric-plt/nodeb-rnib.git] / common / rNibPool.go
1 package common
2
3 import (
4         "sync/atomic"
5 )
6
7 type Pool struct {
8         New     func() interface{}
9         Destroy func(interface{})
10         pool    chan interface{}
11         created int32 //Number of objects created
12 }
13
14 /*
15 NewPool creates thread safe Pool object and returns a pointer to it.
16 poolSize int - sets the capacity of the pool
17 newObj func - specifies a function to generate a value (pool element)
18 destroyObj func - specifies a function to destroy a value (pool element)
19 */
20 func 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 /*
29 Retrieve an object from the pool.
30 If the pool is empty and the number of used object is less than capacity, a new object is created by calling New.
31 Otherwise, the method blocks until an object is returned to the pool.
32 */
33 func (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 /*
46 Return an object to the pool.
47 If capacity is exceeded the object is discarded after calling Destroy on it if Destroy is not nil.
48 */
49 func (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 */
65 func (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 /*
77 Return statistics.
78 available - the number of available instances
79 created - the number of created instances
80 */
81 func (p *Pool) Stats() (available int, created int) {
82         return len(p.pool), int(p.created)
83 }