diff --git a/pool.go b/pool.go index d15d377..cb41bb9 100644 --- a/pool.go +++ b/pool.go @@ -7,7 +7,7 @@ import ( ) const ( - minBitSize = 6 + minBitSize = 6 // CPU cache line size steps = 20 minSize = 1 << minBitSize @@ -38,12 +38,7 @@ func (p *byteBufferPool) Acquire() *ByteBuffer { } func (p *byteBufferPool) Release(b *ByteBuffer) { - idx := bitSize(len(b.B)-1) - minBitSize - if idx < 0 { - idx = 0 - } else if idx >= steps { - idx = steps - 1 - } + idx := index(len(b.B)) if atomic.AddUint64(&p.calls[idx], 1) > calibrateCallsThreshold { p.calibrate() @@ -114,11 +109,16 @@ func (ci callSizes) Swap(i, j int) { ci[i], ci[j] = ci[j], ci[i] } -func bitSize(n int) int { - s := 0 +func index(n int) int { + n-- + n >>= minBitSize + idx := 0 for n > 0 { n >>= 1 - s++ + idx++ } - return s + if idx >= steps { + idx = steps - 1 + } + return idx } diff --git a/pool_test.go b/pool_test.go index a61c576..a8157a9 100644 --- a/pool_test.go +++ b/pool_test.go @@ -6,6 +6,30 @@ import ( "time" ) +func TestIndex(t *testing.T) { + testIndex(t, 0, 0) + testIndex(t, 1, 0) + + testIndex(t, minSize-1, 0) + testIndex(t, minSize, 0) + testIndex(t, minSize+1, 1) + + testIndex(t, 2*minSize-1, 1) + testIndex(t, 2*minSize, 1) + testIndex(t, 2*minSize+1, 2) + + testIndex(t, maxSize-1, steps-1) + testIndex(t, maxSize, steps-1) + testIndex(t, maxSize+1, steps-1) +} + +func testIndex(t *testing.T, n, expectedIdx int) { + idx := index(n) + if idx != expectedIdx { + t.Fatalf("unexpected idx for n=%d: %d. Expecting %d", n, idx, expectedIdx) + } +} + func TestPoolCalibrate(t *testing.T) { for i := 0; i < steps*calibrateCallsThreshold; i++ { n := 1004