Convert allResources from map to array
This commit is contained in:
@@ -32,22 +32,23 @@ func (res *Resource) Value() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (res *Resource) Release() {
|
func (res *Resource) Release() {
|
||||||
res.pool.releaseBorrowedResource(res.value)
|
res.pool.releaseBorrowedResource(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (res *Resource) Destroy() {
|
func (res *Resource) Destroy() {
|
||||||
res.pool.destroyBorrowedResource(res.value)
|
res.pool.destroyBorrowedResource(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pool is a thread-safe resource pool.
|
// Pool is a thread-safe resource pool.
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
cond *sync.Cond
|
cond *sync.Cond
|
||||||
|
|
||||||
allResources map[interface{}]*Resource
|
allResources []*Resource
|
||||||
availableResources []*Resource
|
availableResources []*Resource
|
||||||
minSize int
|
|
||||||
maxSize int
|
minSize int
|
||||||
closed bool
|
maxSize int
|
||||||
|
closed bool
|
||||||
|
|
||||||
createRes CreateFunc
|
createRes CreateFunc
|
||||||
closeRes CloseFunc
|
closeRes CloseFunc
|
||||||
@@ -55,11 +56,10 @@ type Pool struct {
|
|||||||
|
|
||||||
func NewPool(createRes CreateFunc, closeRes CloseFunc) *Pool {
|
func NewPool(createRes CreateFunc, closeRes CloseFunc) *Pool {
|
||||||
return &Pool{
|
return &Pool{
|
||||||
cond: sync.NewCond(new(sync.Mutex)),
|
cond: sync.NewCond(new(sync.Mutex)),
|
||||||
allResources: make(map[interface{}]*Resource),
|
maxSize: maxInt,
|
||||||
maxSize: maxInt,
|
createRes: createRes,
|
||||||
createRes: createRes,
|
closeRes: closeRes,
|
||||||
closeRes: closeRes,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +69,9 @@ func (p *Pool) Close() {
|
|||||||
p.cond.L.Lock()
|
p.cond.L.Lock()
|
||||||
p.closed = true
|
p.closed = true
|
||||||
|
|
||||||
for _, rw := range p.availableResources {
|
for _, res := range p.availableResources {
|
||||||
p.closeRes(rw.value)
|
p.closeRes(res.value)
|
||||||
delete(p.allResources, rw.value)
|
p.allResources = removeResource(p.allResources, res)
|
||||||
}
|
}
|
||||||
p.availableResources = nil
|
p.availableResources = nil
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
@@ -154,23 +154,22 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) {
|
|||||||
|
|
||||||
// If there is room to create a resource do so
|
// If there is room to create a resource do so
|
||||||
if len(p.allResources) < p.maxSize {
|
if len(p.allResources) < p.maxSize {
|
||||||
var localVal int
|
res := &Resource{pool: p, status: resourceStatusCreating}
|
||||||
placeholder := &localVal
|
p.allResources = append(p.allResources, res)
|
||||||
p.allResources[placeholder] = &Resource{value: placeholder, status: resourceStatusCreating}
|
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
|
|
||||||
res, err := p.createRes(ctx)
|
value, err := p.createRes(ctx)
|
||||||
p.cond.L.Lock()
|
p.cond.L.Lock()
|
||||||
delete(p.allResources, placeholder)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
p.allResources = removeResource(p.allResources, res)
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rw := &Resource{pool: p, value: res, status: resourceStatusBorrowed}
|
res.value = value
|
||||||
p.allResources[res] = rw
|
res.status = resourceStatusBorrowed
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
return rw, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
|
|
||||||
@@ -191,7 +190,7 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-abortWaitResChan:
|
case <-abortWaitResChan:
|
||||||
p.releaseBorrowedResource(rw.value)
|
p.releaseBorrowedResource(rw)
|
||||||
case waitResChan <- rw:
|
case waitResChan <- rw:
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -218,20 +217,18 @@ func (p *Pool) lockedAvailableAcquire() *Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// releaseBorrowedResource returns res to the the pool.
|
// releaseBorrowedResource returns res to the the pool.
|
||||||
func (p *Pool) releaseBorrowedResource(res interface{}) {
|
func (p *Pool) releaseBorrowedResource(res *Resource) {
|
||||||
p.cond.L.Lock()
|
p.cond.L.Lock()
|
||||||
|
|
||||||
rw := p.allResources[res]
|
|
||||||
|
|
||||||
if p.closed {
|
if p.closed {
|
||||||
delete(p.allResources, rw.value)
|
p.allResources = removeResource(p.allResources, res)
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
go p.closeRes(rw.value)
|
go p.closeRes(res.value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rw.status = resourceStatusAvailable
|
res.status = resourceStatusAvailable
|
||||||
p.availableResources = append(p.availableResources, rw)
|
p.availableResources = append(p.availableResources, res)
|
||||||
|
|
||||||
p.cond.L.Unlock()
|
p.cond.L.Unlock()
|
||||||
p.cond.Signal()
|
p.cond.Signal()
|
||||||
@@ -239,17 +236,22 @@ func (p *Pool) releaseBorrowedResource(res interface{}) {
|
|||||||
|
|
||||||
// Remove removes res from the pool and closes it. If res is not part of the
|
// Remove removes res from the pool and closes it. If res is not part of the
|
||||||
// pool Remove will panic.
|
// pool Remove will panic.
|
||||||
func (p *Pool) destroyBorrowedResource(res interface{}) {
|
func (p *Pool) destroyBorrowedResource(res *Resource) {
|
||||||
p.cond.L.Lock()
|
p.cond.L.Lock()
|
||||||
defer p.cond.L.Unlock()
|
p.allResources = removeResource(p.allResources, res)
|
||||||
|
p.cond.L.Unlock()
|
||||||
rw, present := p.allResources[res]
|
|
||||||
if !present {
|
|
||||||
panic("Remove called on resource that does not belong to pool")
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(p.allResources, rw.value)
|
|
||||||
|
|
||||||
// close the resource in the background
|
// close the resource in the background
|
||||||
go p.closeRes(res)
|
go p.closeRes(res.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeResource(slice []*Resource, res *Resource) []*Resource {
|
||||||
|
for i := range slice {
|
||||||
|
if slice[i] == res {
|
||||||
|
slice[i] = slice[len(slice)-1]
|
||||||
|
return slice[:len(slice)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return slice
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,7 +270,6 @@ func BenchmarkPoolAcquireAndRelease(b *testing.B) {
|
|||||||
{8, 16},
|
{8, 16},
|
||||||
{8, 32},
|
{8, 32},
|
||||||
{8, 64},
|
{8, 64},
|
||||||
{8, 64},
|
|
||||||
{8, 128},
|
{8, 128},
|
||||||
{8, 256},
|
{8, 256},
|
||||||
{8, 512},
|
{8, 512},
|
||||||
@@ -283,7 +282,6 @@ func BenchmarkPoolAcquireAndRelease(b *testing.B) {
|
|||||||
{64, 16},
|
{64, 16},
|
||||||
{64, 32},
|
{64, 32},
|
||||||
{64, 64},
|
{64, 64},
|
||||||
{64, 64},
|
|
||||||
{64, 128},
|
{64, 128},
|
||||||
{64, 256},
|
{64, 256},
|
||||||
{64, 512},
|
{64, 512},
|
||||||
@@ -296,7 +294,6 @@ func BenchmarkPoolAcquireAndRelease(b *testing.B) {
|
|||||||
{512, 16},
|
{512, 16},
|
||||||
{512, 32},
|
{512, 32},
|
||||||
{512, 64},
|
{512, 64},
|
||||||
{512, 64},
|
|
||||||
{512, 128},
|
{512, 128},
|
||||||
{512, 256},
|
{512, 256},
|
||||||
{512, 512},
|
{512, 512},
|
||||||
|
|||||||
Reference in New Issue
Block a user