package util import ( "math" "math/bits" "sync" "testing" ) // --- poolIndex / putIndex unit tests --- func TestPoolIndex(t *testing.T) { cases := []struct { length int want int }{ {1, 0}, {2, 1}, {3, 2}, {4, 2}, {5, 3}, {7, 3}, {8, 3}, {255, 8}, {256, 8}, {1023, 10}, {1024, 10}, {math.MaxUint16 - 50, 16}, } for _, c := range cases { got := poolIndex(c.length) if got != c.want { t.Errorf("poolIndex(%d) = %d, want %d", c.length, got, c.want) } } } func TestAllocMinusOne(t *testing.T) { bp := newBufferPool() for i := 1; i <= 16; i++ { capacity := 1 << i length := capacity - 1 if length <= 0 { continue } b := bp.Get(length) c := cap(b) pIndex := poolIndex(length) rIndex := putIndex(c) if pIndex != rIndex { t.Errorf("pIndex: %d != rIndex: %d\n", pIndex, rIndex) } } } func TestPutIndex(t *testing.T) { // putIndex must be the inverse of poolIndex for all power-of-two capacities // that Get hands out. for i := 1; i <= 16; i++ { cap := 1 << i got := putIndex(cap) if got != i { t.Errorf("putIndex(1<<%d = %d) = %d, want %d", i, cap, got, i) } } } func TestPoolIndexPutIndexRoundTrip(t *testing.T) { // For any requested length, the buffer Get returns has capacity 1<= 17 { t.Errorf("poolIndex(MaxUint16) = %d, overflows pool array", i) } } // --- Benchmarks --- func BenchmarkGetPut(b *testing.B) { sizes := []int{64, 512, 4096, 65535} for _, size := range sizes { bp := newBufferPool() b.Run("", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { buf := bp.Get(size) bp.Put(buf) } }) } } func BenchmarkGetPutParallel(b *testing.B) { bp := newBufferPool() b.ReportAllocs() b.RunParallel(func(pb *testing.PB) { for pb.Next() { buf := bp.Get(4096) bp.Put(buf) } }) }