File: bufferpool.go

package info (click to toggle)
syncthing 0.14.18%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 7,388 kB
  • ctags: 4,608
  • sloc: xml: 781; sh: 271; makefile: 45
file content (59 lines) | stat: -rw-r--r-- 1,334 bytes parent folder | download
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
// Copyright (C) 2016 The Protocol Authors.

package protocol

import "sync"

type bufferPool struct {
	minSize int
	pool    sync.Pool
}

// get returns a new buffer of the requested size
func (p *bufferPool) get(size int) []byte {
	intf := p.pool.Get()
	if intf == nil {
		// Pool is empty, must allocate.
		return p.new(size)
	}

	bs := *intf.(*[]byte)
	if cap(bs) < size {
		// Buffer was too small, leave it for someone else and allocate.
		p.pool.Put(intf)
		return p.new(size)
	}

	return bs[:size]
}

// upgrade grows the buffer to the requested size, while attempting to reuse
// it if possible.
func (p *bufferPool) upgrade(bs []byte, size int) []byte {
	if cap(bs) >= size {
		// Reslicing is enough, lets go!
		return bs[:size]
	}

	// It was too small. But it pack into the pool and try to get another
	// buffer.
	p.put(bs)
	return p.get(size)
}

// put returns the buffer to the pool
func (p *bufferPool) put(bs []byte) {
	p.pool.Put(&bs)
}

// new creates a new buffer of the requested size, taking the minimum
// allocation count into account. For internal use only.
func (p *bufferPool) new(size int) []byte {
	allocSize := size
	if allocSize < p.minSize {
		// Avoid allocating tiny buffers that we won't be able to reuse for
		// anything useful.
		allocSize = p.minSize
	}
	return make([]byte, allocSize)[:size]
}