-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathobject_pool.go
85 lines (72 loc) · 1.58 KB
/
object_pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main
import (
"container/list"
"fmt"
"strconv"
"sync"
)
var (
uniqueID int
)
type PooledObject struct {
id int
}
func (o *PooledObject) String() string {
return "PooledObject [id=" + strconv.Itoa(o.id) + "]"
}
type ObjectPool struct {
mu sync.Mutex
idle *list.List
active *list.List
}
func NewObjectPool() *ObjectPool {
idle := list.New()
active := list.New()
return &ObjectPool{idle: idle, active: active}
}
func (p *ObjectPool) BorrowObject() *PooledObject {
p.mu.Lock()
defer p.mu.Unlock()
var object *PooledObject
if p.idle.Len() <= 0 {
object = &PooledObject{uniqueID}
uniqueID++
} else {
object = p.removeAt(p.idle, 0)
}
fmt.Printf("Borrow: %s\n", object)
p.active.PushBack(object)
return object
}
func (p *ObjectPool) ReturnObject(object *PooledObject) {
p.mu.Lock()
defer p.mu.Unlock()
fmt.Printf("Return: %s\n", object)
p.idle.PushBack(object)
p.remove(p.active, object)
}
func (p *ObjectPool) remove(list *list.List, object *PooledObject) {
for e := list.Front(); e != nil; e = e.Next() {
if object == e.Value.(*PooledObject) {
list.Remove(e)
return
}
}
}
func (p *ObjectPool) removeAt(list *list.List, index int) *PooledObject {
for e, i := list.Front(), 0; e != nil; e, i = e.Next(), i+1 {
if index == i {
return list.Remove(e).(*PooledObject)
}
}
return nil
}
func main() {
objectPool := NewObjectPool()
object1 := objectPool.BorrowObject()
objectPool.ReturnObject(object1)
object2 := objectPool.BorrowObject()
object3 := objectPool.BorrowObject()
objectPool.ReturnObject(object2)
objectPool.ReturnObject(object3)
}