mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-25 06:16:03 +03:00
creational/object-pool: fix the implementation
This commit is contained in:
parent
4b81980a1f
commit
2ca6861294
@ -1,6 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "container/list"
|
import (
|
||||||
|
"container/list"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNoMoreObject = errors.New("no more object")
|
||||||
|
ErrNotEnoughPoolSpace = errors.New("not enough pool space")
|
||||||
|
)
|
||||||
|
|
||||||
type Object struct {
|
type Object struct {
|
||||||
ID string
|
ID string
|
||||||
@ -11,23 +20,19 @@ type Pool interface {
|
|||||||
Return(*Object) error
|
Return(*Object) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Allocate func() (Object, error)
|
type Allocate func() (*Object, error)
|
||||||
|
|
||||||
type implementation struct {
|
type implementation struct {
|
||||||
Size int
|
Size int
|
||||||
SizeLimit int
|
Allocate Allocate
|
||||||
Allocate Allocate
|
FreeList *list.List
|
||||||
Objects map[Object]bool
|
|
||||||
FreeList *list.List
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(initSize int, limit int, alloc Allocate) (*Pool, error) {
|
func New(initSize int, alloc Allocate) (Pool, error) {
|
||||||
p := &implementation{
|
p := &implementation{
|
||||||
Size: initSize,
|
Size: initSize,
|
||||||
SizeLimit: limit,
|
Allocate: alloc,
|
||||||
Allocate: alloc,
|
FreeList: list.New(),
|
||||||
Objects: nil,
|
|
||||||
FreeList: list.New(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < initSize; i++ {
|
for i := 0; i < initSize; i++ {
|
||||||
@ -36,37 +41,66 @@ func New(initSize int, limit int, alloc Allocate) (*Pool, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.FreeList.PushFront(&obj)
|
p.FreeList.PushFront(obj)
|
||||||
|
|
||||||
p.Objects[obj] = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *implementation) Borrow() (*Object, error) {
|
func (p *implementation) Borrow() (*Object, error) {
|
||||||
elem := p.FreeList.Front()
|
elem := p.FreeList.Front()
|
||||||
|
if elem == nil {
|
||||||
|
return nil, ErrNoMoreObject
|
||||||
|
}
|
||||||
|
|
||||||
obj := p.FreeList.Remove(elem)
|
obj := p.FreeList.Remove(elem)
|
||||||
|
|
||||||
p.Objects[obj] = false
|
o := obj.(*Object)
|
||||||
|
|
||||||
return obj, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *implementation) Return(ref *Object) error {
|
func (p *implementation) Return(ref *Object) error {
|
||||||
list.PushBack(ref)
|
if p.FreeList.Len() == p.Size {
|
||||||
|
return ErrNotEnoughPoolSpace
|
||||||
p.Objects[*ref] = true
|
}
|
||||||
|
p.FreeList.PushBack(ref)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p := New(0, 0, func() (Object, error) {
|
const poolSize = 3
|
||||||
return []string{}
|
|
||||||
|
p, _ := New(poolSize, func() (*Object, error) {
|
||||||
|
return &Object{}, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
s, _ := p.Borrow()
|
ob, err := p.Borrow()
|
||||||
s = append(s, "string")
|
if err != nil {
|
||||||
_ = p.Return(s)
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Printf("borrow a object from pool: %#v\n", *ob)
|
||||||
|
|
||||||
|
for i := 0; i < poolSize-1; i++ {
|
||||||
|
o, err := p.Borrow()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Printf("borrow a object from pool: %#v\n", *o)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = p.Borrow()
|
||||||
|
if err.Error() != ErrNoMoreObject.Error() {
|
||||||
|
log.Fatalf("expect: %v\n", ErrNoMoreObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Return(ob)
|
||||||
|
ob1, err := p.Borrow()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ob != ob1 {
|
||||||
|
log.Fatal("expect the same object")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user