1
0
mirror of https://github.com/tmrts/go-patterns.git synced 2024-11-25 06:26:06 +03:00
go-patterns/creational/object_pool.go

107 lines
1.7 KiB
Go
Raw Normal View History

2016-01-19 09:03:51 +03:00
package main
import (
"container/list"
"errors"
"log"
)
var (
ErrNoMoreObject = errors.New("no more object")
ErrNotEnoughPoolSpace = errors.New("not enough pool space")
)
2016-01-19 09:03:51 +03:00
type Object struct {
ID string
}
type Pool interface {
Borrow() (*Object, error)
Return(*Object) error
}
type Allocate func() (*Object, error)
2016-01-19 09:03:51 +03:00
type implementation struct {
Size int
Allocate Allocate
FreeList *list.List
2016-01-19 09:03:51 +03:00
}
func New(initSize int, alloc Allocate) (Pool, error) {
2016-01-19 09:03:51 +03:00
p := &implementation{
Size: initSize,
Allocate: alloc,
FreeList: list.New(),
2016-01-19 09:03:51 +03:00
}
for i := 0; i < initSize; i++ {
obj, err := p.Allocate()
if err != nil {
return nil, err
}
p.FreeList.PushFront(obj)
2016-01-19 09:03:51 +03:00
}
return p, nil
2016-01-19 09:03:51 +03:00
}
func (p *implementation) Borrow() (*Object, error) {
elem := p.FreeList.Front()
if elem == nil {
return nil, ErrNoMoreObject
}
2016-01-19 09:03:51 +03:00
obj := p.FreeList.Remove(elem)
o := obj.(*Object)
2016-01-19 09:03:51 +03:00
return o, nil
2016-01-19 09:03:51 +03:00
}
func (p *implementation) Return(ref *Object) error {
if p.FreeList.Len() == p.Size {
return ErrNotEnoughPoolSpace
}
p.FreeList.PushBack(ref)
2016-01-19 09:03:51 +03:00
return nil
}
func main() {
const poolSize = 3
p, _ := New(poolSize, func() (*Object, error) {
return &Object{}, nil
2016-01-19 09:03:51 +03:00
})
ob, err := p.Borrow()
if err != nil {
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")
}
2016-01-19 09:03:51 +03:00
}