-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpool.go
More file actions
115 lines (101 loc) · 2.34 KB
/
pool.go
File metadata and controls
115 lines (101 loc) · 2.34 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package memoryPool
import "math/rand"
type item []byte
type MemoryPool struct {
buffers []item
}
func NewMemoryPool(poolCap int) *MemoryPool {
if poolCap < 4 {
poolCap = 4
}
return &MemoryPool{
buffers: make([]item, 0, poolCap),
}
}
func (pool *MemoryPool) Get(bufferSize int) []byte {
if bufferSize <= 0 {
return make([]byte, 0)
}
index := searchInsert(pool.buffers, len(pool.buffers), bufferSize)
if index < 0 {
return make([]byte, bufferSize)
} else {
buffer := pool.buffers[index]
pool.buffers = append(pool.buffers[:index], pool.buffers[index+1:]...)
return buffer[:bufferSize]
}
}
func (pool *MemoryPool) Set(buffer []byte) bool {
if buffer == nil {
return false
}
pool.reset(buffer)
if pool.IsFull() {
pool.GetRandom()
}
index := searchInsert(pool.buffers, len(pool.buffers), cap(buffer))
pool.buffers = append(pool.buffers, buffer)
if index >= 0 {
for i := len(pool.buffers) - 1; i > index; i-- {
pool.buffers[i] = pool.buffers[i-1]
}
pool.buffers[index] = buffer
}
return true
}
func (pool *MemoryPool) IsFull() bool {
return len(pool.buffers) == cap(pool.buffers)
}
func (pool *MemoryPool) GetRandom() ([]byte, bool) {
index := rand.Intn(len(pool.buffers))
return pool.GetIndex(index)
}
func (pool *MemoryPool) GetIndex(index int) ([]byte, bool) {
if len(pool.buffers) == 0 || index < 0 || index >= len(pool.buffers) {
return nil, false
}
buffer := pool.buffers[index]
pool.buffers = append(pool.buffers[:index], pool.buffers[index+1:]...)
return buffer, true
}
func (pool *MemoryPool) Len() int {
return len(pool.buffers)
}
func (pool *MemoryPool) Cap() int {
return cap(pool.buffers)
}
func (pool *MemoryPool) Clear() {
pool.buffers = make([]item, 0, cap(pool.buffers))
}
func (pool *MemoryPool) reset(buffer []byte) {
i := 0
for ; i < len(buffer); i++ {
buffer[i] = 0
}
for ; i < cap(buffer); i++ {
buffer = append(buffer, 0)
}
}
func searchInsert(nums []item, size int, target int) int {
if size == 0 {
return -1
}
start, middle, end := 0, 0, size-1
for start <= end {
middle = start + (end-start)/2
if cap(nums[middle]) == target {
return middle
} else if cap(nums[middle]) > target {
end = middle - 1
} else {
start = middle + 1
}
}
if middle < size && target > cap(nums[middle]) {
if target > cap(nums[size-1]) {
return -1
}
return middle + 1
}
return middle
}