creational/object-pool: fix the implementation

This commit is contained in:
Simon Xia 2016-09-13 19:05:01 +08:00 committed by Tamer Tas
parent 4b81980a1f
commit 2ca6861294

View File

@ -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")
}
} }