forked from erigontech/erigon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpool.go
114 lines (100 loc) · 2.27 KB
/
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
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
package cbor
import (
"fmt"
"io"
"github.com/ledgerwatch/log/v3"
"github.com/ugorji/go/codec"
)
var logger = log.New("package", "cbor")
// Pool of decoders
var decoderPool = make(chan *codec.Decoder, 128)
func Decoder(r io.Reader) *codec.Decoder {
var d *codec.Decoder
select {
case d = <-decoderPool:
d.Reset(r)
default:
{
var handle codec.CborHandle
handle.ReaderBufferSize = 64 * 1024
handle.ZeroCopy = true // if you need access to object outside of db transaction - please copy bytes before deserialization
d = codec.NewDecoder(r, &handle)
}
}
return d
}
func DecoderBytes(r []byte) *codec.Decoder {
var d *codec.Decoder
select {
case d = <-decoderPool:
d.ResetBytes(r)
default:
{
var handle codec.CborHandle
handle.ReaderBufferSize = 64 * 1024
handle.ZeroCopy = true // if you need access to object outside of db transaction - please copy bytes before deserialization
d = codec.NewDecoderBytes(r, &handle)
}
}
return d
}
func returnDecoderToPool(d *codec.Decoder) {
select {
case decoderPool <- d:
default:
logger.Trace("Allowing decoder to be garbage collected, pool is full")
}
}
// Pool of encoders
var encoderPool = make(chan *codec.Encoder, 128)
func Encoder(w io.Writer) *codec.Encoder {
var e *codec.Encoder
select {
case e = <-encoderPool:
e.Reset(w)
default:
{
var handle codec.CborHandle
handle.WriterBufferSize = 64 * 1024
handle.StructToArray = true
handle.OptimumSize = true
handle.StringToRaw = true
e = codec.NewEncoder(w, &handle)
}
}
return e
}
func EncoderBytes(w *[]byte) *codec.Encoder {
var e *codec.Encoder
select {
case e = <-encoderPool:
e.ResetBytes(w)
default:
{
var handle codec.CborHandle
handle.WriterBufferSize = 64 * 1024
handle.StructToArray = true
handle.OptimumSize = true
handle.StringToRaw = true
e = codec.NewEncoderBytes(w, &handle)
}
}
return e
}
func returnEncoderToPool(e *codec.Encoder) {
select {
case encoderPool <- e:
default:
logger.Trace("Allowing encoder to be garbage collected, pool is full")
}
}
func Return(d interface{}) {
switch toReturn := d.(type) {
case *codec.Decoder:
returnDecoderToPool(toReturn)
case *codec.Encoder:
returnEncoderToPool(toReturn)
default:
panic(fmt.Sprintf("unexpected type: %T", d))
}
}