aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool_test.go
blob: a293f9754a8a0cf5e3a661dddf5bfb07afc2df5f (plain) (blame)
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 iobufpool_test

import (
	"testing"

	"github.com/jackc/pgx/v5/internal/iobufpool"
	"github.com/stretchr/testify/assert"
)

func TestGetCap(t *testing.T) {
	tests := []struct {
		requestedLen int
		expectedCap  int
	}{
		{requestedLen: 0, expectedCap: 256},
		{requestedLen: 128, expectedCap: 256},
		{requestedLen: 255, expectedCap: 256},
		{requestedLen: 256, expectedCap: 256},
		{requestedLen: 257, expectedCap: 512},
		{requestedLen: 511, expectedCap: 512},
		{requestedLen: 512, expectedCap: 512},
		{requestedLen: 513, expectedCap: 1024},
		{requestedLen: 1023, expectedCap: 1024},
		{requestedLen: 1024, expectedCap: 1024},
		{requestedLen: 33554431, expectedCap: 33554432},
		{requestedLen: 33554432, expectedCap: 33554432},

		// Above 32 MiB skip the pool and allocate exactly the requested size.
		{requestedLen: 33554433, expectedCap: 33554433},
	}
	for _, tt := range tests {
		buf := iobufpool.Get(tt.requestedLen)
		assert.Equalf(t, tt.requestedLen, len(*buf), "bad len for requestedLen: %d", len(*buf), tt.requestedLen)
		assert.Equalf(t, tt.expectedCap, cap(*buf), "bad cap for requestedLen: %d", tt.requestedLen)
	}
}

func TestPutHandlesWrongSizedBuffers(t *testing.T) {
	for putBufSize := range []int{0, 1, 128, 250, 256, 257, 1023, 1024, 1025, 1 << 28} {
		putBuf := make([]byte, putBufSize)
		iobufpool.Put(&putBuf)

		tests := []struct {
			requestedLen int
			expectedCap  int
		}{
			{requestedLen: 0, expectedCap: 256},
			{requestedLen: 128, expectedCap: 256},
			{requestedLen: 255, expectedCap: 256},
			{requestedLen: 256, expectedCap: 256},
			{requestedLen: 257, expectedCap: 512},
			{requestedLen: 511, expectedCap: 512},
			{requestedLen: 512, expectedCap: 512},
			{requestedLen: 513, expectedCap: 1024},
			{requestedLen: 1023, expectedCap: 1024},
			{requestedLen: 1024, expectedCap: 1024},
			{requestedLen: 33554431, expectedCap: 33554432},
			{requestedLen: 33554432, expectedCap: 33554432},

			// Above 32 MiB skip the pool and allocate exactly the requested size.
			{requestedLen: 33554433, expectedCap: 33554433},
		}
		for _, tt := range tests {
			getBuf := iobufpool.Get(tt.requestedLen)
			assert.Equalf(t, tt.requestedLen, len(*getBuf), "len(putBuf): %d, requestedLen: %d", len(putBuf), tt.requestedLen)
			assert.Equalf(t, tt.expectedCap, cap(*getBuf), "cap(putBuf): %d, requestedLen: %d", cap(putBuf), tt.requestedLen)
		}
	}
}

func TestPutGetBufferReuse(t *testing.T) {
	// There is no way to guarantee a buffer will be reused. It should be, but a GC between the Put and the Get will cause
	// it not to be. So try many times.
	for i := 0; i < 100000; i++ {
		buf := iobufpool.Get(4)
		(*buf)[0] = 1
		iobufpool.Put(buf)
		buf = iobufpool.Get(4)
		if (*buf)[0] == 1 {
			return
		}
	}

	t.Error("buffer was never reused")
}