2
0

Extract int16SlicePool

This commit is contained in:
Jack Christensen
2019-05-04 11:01:09 -05:00
parent dd571cf345
commit 8b365ce37e
2 changed files with 47 additions and 15 deletions
+5 -15
View File
@@ -49,9 +49,8 @@ type Conn struct {
wbuf []byte wbuf []byte
preallocatedRows []connRows preallocatedRows []connRows
paramFormats []int16 int16SlicePool int16SlicePool
paramValues [][]byte paramValues [][]byte
resultFormats []int16
} }
// PreparedStatement is a description of a prepared statement // PreparedStatement is a description of a prepared statement
@@ -160,9 +159,7 @@ func connect(ctx context.Context, config *ConnConfig) (c *Conn, err error) {
c.doneChan = make(chan struct{}) c.doneChan = make(chan struct{})
c.closedChan = make(chan error) c.closedChan = make(chan error)
c.wbuf = make([]byte, 0, 1024) c.wbuf = make([]byte, 0, 1024)
c.paramFormats = make([]int16, 0, 16)
c.paramValues = make([][]byte, 0, 16) c.paramValues = make([][]byte, 0, 16)
c.resultFormats = make([]int16, 0, 32)
// Replication connections can't execute the queries to // Replication connections can't execute the queries to
// populate the c.PgTypes and c.pgsqlAfInet // populate the c.PgTypes and c.pgsqlAfInet
@@ -651,12 +648,7 @@ optionLoop:
return rows, rows.err return rows, rows.err
} }
var paramFormats []int16 paramFormats := c.int16SlicePool.get(len(args))
if len(args) > cap(c.paramFormats) {
paramFormats = make([]int16, len(args))
} else {
paramFormats = c.paramFormats[:len(args)]
}
var paramValues [][]byte var paramValues [][]byte
if len(args) > cap(c.paramValues) { if len(args) > cap(c.paramValues) {
@@ -682,11 +674,7 @@ optionLoop:
} }
if resultFormats == nil { if resultFormats == nil {
if len(ps.FieldDescriptions) > cap(c.resultFormats) { resultFormats = c.int16SlicePool.get(len(ps.FieldDescriptions))
resultFormats = make([]int16, len(ps.FieldDescriptions))
} else {
resultFormats = c.resultFormats[:len(ps.FieldDescriptions)]
}
for i := range resultFormats { for i := range resultFormats {
if dt, ok := c.ConnInfo.DataTypeForOID(ps.FieldDescriptions[i].DataType); ok { if dt, ok := c.ConnInfo.DataTypeForOID(ps.FieldDescriptions[i].DataType); ok {
@@ -701,6 +689,8 @@ optionLoop:
rows.resultReader = c.pgConn.ExecPrepared(ctx, ps.Name, paramValues, paramFormats, resultFormats) rows.resultReader = c.pgConn.ExecPrepared(ctx, ps.Name, paramValues, paramFormats, resultFormats)
c.int16SlicePool.reset()
return rows, rows.err return rows, rows.err
} }
+42
View File
@@ -0,0 +1,42 @@
package pgx
const int16SlicePoolSizeStep = 16
type int16SlicePool struct {
buf []int16
pos int
allocCount int
resetCount int
}
func (p *int16SlicePool) get(n int) []int16 {
if n > len(p.buf[p.pos:]) {
growthStep := ((n / int16SlicePoolSizeStep) + 1) * int16SlicePoolSizeStep
p.buf = make([]int16, len(p.buf)+growthStep)
p.pos = 0
}
result := p.buf[p.pos : p.pos+n]
p.pos += n
p.allocCount += n
return result
}
func (p *int16SlicePool) reset() {
p.pos = 0
p.resetCount += 1
if p.resetCount == 128 {
allocsPerReset := p.allocCount / p.resetCount
maxSize := allocsPerReset + (int16SlicePoolSizeStep * 4)
if len(p.buf) > maxSize {
p.buf = make([]int16, maxSize)
}
p.allocCount = 0
p.resetCount = 0
}
}