package bytespool

import (
	"bufio"
	"bytes"
	"github.com/CAFxX/bytespool/internal"
	"io"
	"net/http/httputil"
	"sync"
)

var buckets = [...]int{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216}

var pool256 sync.Pool  
var poolb256 sync.Pool 
var poolr256 sync.Pool 
var poolw256 sync.Pool 

func get256() *[]byte {
	p, _ := pool256.Get().(*[]byte)
	return p
}

func getb256() *bytes.Buffer {
	b, _ := poolb256.Get().(*bytes.Buffer)
	return b
}

func getr256() *bufio.Reader {
	r, _ := poolr256.Get().(*bufio.Reader)
	return r
}

func getw256() *bufio.Writer {
	w, _ := poolw256.Get().(*bufio.Writer)
	return w
}

func put256(b *[]byte) {
	pool256.Put(b)
}

func putb256(b *bytes.Buffer) {
	poolb256.Put(b)
}

func putr256(r *bufio.Reader) {
	poolr256.Put(r)
}

func putw256(w *bufio.Writer) {
	poolw256.Put(w)
}

func GetBytesBuffer256() *bytes.Buffer {
	if b := getb256(); b != nil {
		return b
	}
	if p := get256(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 256))
}

func GetBytesSlice256() []byte {
	if p := get256(); p != nil {
		return internal.Puts(p)
	}
	if b := getb256(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 256)
	return p
}

func GetBytesSlicePtr256() *[]byte {
	if p := get256(); p != nil {
		return p
	}
	if b := getb256(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 256)
	return &p
}

func GetBufioReader256(pr io.Reader) *bufio.Reader {
	if r := getr256(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 256)
}

func GetBufioWriter256(pw io.Writer) *bufio.Writer {
	if w := getw256(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 256)
}

func PutBytesBuffer256(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 256 || l >= 512 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb256(b)
	return true
}

func PutBytesSlice256(p []byte) bool {
	if l := cap(p); l < 256 || l >= 512 {
		return PutBytesSlice(p)
	}
	p = p[0:256]
	put256(internal.Gets(p))
	return true
}

func PutBytesSlicePtr256(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 256 || l >= 512 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:256]
	put256(p)
	return true
}

func PutBufioReader256(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 256 || l >= 512 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr256(r)
	return true
}

func PutBufioWriter256(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 256 || l >= 512 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw256(w)
	return true
}

type BufferPool256 struct {
	httputil.BufferPool
}

func (_ BufferPool256) Get() []byte {
	return GetBytesSlice256()
}

func (_ BufferPool256) Put(b []byte) {
	PutBytesSlice256(b)
}

type BufferPtrPool256 struct{}

func (_ BufferPtrPool256) Get() *[]byte {
	return GetBytesSlicePtr256()
}

func (_ BufferPtrPool256) Put(b *[]byte) {
	PutBytesSlicePtr256(b)
}

var pool512 sync.Pool  
var poolb512 sync.Pool 
var poolr512 sync.Pool 
var poolw512 sync.Pool 

func get512() *[]byte {
	p, _ := pool512.Get().(*[]byte)
	return p
}

func getb512() *bytes.Buffer {
	b, _ := poolb512.Get().(*bytes.Buffer)
	return b
}

func getr512() *bufio.Reader {
	r, _ := poolr512.Get().(*bufio.Reader)
	return r
}

func getw512() *bufio.Writer {
	w, _ := poolw512.Get().(*bufio.Writer)
	return w
}

func put512(b *[]byte) {
	pool512.Put(b)
}

func putb512(b *bytes.Buffer) {
	poolb512.Put(b)
}

func putr512(r *bufio.Reader) {
	poolr512.Put(r)
}

func putw512(w *bufio.Writer) {
	poolw512.Put(w)
}

func GetBytesBuffer512() *bytes.Buffer {
	if b := getb512(); b != nil {
		return b
	}
	if p := get512(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 512))
}

func GetBytesSlice512() []byte {
	if p := get512(); p != nil {
		return internal.Puts(p)
	}
	if b := getb512(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 512)
	return p
}

func GetBytesSlicePtr512() *[]byte {
	if p := get512(); p != nil {
		return p
	}
	if b := getb512(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 512)
	return &p
}

func GetBufioReader512(pr io.Reader) *bufio.Reader {
	if r := getr512(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 512)
}

func GetBufioWriter512(pw io.Writer) *bufio.Writer {
	if w := getw512(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 512)
}

func PutBytesBuffer512(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 512 || l >= 1024 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb512(b)
	return true
}

func PutBytesSlice512(p []byte) bool {
	if l := cap(p); l < 512 || l >= 1024 {
		return PutBytesSlice(p)
	}
	p = p[0:512]
	put512(internal.Gets(p))
	return true
}

func PutBytesSlicePtr512(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 512 || l >= 1024 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:512]
	put512(p)
	return true
}

func PutBufioReader512(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 512 || l >= 1024 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr512(r)
	return true
}

func PutBufioWriter512(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 512 || l >= 1024 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw512(w)
	return true
}

type BufferPool512 struct {
	httputil.BufferPool
}

func (_ BufferPool512) Get() []byte {
	return GetBytesSlice512()
}

func (_ BufferPool512) Put(b []byte) {
	PutBytesSlice512(b)
}

type BufferPtrPool512 struct{}

func (_ BufferPtrPool512) Get() *[]byte {
	return GetBytesSlicePtr512()
}

func (_ BufferPtrPool512) Put(b *[]byte) {
	PutBytesSlicePtr512(b)
}

var pool1K sync.Pool  
var poolb1K sync.Pool 
var poolr1K sync.Pool 
var poolw1K sync.Pool 

func get1K() *[]byte {
	p, _ := pool1K.Get().(*[]byte)
	return p
}

func getb1K() *bytes.Buffer {
	b, _ := poolb1K.Get().(*bytes.Buffer)
	return b
}

func getr1K() *bufio.Reader {
	r, _ := poolr1K.Get().(*bufio.Reader)
	return r
}

func getw1K() *bufio.Writer {
	w, _ := poolw1K.Get().(*bufio.Writer)
	return w
}

func put1K(b *[]byte) {
	pool1K.Put(b)
}

func putb1K(b *bytes.Buffer) {
	poolb1K.Put(b)
}

func putr1K(r *bufio.Reader) {
	poolr1K.Put(r)
}

func putw1K(w *bufio.Writer) {
	poolw1K.Put(w)
}

func GetBytesBuffer1K() *bytes.Buffer {
	if b := getb1K(); b != nil {
		return b
	}
	if p := get1K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 1024))
}

func GetBytesSlice1K() []byte {
	if p := get1K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb1K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 1024)
	return p
}

func GetBytesSlicePtr1K() *[]byte {
	if p := get1K(); p != nil {
		return p
	}
	if b := getb1K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 1024)
	return &p
}

func GetBufioReader1K(pr io.Reader) *bufio.Reader {
	if r := getr1K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 1024)
}

func GetBufioWriter1K(pw io.Writer) *bufio.Writer {
	if w := getw1K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 1024)
}

func PutBytesBuffer1K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 1024 || l >= 2048 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb1K(b)
	return true
}

func PutBytesSlice1K(p []byte) bool {
	if l := cap(p); l < 1024 || l >= 2048 {
		return PutBytesSlice(p)
	}
	p = p[0:1024]
	put1K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr1K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 1024 || l >= 2048 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:1024]
	put1K(p)
	return true
}

func PutBufioReader1K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 1024 || l >= 2048 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr1K(r)
	return true
}

func PutBufioWriter1K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 1024 || l >= 2048 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw1K(w)
	return true
}

type BufferPool1K struct {
	httputil.BufferPool
}

func (_ BufferPool1K) Get() []byte {
	return GetBytesSlice1K()
}

func (_ BufferPool1K) Put(b []byte) {
	PutBytesSlice1K(b)
}

type BufferPtrPool1K struct{}

func (_ BufferPtrPool1K) Get() *[]byte {
	return GetBytesSlicePtr1K()
}

func (_ BufferPtrPool1K) Put(b *[]byte) {
	PutBytesSlicePtr1K(b)
}

var pool2K sync.Pool  
var poolb2K sync.Pool 
var poolr2K sync.Pool 
var poolw2K sync.Pool 

func get2K() *[]byte {
	p, _ := pool2K.Get().(*[]byte)
	return p
}

func getb2K() *bytes.Buffer {
	b, _ := poolb2K.Get().(*bytes.Buffer)
	return b
}

func getr2K() *bufio.Reader {
	r, _ := poolr2K.Get().(*bufio.Reader)
	return r
}

func getw2K() *bufio.Writer {
	w, _ := poolw2K.Get().(*bufio.Writer)
	return w
}

func put2K(b *[]byte) {
	pool2K.Put(b)
}

func putb2K(b *bytes.Buffer) {
	poolb2K.Put(b)
}

func putr2K(r *bufio.Reader) {
	poolr2K.Put(r)
}

func putw2K(w *bufio.Writer) {
	poolw2K.Put(w)
}

func GetBytesBuffer2K() *bytes.Buffer {
	if b := getb2K(); b != nil {
		return b
	}
	if p := get2K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 2048))
}

func GetBytesSlice2K() []byte {
	if p := get2K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb2K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 2048)
	return p
}

func GetBytesSlicePtr2K() *[]byte {
	if p := get2K(); p != nil {
		return p
	}
	if b := getb2K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 2048)
	return &p
}

func GetBufioReader2K(pr io.Reader) *bufio.Reader {
	if r := getr2K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 2048)
}

func GetBufioWriter2K(pw io.Writer) *bufio.Writer {
	if w := getw2K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 2048)
}

func PutBytesBuffer2K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 2048 || l >= 4096 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb2K(b)
	return true
}

func PutBytesSlice2K(p []byte) bool {
	if l := cap(p); l < 2048 || l >= 4096 {
		return PutBytesSlice(p)
	}
	p = p[0:2048]
	put2K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr2K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 2048 || l >= 4096 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:2048]
	put2K(p)
	return true
}

func PutBufioReader2K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 2048 || l >= 4096 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr2K(r)
	return true
}

func PutBufioWriter2K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 2048 || l >= 4096 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw2K(w)
	return true
}

type BufferPool2K struct {
	httputil.BufferPool
}

func (_ BufferPool2K) Get() []byte {
	return GetBytesSlice2K()
}

func (_ BufferPool2K) Put(b []byte) {
	PutBytesSlice2K(b)
}

type BufferPtrPool2K struct{}

func (_ BufferPtrPool2K) Get() *[]byte {
	return GetBytesSlicePtr2K()
}

func (_ BufferPtrPool2K) Put(b *[]byte) {
	PutBytesSlicePtr2K(b)
}

var pool4K sync.Pool  
var poolb4K sync.Pool 
var poolr4K sync.Pool 
var poolw4K sync.Pool 

func get4K() *[]byte {
	p, _ := pool4K.Get().(*[]byte)
	return p
}

func getb4K() *bytes.Buffer {
	b, _ := poolb4K.Get().(*bytes.Buffer)
	return b
}

func getr4K() *bufio.Reader {
	r, _ := poolr4K.Get().(*bufio.Reader)
	return r
}

func getw4K() *bufio.Writer {
	w, _ := poolw4K.Get().(*bufio.Writer)
	return w
}

func put4K(b *[]byte) {
	pool4K.Put(b)
}

func putb4K(b *bytes.Buffer) {
	poolb4K.Put(b)
}

func putr4K(r *bufio.Reader) {
	poolr4K.Put(r)
}

func putw4K(w *bufio.Writer) {
	poolw4K.Put(w)
}

func GetBytesBuffer4K() *bytes.Buffer {
	if b := getb4K(); b != nil {
		return b
	}
	if p := get4K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 4096))
}

func GetBytesSlice4K() []byte {
	if p := get4K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb4K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 4096)
	return p
}

func GetBytesSlicePtr4K() *[]byte {
	if p := get4K(); p != nil {
		return p
	}
	if b := getb4K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 4096)
	return &p
}

func GetBufioReader4K(pr io.Reader) *bufio.Reader {
	if r := getr4K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 4096)
}

func GetBufioWriter4K(pw io.Writer) *bufio.Writer {
	if w := getw4K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 4096)
}

func PutBytesBuffer4K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 4096 || l >= 8192 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb4K(b)
	return true
}

func PutBytesSlice4K(p []byte) bool {
	if l := cap(p); l < 4096 || l >= 8192 {
		return PutBytesSlice(p)
	}
	p = p[0:4096]
	put4K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr4K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 4096 || l >= 8192 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:4096]
	put4K(p)
	return true
}

func PutBufioReader4K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 4096 || l >= 8192 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr4K(r)
	return true
}

func PutBufioWriter4K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 4096 || l >= 8192 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw4K(w)
	return true
}

type BufferPool4K struct {
	httputil.BufferPool
}

func (_ BufferPool4K) Get() []byte {
	return GetBytesSlice4K()
}

func (_ BufferPool4K) Put(b []byte) {
	PutBytesSlice4K(b)
}

type BufferPtrPool4K struct{}

func (_ BufferPtrPool4K) Get() *[]byte {
	return GetBytesSlicePtr4K()
}

func (_ BufferPtrPool4K) Put(b *[]byte) {
	PutBytesSlicePtr4K(b)
}

var pool8K sync.Pool  
var poolb8K sync.Pool 
var poolr8K sync.Pool 
var poolw8K sync.Pool 

func get8K() *[]byte {
	p, _ := pool8K.Get().(*[]byte)
	return p
}

func getb8K() *bytes.Buffer {
	b, _ := poolb8K.Get().(*bytes.Buffer)
	return b
}

func getr8K() *bufio.Reader {
	r, _ := poolr8K.Get().(*bufio.Reader)
	return r
}

func getw8K() *bufio.Writer {
	w, _ := poolw8K.Get().(*bufio.Writer)
	return w
}

func put8K(b *[]byte) {
	pool8K.Put(b)
}

func putb8K(b *bytes.Buffer) {
	poolb8K.Put(b)
}

func putr8K(r *bufio.Reader) {
	poolr8K.Put(r)
}

func putw8K(w *bufio.Writer) {
	poolw8K.Put(w)
}

func GetBytesBuffer8K() *bytes.Buffer {
	if b := getb8K(); b != nil {
		return b
	}
	if p := get8K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 8192))
}

func GetBytesSlice8K() []byte {
	if p := get8K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb8K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 8192)
	return p
}

func GetBytesSlicePtr8K() *[]byte {
	if p := get8K(); p != nil {
		return p
	}
	if b := getb8K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 8192)
	return &p
}

func GetBufioReader8K(pr io.Reader) *bufio.Reader {
	if r := getr8K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 8192)
}

func GetBufioWriter8K(pw io.Writer) *bufio.Writer {
	if w := getw8K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 8192)
}

func PutBytesBuffer8K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 8192 || l >= 16384 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb8K(b)
	return true
}

func PutBytesSlice8K(p []byte) bool {
	if l := cap(p); l < 8192 || l >= 16384 {
		return PutBytesSlice(p)
	}
	p = p[0:8192]
	put8K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr8K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 8192 || l >= 16384 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:8192]
	put8K(p)
	return true
}

func PutBufioReader8K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 8192 || l >= 16384 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr8K(r)
	return true
}

func PutBufioWriter8K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 8192 || l >= 16384 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw8K(w)
	return true
}

type BufferPool8K struct {
	httputil.BufferPool
}

func (_ BufferPool8K) Get() []byte {
	return GetBytesSlice8K()
}

func (_ BufferPool8K) Put(b []byte) {
	PutBytesSlice8K(b)
}

type BufferPtrPool8K struct{}

func (_ BufferPtrPool8K) Get() *[]byte {
	return GetBytesSlicePtr8K()
}

func (_ BufferPtrPool8K) Put(b *[]byte) {
	PutBytesSlicePtr8K(b)
}

var pool16K sync.Pool  
var poolb16K sync.Pool 
var poolr16K sync.Pool 
var poolw16K sync.Pool 

func get16K() *[]byte {
	p, _ := pool16K.Get().(*[]byte)
	return p
}

func getb16K() *bytes.Buffer {
	b, _ := poolb16K.Get().(*bytes.Buffer)
	return b
}

func getr16K() *bufio.Reader {
	r, _ := poolr16K.Get().(*bufio.Reader)
	return r
}

func getw16K() *bufio.Writer {
	w, _ := poolw16K.Get().(*bufio.Writer)
	return w
}

func put16K(b *[]byte) {
	pool16K.Put(b)
}

func putb16K(b *bytes.Buffer) {
	poolb16K.Put(b)
}

func putr16K(r *bufio.Reader) {
	poolr16K.Put(r)
}

func putw16K(w *bufio.Writer) {
	poolw16K.Put(w)
}

func GetBytesBuffer16K() *bytes.Buffer {
	if b := getb16K(); b != nil {
		return b
	}
	if p := get16K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 16384))
}

func GetBytesSlice16K() []byte {
	if p := get16K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb16K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 16384)
	return p
}

func GetBytesSlicePtr16K() *[]byte {
	if p := get16K(); p != nil {
		return p
	}
	if b := getb16K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 16384)
	return &p
}

func GetBufioReader16K(pr io.Reader) *bufio.Reader {
	if r := getr16K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 16384)
}

func GetBufioWriter16K(pw io.Writer) *bufio.Writer {
	if w := getw16K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 16384)
}

func PutBytesBuffer16K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 16384 || l >= 32768 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb16K(b)
	return true
}

func PutBytesSlice16K(p []byte) bool {
	if l := cap(p); l < 16384 || l >= 32768 {
		return PutBytesSlice(p)
	}
	p = p[0:16384]
	put16K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr16K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 16384 || l >= 32768 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:16384]
	put16K(p)
	return true
}

func PutBufioReader16K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 16384 || l >= 32768 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr16K(r)
	return true
}

func PutBufioWriter16K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 16384 || l >= 32768 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw16K(w)
	return true
}

type BufferPool16K struct {
	httputil.BufferPool
}

func (_ BufferPool16K) Get() []byte {
	return GetBytesSlice16K()
}

func (_ BufferPool16K) Put(b []byte) {
	PutBytesSlice16K(b)
}

type BufferPtrPool16K struct{}

func (_ BufferPtrPool16K) Get() *[]byte {
	return GetBytesSlicePtr16K()
}

func (_ BufferPtrPool16K) Put(b *[]byte) {
	PutBytesSlicePtr16K(b)
}

var pool32K sync.Pool  
var poolb32K sync.Pool 
var poolr32K sync.Pool 
var poolw32K sync.Pool 

func get32K() *[]byte {
	p, _ := pool32K.Get().(*[]byte)
	return p
}

func getb32K() *bytes.Buffer {
	b, _ := poolb32K.Get().(*bytes.Buffer)
	return b
}

func getr32K() *bufio.Reader {
	r, _ := poolr32K.Get().(*bufio.Reader)
	return r
}

func getw32K() *bufio.Writer {
	w, _ := poolw32K.Get().(*bufio.Writer)
	return w
}

func put32K(b *[]byte) {
	pool32K.Put(b)
}

func putb32K(b *bytes.Buffer) {
	poolb32K.Put(b)
}

func putr32K(r *bufio.Reader) {
	poolr32K.Put(r)
}

func putw32K(w *bufio.Writer) {
	poolw32K.Put(w)
}

func GetBytesBuffer32K() *bytes.Buffer {
	if b := getb32K(); b != nil {
		return b
	}
	if p := get32K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 32768))
}

func GetBytesSlice32K() []byte {
	if p := get32K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb32K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 32768)
	return p
}

func GetBytesSlicePtr32K() *[]byte {
	if p := get32K(); p != nil {
		return p
	}
	if b := getb32K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 32768)
	return &p
}

func GetBufioReader32K(pr io.Reader) *bufio.Reader {
	if r := getr32K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 32768)
}

func GetBufioWriter32K(pw io.Writer) *bufio.Writer {
	if w := getw32K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 32768)
}

func PutBytesBuffer32K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 32768 || l >= 65536 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb32K(b)
	return true
}

func PutBytesSlice32K(p []byte) bool {
	if l := cap(p); l < 32768 || l >= 65536 {
		return PutBytesSlice(p)
	}
	p = p[0:32768]
	put32K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr32K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 32768 || l >= 65536 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:32768]
	put32K(p)
	return true
}

func PutBufioReader32K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 32768 || l >= 65536 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr32K(r)
	return true
}

func PutBufioWriter32K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 32768 || l >= 65536 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw32K(w)
	return true
}

type BufferPool32K struct {
	httputil.BufferPool
}

func (_ BufferPool32K) Get() []byte {
	return GetBytesSlice32K()
}

func (_ BufferPool32K) Put(b []byte) {
	PutBytesSlice32K(b)
}

type BufferPtrPool32K struct{}

func (_ BufferPtrPool32K) Get() *[]byte {
	return GetBytesSlicePtr32K()
}

func (_ BufferPtrPool32K) Put(b *[]byte) {
	PutBytesSlicePtr32K(b)
}

var pool64K sync.Pool  
var poolb64K sync.Pool 
var poolr64K sync.Pool 
var poolw64K sync.Pool 

func get64K() *[]byte {
	p, _ := pool64K.Get().(*[]byte)
	return p
}

func getb64K() *bytes.Buffer {
	b, _ := poolb64K.Get().(*bytes.Buffer)
	return b
}

func getr64K() *bufio.Reader {
	r, _ := poolr64K.Get().(*bufio.Reader)
	return r
}

func getw64K() *bufio.Writer {
	w, _ := poolw64K.Get().(*bufio.Writer)
	return w
}

func put64K(b *[]byte) {
	pool64K.Put(b)
}

func putb64K(b *bytes.Buffer) {
	poolb64K.Put(b)
}

func putr64K(r *bufio.Reader) {
	poolr64K.Put(r)
}

func putw64K(w *bufio.Writer) {
	poolw64K.Put(w)
}

func GetBytesBuffer64K() *bytes.Buffer {
	if b := getb64K(); b != nil {
		return b
	}
	if p := get64K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 65536))
}

func GetBytesSlice64K() []byte {
	if p := get64K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb64K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 65536)
	return p
}

func GetBytesSlicePtr64K() *[]byte {
	if p := get64K(); p != nil {
		return p
	}
	if b := getb64K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 65536)
	return &p
}

func GetBufioReader64K(pr io.Reader) *bufio.Reader {
	if r := getr64K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 65536)
}

func GetBufioWriter64K(pw io.Writer) *bufio.Writer {
	if w := getw64K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 65536)
}

func PutBytesBuffer64K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 65536 || l >= 131072 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb64K(b)
	return true
}

func PutBytesSlice64K(p []byte) bool {
	if l := cap(p); l < 65536 || l >= 131072 {
		return PutBytesSlice(p)
	}
	p = p[0:65536]
	put64K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr64K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 65536 || l >= 131072 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:65536]
	put64K(p)
	return true
}

func PutBufioReader64K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 65536 || l >= 131072 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr64K(r)
	return true
}

func PutBufioWriter64K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 65536 || l >= 131072 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw64K(w)
	return true
}

type BufferPool64K struct {
	httputil.BufferPool
}

func (_ BufferPool64K) Get() []byte {
	return GetBytesSlice64K()
}

func (_ BufferPool64K) Put(b []byte) {
	PutBytesSlice64K(b)
}

type BufferPtrPool64K struct{}

func (_ BufferPtrPool64K) Get() *[]byte {
	return GetBytesSlicePtr64K()
}

func (_ BufferPtrPool64K) Put(b *[]byte) {
	PutBytesSlicePtr64K(b)
}

var pool128K sync.Pool  
var poolb128K sync.Pool 
var poolr128K sync.Pool 
var poolw128K sync.Pool 

func get128K() *[]byte {
	p, _ := pool128K.Get().(*[]byte)
	return p
}

func getb128K() *bytes.Buffer {
	b, _ := poolb128K.Get().(*bytes.Buffer)
	return b
}

func getr128K() *bufio.Reader {
	r, _ := poolr128K.Get().(*bufio.Reader)
	return r
}

func getw128K() *bufio.Writer {
	w, _ := poolw128K.Get().(*bufio.Writer)
	return w
}

func put128K(b *[]byte) {
	pool128K.Put(b)
}

func putb128K(b *bytes.Buffer) {
	poolb128K.Put(b)
}

func putr128K(r *bufio.Reader) {
	poolr128K.Put(r)
}

func putw128K(w *bufio.Writer) {
	poolw128K.Put(w)
}

func GetBytesBuffer128K() *bytes.Buffer {
	if b := getb128K(); b != nil {
		return b
	}
	if p := get128K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 131072))
}

func GetBytesSlice128K() []byte {
	if p := get128K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb128K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 131072)
	return p
}

func GetBytesSlicePtr128K() *[]byte {
	if p := get128K(); p != nil {
		return p
	}
	if b := getb128K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 131072)
	return &p
}

func GetBufioReader128K(pr io.Reader) *bufio.Reader {
	if r := getr128K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 131072)
}

func GetBufioWriter128K(pw io.Writer) *bufio.Writer {
	if w := getw128K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 131072)
}

func PutBytesBuffer128K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 131072 || l >= 262144 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb128K(b)
	return true
}

func PutBytesSlice128K(p []byte) bool {
	if l := cap(p); l < 131072 || l >= 262144 {
		return PutBytesSlice(p)
	}
	p = p[0:131072]
	put128K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr128K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 131072 || l >= 262144 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:131072]
	put128K(p)
	return true
}

func PutBufioReader128K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 131072 || l >= 262144 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr128K(r)
	return true
}

func PutBufioWriter128K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 131072 || l >= 262144 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw128K(w)
	return true
}

type BufferPool128K struct {
	httputil.BufferPool
}

func (_ BufferPool128K) Get() []byte {
	return GetBytesSlice128K()
}

func (_ BufferPool128K) Put(b []byte) {
	PutBytesSlice128K(b)
}

type BufferPtrPool128K struct{}

func (_ BufferPtrPool128K) Get() *[]byte {
	return GetBytesSlicePtr128K()
}

func (_ BufferPtrPool128K) Put(b *[]byte) {
	PutBytesSlicePtr128K(b)
}

var pool256K sync.Pool  
var poolb256K sync.Pool 
var poolr256K sync.Pool 
var poolw256K sync.Pool 

func get256K() *[]byte {
	p, _ := pool256K.Get().(*[]byte)
	return p
}

func getb256K() *bytes.Buffer {
	b, _ := poolb256K.Get().(*bytes.Buffer)
	return b
}

func getr256K() *bufio.Reader {
	r, _ := poolr256K.Get().(*bufio.Reader)
	return r
}

func getw256K() *bufio.Writer {
	w, _ := poolw256K.Get().(*bufio.Writer)
	return w
}

func put256K(b *[]byte) {
	pool256K.Put(b)
}

func putb256K(b *bytes.Buffer) {
	poolb256K.Put(b)
}

func putr256K(r *bufio.Reader) {
	poolr256K.Put(r)
}

func putw256K(w *bufio.Writer) {
	poolw256K.Put(w)
}

func GetBytesBuffer256K() *bytes.Buffer {
	if b := getb256K(); b != nil {
		return b
	}
	if p := get256K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 262144))
}

func GetBytesSlice256K() []byte {
	if p := get256K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb256K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 262144)
	return p
}

func GetBytesSlicePtr256K() *[]byte {
	if p := get256K(); p != nil {
		return p
	}
	if b := getb256K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 262144)
	return &p
}

func GetBufioReader256K(pr io.Reader) *bufio.Reader {
	if r := getr256K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 262144)
}

func GetBufioWriter256K(pw io.Writer) *bufio.Writer {
	if w := getw256K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 262144)
}

func PutBytesBuffer256K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 262144 || l >= 524288 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb256K(b)
	return true
}

func PutBytesSlice256K(p []byte) bool {
	if l := cap(p); l < 262144 || l >= 524288 {
		return PutBytesSlice(p)
	}
	p = p[0:262144]
	put256K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr256K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 262144 || l >= 524288 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:262144]
	put256K(p)
	return true
}

func PutBufioReader256K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 262144 || l >= 524288 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr256K(r)
	return true
}

func PutBufioWriter256K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 262144 || l >= 524288 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw256K(w)
	return true
}

type BufferPool256K struct {
	httputil.BufferPool
}

func (_ BufferPool256K) Get() []byte {
	return GetBytesSlice256K()
}

func (_ BufferPool256K) Put(b []byte) {
	PutBytesSlice256K(b)
}

type BufferPtrPool256K struct{}

func (_ BufferPtrPool256K) Get() *[]byte {
	return GetBytesSlicePtr256K()
}

func (_ BufferPtrPool256K) Put(b *[]byte) {
	PutBytesSlicePtr256K(b)
}

var pool512K sync.Pool  
var poolb512K sync.Pool 
var poolr512K sync.Pool 
var poolw512K sync.Pool 

func get512K() *[]byte {
	p, _ := pool512K.Get().(*[]byte)
	return p
}

func getb512K() *bytes.Buffer {
	b, _ := poolb512K.Get().(*bytes.Buffer)
	return b
}

func getr512K() *bufio.Reader {
	r, _ := poolr512K.Get().(*bufio.Reader)
	return r
}

func getw512K() *bufio.Writer {
	w, _ := poolw512K.Get().(*bufio.Writer)
	return w
}

func put512K(b *[]byte) {
	pool512K.Put(b)
}

func putb512K(b *bytes.Buffer) {
	poolb512K.Put(b)
}

func putr512K(r *bufio.Reader) {
	poolr512K.Put(r)
}

func putw512K(w *bufio.Writer) {
	poolw512K.Put(w)
}

func GetBytesBuffer512K() *bytes.Buffer {
	if b := getb512K(); b != nil {
		return b
	}
	if p := get512K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 524288))
}

func GetBytesSlice512K() []byte {
	if p := get512K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb512K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 524288)
	return p
}

func GetBytesSlicePtr512K() *[]byte {
	if p := get512K(); p != nil {
		return p
	}
	if b := getb512K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 524288)
	return &p
}

func GetBufioReader512K(pr io.Reader) *bufio.Reader {
	if r := getr512K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 524288)
}

func GetBufioWriter512K(pw io.Writer) *bufio.Writer {
	if w := getw512K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 524288)
}

func PutBytesBuffer512K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 524288 || l >= 1048576 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb512K(b)
	return true
}

func PutBytesSlice512K(p []byte) bool {
	if l := cap(p); l < 524288 || l >= 1048576 {
		return PutBytesSlice(p)
	}
	p = p[0:524288]
	put512K(internal.Gets(p))
	return true
}

func PutBytesSlicePtr512K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 524288 || l >= 1048576 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:524288]
	put512K(p)
	return true
}

func PutBufioReader512K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 524288 || l >= 1048576 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr512K(r)
	return true
}

func PutBufioWriter512K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 524288 || l >= 1048576 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw512K(w)
	return true
}

type BufferPool512K struct {
	httputil.BufferPool
}

func (_ BufferPool512K) Get() []byte {
	return GetBytesSlice512K()
}

func (_ BufferPool512K) Put(b []byte) {
	PutBytesSlice512K(b)
}

type BufferPtrPool512K struct{}

func (_ BufferPtrPool512K) Get() *[]byte {
	return GetBytesSlicePtr512K()
}

func (_ BufferPtrPool512K) Put(b *[]byte) {
	PutBytesSlicePtr512K(b)
}

var pool1M sync.Pool  
var poolb1M sync.Pool 
var poolr1M sync.Pool 
var poolw1M sync.Pool 

func get1M() *[]byte {
	p, _ := pool1M.Get().(*[]byte)
	return p
}

func getb1M() *bytes.Buffer {
	b, _ := poolb1M.Get().(*bytes.Buffer)
	return b
}

func getr1M() *bufio.Reader {
	r, _ := poolr1M.Get().(*bufio.Reader)
	return r
}

func getw1M() *bufio.Writer {
	w, _ := poolw1M.Get().(*bufio.Writer)
	return w
}

func put1M(b *[]byte) {
	pool1M.Put(b)
}

func putb1M(b *bytes.Buffer) {
	poolb1M.Put(b)
}

func putr1M(r *bufio.Reader) {
	poolr1M.Put(r)
}

func putw1M(w *bufio.Writer) {
	poolw1M.Put(w)
}

func GetBytesBuffer1M() *bytes.Buffer {
	if b := getb1M(); b != nil {
		return b
	}
	if p := get1M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 1048576))
}

func GetBytesSlice1M() []byte {
	if p := get1M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb1M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 1048576)
	return p
}

func GetBytesSlicePtr1M() *[]byte {
	if p := get1M(); p != nil {
		return p
	}
	if b := getb1M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 1048576)
	return &p
}

func GetBufioReader1M(pr io.Reader) *bufio.Reader {
	if r := getr1M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 1048576)
}

func GetBufioWriter1M(pw io.Writer) *bufio.Writer {
	if w := getw1M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 1048576)
}

func PutBytesBuffer1M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 1048576 || l >= 2097152 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb1M(b)
	return true
}

func PutBytesSlice1M(p []byte) bool {
	if l := cap(p); l < 1048576 || l >= 2097152 {
		return PutBytesSlice(p)
	}
	p = p[0:1048576]
	put1M(internal.Gets(p))
	return true
}

func PutBytesSlicePtr1M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 1048576 || l >= 2097152 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:1048576]
	put1M(p)
	return true
}

func PutBufioReader1M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 1048576 || l >= 2097152 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr1M(r)
	return true
}

func PutBufioWriter1M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 1048576 || l >= 2097152 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw1M(w)
	return true
}

type BufferPool1M struct {
	httputil.BufferPool
}

func (_ BufferPool1M) Get() []byte {
	return GetBytesSlice1M()
}

func (_ BufferPool1M) Put(b []byte) {
	PutBytesSlice1M(b)
}

type BufferPtrPool1M struct{}

func (_ BufferPtrPool1M) Get() *[]byte {
	return GetBytesSlicePtr1M()
}

func (_ BufferPtrPool1M) Put(b *[]byte) {
	PutBytesSlicePtr1M(b)
}

var pool2M sync.Pool  
var poolb2M sync.Pool 
var poolr2M sync.Pool 
var poolw2M sync.Pool 

func get2M() *[]byte {
	p, _ := pool2M.Get().(*[]byte)
	return p
}

func getb2M() *bytes.Buffer {
	b, _ := poolb2M.Get().(*bytes.Buffer)
	return b
}

func getr2M() *bufio.Reader {
	r, _ := poolr2M.Get().(*bufio.Reader)
	return r
}

func getw2M() *bufio.Writer {
	w, _ := poolw2M.Get().(*bufio.Writer)
	return w
}

func put2M(b *[]byte) {
	pool2M.Put(b)
}

func putb2M(b *bytes.Buffer) {
	poolb2M.Put(b)
}

func putr2M(r *bufio.Reader) {
	poolr2M.Put(r)
}

func putw2M(w *bufio.Writer) {
	poolw2M.Put(w)
}

func GetBytesBuffer2M() *bytes.Buffer {
	if b := getb2M(); b != nil {
		return b
	}
	if p := get2M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 2097152))
}

func GetBytesSlice2M() []byte {
	if p := get2M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb2M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 2097152)
	return p
}

func GetBytesSlicePtr2M() *[]byte {
	if p := get2M(); p != nil {
		return p
	}
	if b := getb2M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 2097152)
	return &p
}

func GetBufioReader2M(pr io.Reader) *bufio.Reader {
	if r := getr2M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 2097152)
}

func GetBufioWriter2M(pw io.Writer) *bufio.Writer {
	if w := getw2M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 2097152)
}

func PutBytesBuffer2M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 2097152 || l >= 4194304 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb2M(b)
	return true
}

func PutBytesSlice2M(p []byte) bool {
	if l := cap(p); l < 2097152 || l >= 4194304 {
		return PutBytesSlice(p)
	}
	p = p[0:2097152]
	put2M(internal.Gets(p))
	return true
}

func PutBytesSlicePtr2M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 2097152 || l >= 4194304 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:2097152]
	put2M(p)
	return true
}

func PutBufioReader2M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 2097152 || l >= 4194304 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr2M(r)
	return true
}

func PutBufioWriter2M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 2097152 || l >= 4194304 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw2M(w)
	return true
}

type BufferPool2M struct {
	httputil.BufferPool
}

func (_ BufferPool2M) Get() []byte {
	return GetBytesSlice2M()
}

func (_ BufferPool2M) Put(b []byte) {
	PutBytesSlice2M(b)
}

type BufferPtrPool2M struct{}

func (_ BufferPtrPool2M) Get() *[]byte {
	return GetBytesSlicePtr2M()
}

func (_ BufferPtrPool2M) Put(b *[]byte) {
	PutBytesSlicePtr2M(b)
}

var pool4M sync.Pool  
var poolb4M sync.Pool 
var poolr4M sync.Pool 
var poolw4M sync.Pool 

func get4M() *[]byte {
	p, _ := pool4M.Get().(*[]byte)
	return p
}

func getb4M() *bytes.Buffer {
	b, _ := poolb4M.Get().(*bytes.Buffer)
	return b
}

func getr4M() *bufio.Reader {
	r, _ := poolr4M.Get().(*bufio.Reader)
	return r
}

func getw4M() *bufio.Writer {
	w, _ := poolw4M.Get().(*bufio.Writer)
	return w
}

func put4M(b *[]byte) {
	pool4M.Put(b)
}

func putb4M(b *bytes.Buffer) {
	poolb4M.Put(b)
}

func putr4M(r *bufio.Reader) {
	poolr4M.Put(r)
}

func putw4M(w *bufio.Writer) {
	poolw4M.Put(w)
}

func GetBytesBuffer4M() *bytes.Buffer {
	if b := getb4M(); b != nil {
		return b
	}
	if p := get4M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 4194304))
}

func GetBytesSlice4M() []byte {
	if p := get4M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb4M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 4194304)
	return p
}

func GetBytesSlicePtr4M() *[]byte {
	if p := get4M(); p != nil {
		return p
	}
	if b := getb4M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 4194304)
	return &p
}

func GetBufioReader4M(pr io.Reader) *bufio.Reader {
	if r := getr4M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 4194304)
}

func GetBufioWriter4M(pw io.Writer) *bufio.Writer {
	if w := getw4M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 4194304)
}

func PutBytesBuffer4M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 4194304 || l >= 8388608 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb4M(b)
	return true
}

func PutBytesSlice4M(p []byte) bool {
	if l := cap(p); l < 4194304 || l >= 8388608 {
		return PutBytesSlice(p)
	}
	p = p[0:4194304]
	put4M(internal.Gets(p))
	return true
}

func PutBytesSlicePtr4M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 4194304 || l >= 8388608 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:4194304]
	put4M(p)
	return true
}

func PutBufioReader4M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 4194304 || l >= 8388608 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr4M(r)
	return true
}

func PutBufioWriter4M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 4194304 || l >= 8388608 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw4M(w)
	return true
}

type BufferPool4M struct {
	httputil.BufferPool
}

func (_ BufferPool4M) Get() []byte {
	return GetBytesSlice4M()
}

func (_ BufferPool4M) Put(b []byte) {
	PutBytesSlice4M(b)
}

type BufferPtrPool4M struct{}

func (_ BufferPtrPool4M) Get() *[]byte {
	return GetBytesSlicePtr4M()
}

func (_ BufferPtrPool4M) Put(b *[]byte) {
	PutBytesSlicePtr4M(b)
}

var pool8M sync.Pool  
var poolb8M sync.Pool 
var poolr8M sync.Pool 
var poolw8M sync.Pool 

func get8M() *[]byte {
	p, _ := pool8M.Get().(*[]byte)
	return p
}

func getb8M() *bytes.Buffer {
	b, _ := poolb8M.Get().(*bytes.Buffer)
	return b
}

func getr8M() *bufio.Reader {
	r, _ := poolr8M.Get().(*bufio.Reader)
	return r
}

func getw8M() *bufio.Writer {
	w, _ := poolw8M.Get().(*bufio.Writer)
	return w
}

func put8M(b *[]byte) {
	pool8M.Put(b)
}

func putb8M(b *bytes.Buffer) {
	poolb8M.Put(b)
}

func putr8M(r *bufio.Reader) {
	poolr8M.Put(r)
}

func putw8M(w *bufio.Writer) {
	poolw8M.Put(w)
}

func GetBytesBuffer8M() *bytes.Buffer {
	if b := getb8M(); b != nil {
		return b
	}
	if p := get8M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 8388608))
}

func GetBytesSlice8M() []byte {
	if p := get8M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb8M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 8388608)
	return p
}

func GetBytesSlicePtr8M() *[]byte {
	if p := get8M(); p != nil {
		return p
	}
	if b := getb8M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 8388608)
	return &p
}

func GetBufioReader8M(pr io.Reader) *bufio.Reader {
	if r := getr8M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 8388608)
}

func GetBufioWriter8M(pw io.Writer) *bufio.Writer {
	if w := getw8M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 8388608)
}

func PutBytesBuffer8M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 8388608 || l >= 16777216 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb8M(b)
	return true
}

func PutBytesSlice8M(p []byte) bool {
	if l := cap(p); l < 8388608 || l >= 16777216 {
		return PutBytesSlice(p)
	}
	p = p[0:8388608]
	put8M(internal.Gets(p))
	return true
}

func PutBytesSlicePtr8M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 8388608 || l >= 16777216 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:8388608]
	put8M(p)
	return true
}

func PutBufioReader8M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 8388608 || l >= 16777216 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr8M(r)
	return true
}

func PutBufioWriter8M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 8388608 || l >= 16777216 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw8M(w)
	return true
}

type BufferPool8M struct {
	httputil.BufferPool
}

func (_ BufferPool8M) Get() []byte {
	return GetBytesSlice8M()
}

func (_ BufferPool8M) Put(b []byte) {
	PutBytesSlice8M(b)
}

type BufferPtrPool8M struct{}

func (_ BufferPtrPool8M) Get() *[]byte {
	return GetBytesSlicePtr8M()
}

func (_ BufferPtrPool8M) Put(b *[]byte) {
	PutBytesSlicePtr8M(b)
}

var pool16M sync.Pool  
var poolb16M sync.Pool 
var poolr16M sync.Pool 
var poolw16M sync.Pool 

func get16M() *[]byte {
	p, _ := pool16M.Get().(*[]byte)
	return p
}

func getb16M() *bytes.Buffer {
	b, _ := poolb16M.Get().(*bytes.Buffer)
	return b
}

func getr16M() *bufio.Reader {
	r, _ := poolr16M.Get().(*bufio.Reader)
	return r
}

func getw16M() *bufio.Writer {
	w, _ := poolw16M.Get().(*bufio.Writer)
	return w
}

func put16M(b *[]byte) {
	pool16M.Put(b)
}

func putb16M(b *bytes.Buffer) {
	poolb16M.Put(b)
}

func putr16M(r *bufio.Reader) {
	poolr16M.Put(r)
}

func putw16M(w *bufio.Writer) {
	poolw16M.Put(w)
}

func GetBytesBuffer16M() *bytes.Buffer {
	if b := getb16M(); b != nil {
		return b
	}
	if p := get16M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 16777216))
}

func GetBytesSlice16M() []byte {
	if p := get16M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb16M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 16777216)
	return p
}

func GetBytesSlicePtr16M() *[]byte {
	if p := get16M(); p != nil {
		return p
	}
	if b := getb16M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 16777216)
	return &p
}

func GetBufioReader16M(pr io.Reader) *bufio.Reader {
	if r := getr16M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 16777216)
}

func GetBufioWriter16M(pw io.Writer) *bufio.Writer {
	if w := getw16M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 16777216)
}

func PutBytesBuffer16M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 16777216 || l >= 33554432 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb16M(b)
	return true
}

func PutBytesSlice16M(p []byte) bool {
	if l := cap(p); l < 16777216 || l >= 33554432 {
		return PutBytesSlice(p)
	}
	p = p[0:16777216]
	put16M(internal.Gets(p))
	return true
}

func PutBytesSlicePtr16M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 16777216 || l >= 33554432 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:16777216]
	put16M(p)
	return true
}

func PutBufioReader16M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 16777216 || l >= 33554432 {
		return PutBufioReader(r)
	}
	r.Reset(nil) 
	putr16M(r)
	return true
}

func PutBufioWriter16M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 16777216 || l >= 33554432 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) 
	putw16M(w)
	return true
}

type BufferPool16M struct {
	httputil.BufferPool
}

func (_ BufferPool16M) Get() []byte {
	return GetBytesSlice16M()
}

func (_ BufferPool16M) Put(b []byte) {
	PutBytesSlice16M(b)
}

type BufferPtrPool16M struct{}

func (_ BufferPtrPool16M) Get() *[]byte {
	return GetBytesSlicePtr16M()
}

func (_ BufferPtrPool16M) Put(b *[]byte) {
	PutBytesSlicePtr16M(b)
}

func GetBytesBuffer(size int) *bytes.Buffer {
	switch {

	case size > 0 && size <= 256:
		return GetBytesBuffer256()

	case size > 256 && size <= 512:
		return GetBytesBuffer512()

	case size > 512 && size <= 1024:
		return GetBytesBuffer1K()

	case size > 1024 && size <= 2048:
		return GetBytesBuffer2K()

	case size > 2048 && size <= 4096:
		return GetBytesBuffer4K()

	case size > 4096 && size <= 8192:
		return GetBytesBuffer8K()

	case size > 8192 && size <= 16384:
		return GetBytesBuffer16K()

	case size > 16384 && size <= 32768:
		return GetBytesBuffer32K()

	case size > 32768 && size <= 65536:
		return GetBytesBuffer64K()

	case size > 65536 && size <= 131072:
		return GetBytesBuffer128K()

	case size > 131072 && size <= 262144:
		return GetBytesBuffer256K()

	case size > 262144 && size <= 524288:
		return GetBytesBuffer512K()

	case size > 524288 && size <= 1048576:
		return GetBytesBuffer1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesBuffer2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesBuffer4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesBuffer8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesBuffer16M()

	default:
		return bytes.NewBuffer(make([]byte, size))
	}
}

func GetBytesSlice(size int) []byte {
	switch {

	case size > 0 && size <= 256:
		return GetBytesSlice256()

	case size > 256 && size <= 512:
		return GetBytesSlice512()

	case size > 512 && size <= 1024:
		return GetBytesSlice1K()

	case size > 1024 && size <= 2048:
		return GetBytesSlice2K()

	case size > 2048 && size <= 4096:
		return GetBytesSlice4K()

	case size > 4096 && size <= 8192:
		return GetBytesSlice8K()

	case size > 8192 && size <= 16384:
		return GetBytesSlice16K()

	case size > 16384 && size <= 32768:
		return GetBytesSlice32K()

	case size > 32768 && size <= 65536:
		return GetBytesSlice64K()

	case size > 65536 && size <= 131072:
		return GetBytesSlice128K()

	case size > 131072 && size <= 262144:
		return GetBytesSlice256K()

	case size > 262144 && size <= 524288:
		return GetBytesSlice512K()

	case size > 524288 && size <= 1048576:
		return GetBytesSlice1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesSlice2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesSlice4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesSlice8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesSlice16M()

	default:
		return make([]byte, size)
	}
}

func GetBytesSlicePtr(size int) *[]byte {
	switch {

	case size > 0 && size <= 256:
		return GetBytesSlicePtr256()

	case size > 256 && size <= 512:
		return GetBytesSlicePtr512()

	case size > 512 && size <= 1024:
		return GetBytesSlicePtr1K()

	case size > 1024 && size <= 2048:
		return GetBytesSlicePtr2K()

	case size > 2048 && size <= 4096:
		return GetBytesSlicePtr4K()

	case size > 4096 && size <= 8192:
		return GetBytesSlicePtr8K()

	case size > 8192 && size <= 16384:
		return GetBytesSlicePtr16K()

	case size > 16384 && size <= 32768:
		return GetBytesSlicePtr32K()

	case size > 32768 && size <= 65536:
		return GetBytesSlicePtr64K()

	case size > 65536 && size <= 131072:
		return GetBytesSlicePtr128K()

	case size > 131072 && size <= 262144:
		return GetBytesSlicePtr256K()

	case size > 262144 && size <= 524288:
		return GetBytesSlicePtr512K()

	case size > 524288 && size <= 1048576:
		return GetBytesSlicePtr1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesSlicePtr2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesSlicePtr4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesSlicePtr8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesSlicePtr16M()

	default:
		p := make([]byte, size)
		return &p
	}
}

func GetBufferPool(size int) httputil.BufferPool {
	bp := internal.BufferPool{Sz: size}
	switch {

	case size > 0 && size <= 256:
		bp.P = BufferPool256{}

	case size > 256 && size <= 512:
		bp.P = BufferPool512{}

	case size > 512 && size <= 1024:
		bp.P = BufferPool1K{}

	case size > 1024 && size <= 2048:
		bp.P = BufferPool2K{}

	case size > 2048 && size <= 4096:
		bp.P = BufferPool4K{}

	case size > 4096 && size <= 8192:
		bp.P = BufferPool8K{}

	case size > 8192 && size <= 16384:
		bp.P = BufferPool16K{}

	case size > 16384 && size <= 32768:
		bp.P = BufferPool32K{}

	case size > 32768 && size <= 65536:
		bp.P = BufferPool64K{}

	case size > 65536 && size <= 131072:
		bp.P = BufferPool128K{}

	case size > 131072 && size <= 262144:
		bp.P = BufferPool256K{}

	case size > 262144 && size <= 524288:
		bp.P = BufferPool512K{}

	case size > 524288 && size <= 1048576:
		bp.P = BufferPool1M{}

	case size > 1048576 && size <= 2097152:
		bp.P = BufferPool2M{}

	case size > 2097152 && size <= 4194304:
		bp.P = BufferPool4M{}

	case size > 4194304 && size <= 8388608:
		bp.P = BufferPool8M{}

	case size > 8388608 && size <= 16777216:
		bp.P = BufferPool16M{}

	default:
		return &internal.SingleSizeBufferPool{Sz: size}
	}
	return bp
}

func GetBufioReader(pr io.Reader, size int) *bufio.Reader {
	switch {

	case size > 0 && size <= 256:
		return GetBufioReader256(pr)

	case size > 256 && size <= 512:
		return GetBufioReader512(pr)

	case size > 512 && size <= 1024:
		return GetBufioReader1K(pr)

	case size > 1024 && size <= 2048:
		return GetBufioReader2K(pr)

	case size > 2048 && size <= 4096:
		return GetBufioReader4K(pr)

	case size > 4096 && size <= 8192:
		return GetBufioReader8K(pr)

	case size > 8192 && size <= 16384:
		return GetBufioReader16K(pr)

	case size > 16384 && size <= 32768:
		return GetBufioReader32K(pr)

	case size > 32768 && size <= 65536:
		return GetBufioReader64K(pr)

	case size > 65536 && size <= 131072:
		return GetBufioReader128K(pr)

	case size > 131072 && size <= 262144:
		return GetBufioReader256K(pr)

	case size > 262144 && size <= 524288:
		return GetBufioReader512K(pr)

	case size > 524288 && size <= 1048576:
		return GetBufioReader1M(pr)

	case size > 1048576 && size <= 2097152:
		return GetBufioReader2M(pr)

	case size > 2097152 && size <= 4194304:
		return GetBufioReader4M(pr)

	case size > 4194304 && size <= 8388608:
		return GetBufioReader8M(pr)

	case size > 8388608 && size <= 16777216:
		return GetBufioReader16M(pr)

	default:
		return bufio.NewReaderSize(pr, size)
	}
}

func GetBufioWriter(pw io.Writer, size int) *bufio.Writer {
	switch {

	case size > 0 && size <= 256:
		return GetBufioWriter256(pw)

	case size > 256 && size <= 512:
		return GetBufioWriter512(pw)

	case size > 512 && size <= 1024:
		return GetBufioWriter1K(pw)

	case size > 1024 && size <= 2048:
		return GetBufioWriter2K(pw)

	case size > 2048 && size <= 4096:
		return GetBufioWriter4K(pw)

	case size > 4096 && size <= 8192:
		return GetBufioWriter8K(pw)

	case size > 8192 && size <= 16384:
		return GetBufioWriter16K(pw)

	case size > 16384 && size <= 32768:
		return GetBufioWriter32K(pw)

	case size > 32768 && size <= 65536:
		return GetBufioWriter64K(pw)

	case size > 65536 && size <= 131072:
		return GetBufioWriter128K(pw)

	case size > 131072 && size <= 262144:
		return GetBufioWriter256K(pw)

	case size > 262144 && size <= 524288:
		return GetBufioWriter512K(pw)

	case size > 524288 && size <= 1048576:
		return GetBufioWriter1M(pw)

	case size > 1048576 && size <= 2097152:
		return GetBufioWriter2M(pw)

	case size > 2097152 && size <= 4194304:
		return GetBufioWriter4M(pw)

	case size > 4194304 && size <= 8388608:
		return GetBufioWriter8M(pw)

	case size > 8388608 && size <= 16777216:
		return GetBufioWriter16M(pw)

	default:
		return bufio.NewWriterSize(pw, size)
	}
}

func PutBytesBuffer(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	size := b.Cap()
	switch {

	case size >= 256 && size < 512:
		b.Reset()
		putb256(b)

	case size >= 512 && size < 1024:
		b.Reset()
		putb512(b)

	case size >= 1024 && size < 2048:
		b.Reset()
		putb1K(b)

	case size >= 2048 && size < 4096:
		b.Reset()
		putb2K(b)

	case size >= 4096 && size < 8192:
		b.Reset()
		putb4K(b)

	case size >= 8192 && size < 16384:
		b.Reset()
		putb8K(b)

	case size >= 16384 && size < 32768:
		b.Reset()
		putb16K(b)

	case size >= 32768 && size < 65536:
		b.Reset()
		putb32K(b)

	case size >= 65536 && size < 131072:
		b.Reset()
		putb64K(b)

	case size >= 131072 && size < 262144:
		b.Reset()
		putb128K(b)

	case size >= 262144 && size < 524288:
		b.Reset()
		putb256K(b)

	case size >= 524288 && size < 1048576:
		b.Reset()
		putb512K(b)

	case size >= 1048576 && size < 2097152:
		b.Reset()
		putb1M(b)

	case size >= 2097152 && size < 4194304:
		b.Reset()
		putb2M(b)

	case size >= 4194304 && size < 8388608:
		b.Reset()
		putb4M(b)

	case size >= 8388608 && size < 16777216:
		b.Reset()
		putb8M(b)

	case size >= 16777216 && size < 33554432:
		b.Reset()
		putb16M(b)

	default:
		return false
	}
	return true
}

func PutBytesSlice(b []byte) bool {
	size := cap(b)
	switch {

	case size >= 256 && size < 512:
		b = b[0:256]
		put256(internal.Gets(b))

	case size >= 512 && size < 1024:
		b = b[0:512]
		put512(internal.Gets(b))

	case size >= 1024 && size < 2048:
		b = b[0:1024]
		put1K(internal.Gets(b))

	case size >= 2048 && size < 4096:
		b = b[0:2048]
		put2K(internal.Gets(b))

	case size >= 4096 && size < 8192:
		b = b[0:4096]
		put4K(internal.Gets(b))

	case size >= 8192 && size < 16384:
		b = b[0:8192]
		put8K(internal.Gets(b))

	case size >= 16384 && size < 32768:
		b = b[0:16384]
		put16K(internal.Gets(b))

	case size >= 32768 && size < 65536:
		b = b[0:32768]
		put32K(internal.Gets(b))

	case size >= 65536 && size < 131072:
		b = b[0:65536]
		put64K(internal.Gets(b))

	case size >= 131072 && size < 262144:
		b = b[0:131072]
		put128K(internal.Gets(b))

	case size >= 262144 && size < 524288:
		b = b[0:262144]
		put256K(internal.Gets(b))

	case size >= 524288 && size < 1048576:
		b = b[0:524288]
		put512K(internal.Gets(b))

	case size >= 1048576 && size < 2097152:
		b = b[0:1048576]
		put1M(internal.Gets(b))

	case size >= 2097152 && size < 4194304:
		b = b[0:2097152]
		put2M(internal.Gets(b))

	case size >= 4194304 && size < 8388608:
		b = b[0:4194304]
		put4M(internal.Gets(b))

	case size >= 8388608 && size < 16777216:
		b = b[0:8388608]
		put8M(internal.Gets(b))

	case size >= 16777216 && size < 33554432:
		b = b[0:16777216]
		put16M(internal.Gets(b))

	default:
		return false
	}
	return true
}

func PutBytesSlicePtr(b *[]byte) bool {
	if b == nil {
		return false
	}
	size := cap(*b)
	switch {

	case size >= 256 && size < 512:
		*b = (*b)[0:256]
		put256(b)

	case size >= 512 && size < 1024:
		*b = (*b)[0:512]
		put512(b)

	case size >= 1024 && size < 2048:
		*b = (*b)[0:1024]
		put1K(b)

	case size >= 2048 && size < 4096:
		*b = (*b)[0:2048]
		put2K(b)

	case size >= 4096 && size < 8192:
		*b = (*b)[0:4096]
		put4K(b)

	case size >= 8192 && size < 16384:
		*b = (*b)[0:8192]
		put8K(b)

	case size >= 16384 && size < 32768:
		*b = (*b)[0:16384]
		put16K(b)

	case size >= 32768 && size < 65536:
		*b = (*b)[0:32768]
		put32K(b)

	case size >= 65536 && size < 131072:
		*b = (*b)[0:65536]
		put64K(b)

	case size >= 131072 && size < 262144:
		*b = (*b)[0:131072]
		put128K(b)

	case size >= 262144 && size < 524288:
		*b = (*b)[0:262144]
		put256K(b)

	case size >= 524288 && size < 1048576:
		*b = (*b)[0:524288]
		put512K(b)

	case size >= 1048576 && size < 2097152:
		*b = (*b)[0:1048576]
		put1M(b)

	case size >= 2097152 && size < 4194304:
		*b = (*b)[0:2097152]
		put2M(b)

	case size >= 4194304 && size < 8388608:
		*b = (*b)[0:4194304]
		put4M(b)

	case size >= 8388608 && size < 16777216:
		*b = (*b)[0:8388608]
		put8M(b)

	case size >= 16777216 && size < 33554432:
		*b = (*b)[0:16777216]
		put16M(b)

	default:
		return false
	}
	return true
}

func PutBufioReader(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	size := r.Size()
	switch {

	case size >= 256 && size < 512:
		r.Reset(nil) 
		putr256(r)

	case size >= 512 && size < 1024:
		r.Reset(nil) 
		putr512(r)

	case size >= 1024 && size < 2048:
		r.Reset(nil) 
		putr1K(r)

	case size >= 2048 && size < 4096:
		r.Reset(nil) 
		putr2K(r)

	case size >= 4096 && size < 8192:
		r.Reset(nil) 
		putr4K(r)

	case size >= 8192 && size < 16384:
		r.Reset(nil) 
		putr8K(r)

	case size >= 16384 && size < 32768:
		r.Reset(nil) 
		putr16K(r)

	case size >= 32768 && size < 65536:
		r.Reset(nil) 
		putr32K(r)

	case size >= 65536 && size < 131072:
		r.Reset(nil) 
		putr64K(r)

	case size >= 131072 && size < 262144:
		r.Reset(nil) 
		putr128K(r)

	case size >= 262144 && size < 524288:
		r.Reset(nil) 
		putr256K(r)

	case size >= 524288 && size < 1048576:
		r.Reset(nil) 
		putr512K(r)

	case size >= 1048576 && size < 2097152:
		r.Reset(nil) 
		putr1M(r)

	case size >= 2097152 && size < 4194304:
		r.Reset(nil) 
		putr2M(r)

	case size >= 4194304 && size < 8388608:
		r.Reset(nil) 
		putr4M(r)

	case size >= 8388608 && size < 16777216:
		r.Reset(nil) 
		putr8M(r)

	case size >= 16777216 && size < 33554432:
		r.Reset(nil) 
		putr16M(r)

	default:
		return false
	}
	return true
}

func PutBufioWriter(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	size := w.Size()
	switch {

	case size >= 256 && size < 512:
		w.Reset(nil) 
		putw256(w)

	case size >= 512 && size < 1024:
		w.Reset(nil) 
		putw512(w)

	case size >= 1024 && size < 2048:
		w.Reset(nil) 
		putw1K(w)

	case size >= 2048 && size < 4096:
		w.Reset(nil) 
		putw2K(w)

	case size >= 4096 && size < 8192:
		w.Reset(nil) 
		putw4K(w)

	case size >= 8192 && size < 16384:
		w.Reset(nil) 
		putw8K(w)

	case size >= 16384 && size < 32768:
		w.Reset(nil) 
		putw16K(w)

	case size >= 32768 && size < 65536:
		w.Reset(nil) 
		putw32K(w)

	case size >= 65536 && size < 131072:
		w.Reset(nil) 
		putw64K(w)

	case size >= 131072 && size < 262144:
		w.Reset(nil) 
		putw128K(w)

	case size >= 262144 && size < 524288:
		w.Reset(nil) 
		putw256K(w)

	case size >= 524288 && size < 1048576:
		w.Reset(nil) 
		putw512K(w)

	case size >= 1048576 && size < 2097152:
		w.Reset(nil) 
		putw1M(w)

	case size >= 2097152 && size < 4194304:
		w.Reset(nil) 
		putw2M(w)

	case size >= 4194304 && size < 8388608:
		w.Reset(nil) 
		putw4M(w)

	case size >= 8388608 && size < 16777216:
		w.Reset(nil) 
		putw8M(w)

	case size >= 16777216 && size < 33554432:
		w.Reset(nil) 
		putw16M(w)

	default:
		return false
	}
	return true
}
// Code generated by bytespool-gen. DO NOT EDIT.

// Package bytespool implements a series of sync.Pools tailored to safely recycle
// byte slices and bytes.Buffers. It works by defining a number of buckets, each for
// slices or Buffers of a certain range of capacities, and directing the Put and Get
// requests to the appropriate bucket.
// This package is autogenerated to allow to customize the granularity of the buckets
// and the range of supported capacities. This version was generated with the following
// buckets: 256B 512B 1KB 2KB 4KB 8KB 16KB 32KB 64KB 128KB 256KB 512KB 1MB 2MB 4MB 8MB 16MB.
// It is advisable not to grow/extend the byte slices or bytes.Buffer returned by
// bytespool, as this incurs allocations. To avoid this, use bytespool to allocate a new
// object of the desired size, copy the data to the new object and then recycle the
// original object.
package bytespool

import (
	"bufio"
	"bytes"
	"github.com/CAFxX/bytespool/internal"
	"io"
	"net/http/httputil"
	"sync"
)

var buckets = [...]int{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216}

var pool256 sync.Pool  // *[]byte, 256 <= cap < 512
var poolb256 sync.Pool // *bytes.Buffer, 256 <= Cap < 512
var poolr256 sync.Pool // *bufio.Reader, 256 <= Size < 512
var poolw256 sync.Pool // *bufio.Writer, 256 <= Size < 512

func get256() *[]byte {
	p, _ := pool256.Get().(*[]byte)
	return p
}

func getb256() *bytes.Buffer {
	b, _ := poolb256.Get().(*bytes.Buffer)
	return b
}

func getr256() *bufio.Reader {
	r, _ := poolr256.Get().(*bufio.Reader)
	return r
}

func getw256() *bufio.Writer {
	w, _ := poolw256.Get().(*bufio.Writer)
	return w
}

func put256(b *[]byte) {
	pool256.Put(b)
}

func putb256(b *bytes.Buffer) {
	poolb256.Put(b)
}

func putr256(r *bufio.Reader) {
	poolr256.Put(r)
}

func putw256(w *bufio.Writer) {
	poolw256.Put(w)
}

// GetBytesBuffer256 gets a bytes.Buffer with a capacity of at least 256 bytes.
func GetBytesBuffer256() *bytes.Buffer {
	if b := getb256(); b != nil {
		return b
	}
	if p := get256(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 256))
}

// GetBytesSlice256 gets a byte slice with a capacity of at least 256 bytes and length of 256 bytes.
// GetBytesSlice256 is somewhat slower than GetBytesSlicePtr256, but it is significantly easier to use.
func GetBytesSlice256() []byte {
	if p := get256(); p != nil {
		return internal.Puts(p)
	}
	if b := getb256(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 256)
	return p
}

// GetBytesSlicePtr256 is like GetBytesSlice256 but returns a pointer to the slice instead.
// GetBytesSlicePtr256 is somewhat faster than GetBytesSlice256, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr256 the original pointer returned by GetBytesSlicePtr256 to recycle the slice.
func GetBytesSlicePtr256() *[]byte {
	if p := get256(); p != nil {
		return p
	}
	if b := getb256(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 256)
	return &p
}

// GetBufioReader256 returns a bufio.Reader with an internal buffer size of at least 256.
func GetBufioReader256(pr io.Reader) *bufio.Reader {
	if r := getr256(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 256)
}

// GetBufioWriter256 returns a bufio.Writer with an internal buffer size of at least 256.
func GetBufioWriter256(pw io.Writer) *bufio.Writer {
	if w := getw256(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 256)
}

// PutBytesBuffer256 recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer256 is optimized for bytes.Buffer of capacity [256, 512) but will accepts other
// sizes as well.
func PutBytesBuffer256(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 256 || l >= 512 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb256(b)
	return true
}

// PutBytesSlice256 recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice256 is optimized for byte slice of capacity [256, 512) but will accepts other
// sizes as well.
// PutBytesSlice256, contrary to PutBytesSlicePtr256, will perform a pointer-sized allocation for each call.
func PutBytesSlice256(p []byte) bool {
	if l := cap(p); l < 256 || l >= 512 {
		return PutBytesSlice(p)
	}
	p = p[0:256]
	put256(internal.Gets(p))
	return true
}

// PutBytesSlicePtr256 is like PutBytesSlice256, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr256(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 256 || l >= 512 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:256]
	put256(p)
	return true
}

// PutBufioReader256 recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader256 is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader256 callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader256 is optimized for bufio.Reader with Size() in the range (256, 512], but it accepts
// also other sizes.
func PutBufioReader256(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 256 || l >= 512 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr256(r)
	return true
}

// PutBufioWriter256 recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter256 is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter256 callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter256 is optimized for bufio.Writer with Size() in the range (256, 512], but it accepts
// also other sizes.
func PutBufioWriter256(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 256 || l >= 512 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw256(w)
	return true
}

// BufferPool256 is a httputil.BufferPool that provides byte slices of 256 bytes.
type BufferPool256 struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool256) Get() []byte {
	return GetBytesSlice256()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool256) Put(b []byte) {
	PutBytesSlice256(b)
}

// BufferPtrPool256 is like BufferPool256, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool256 struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr256 for details.
func (_ BufferPtrPool256) Get() *[]byte {
	return GetBytesSlicePtr256()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr256 for details.
func (_ BufferPtrPool256) Put(b *[]byte) {
	PutBytesSlicePtr256(b)
}

var pool512 sync.Pool  // *[]byte, 512 <= cap < 1024
var poolb512 sync.Pool // *bytes.Buffer, 512 <= Cap < 1024
var poolr512 sync.Pool // *bufio.Reader, 512 <= Size < 1024
var poolw512 sync.Pool // *bufio.Writer, 512 <= Size < 1024

func get512() *[]byte {
	p, _ := pool512.Get().(*[]byte)
	return p
}

func getb512() *bytes.Buffer {
	b, _ := poolb512.Get().(*bytes.Buffer)
	return b
}

func getr512() *bufio.Reader {
	r, _ := poolr512.Get().(*bufio.Reader)
	return r
}

func getw512() *bufio.Writer {
	w, _ := poolw512.Get().(*bufio.Writer)
	return w
}

func put512(b *[]byte) {
	pool512.Put(b)
}

func putb512(b *bytes.Buffer) {
	poolb512.Put(b)
}

func putr512(r *bufio.Reader) {
	poolr512.Put(r)
}

func putw512(w *bufio.Writer) {
	poolw512.Put(w)
}

// GetBytesBuffer512 gets a bytes.Buffer with a capacity of at least 512 bytes.
func GetBytesBuffer512() *bytes.Buffer {
	if b := getb512(); b != nil {
		return b
	}
	if p := get512(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 512))
}

// GetBytesSlice512 gets a byte slice with a capacity of at least 512 bytes and length of 512 bytes.
// GetBytesSlice512 is somewhat slower than GetBytesSlicePtr512, but it is significantly easier to use.
func GetBytesSlice512() []byte {
	if p := get512(); p != nil {
		return internal.Puts(p)
	}
	if b := getb512(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 512)
	return p
}

// GetBytesSlicePtr512 is like GetBytesSlice512 but returns a pointer to the slice instead.
// GetBytesSlicePtr512 is somewhat faster than GetBytesSlice512, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr512 the original pointer returned by GetBytesSlicePtr512 to recycle the slice.
func GetBytesSlicePtr512() *[]byte {
	if p := get512(); p != nil {
		return p
	}
	if b := getb512(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 512)
	return &p
}

// GetBufioReader512 returns a bufio.Reader with an internal buffer size of at least 512.
func GetBufioReader512(pr io.Reader) *bufio.Reader {
	if r := getr512(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 512)
}

// GetBufioWriter512 returns a bufio.Writer with an internal buffer size of at least 512.
func GetBufioWriter512(pw io.Writer) *bufio.Writer {
	if w := getw512(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 512)
}

// PutBytesBuffer512 recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer512 is optimized for bytes.Buffer of capacity [512, 1024) but will accepts other
// sizes as well.
func PutBytesBuffer512(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 512 || l >= 1024 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb512(b)
	return true
}

// PutBytesSlice512 recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice512 is optimized for byte slice of capacity [512, 1024) but will accepts other
// sizes as well.
// PutBytesSlice512, contrary to PutBytesSlicePtr512, will perform a pointer-sized allocation for each call.
func PutBytesSlice512(p []byte) bool {
	if l := cap(p); l < 512 || l >= 1024 {
		return PutBytesSlice(p)
	}
	p = p[0:512]
	put512(internal.Gets(p))
	return true
}

// PutBytesSlicePtr512 is like PutBytesSlice512, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr512(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 512 || l >= 1024 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:512]
	put512(p)
	return true
}

// PutBufioReader512 recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader512 is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader512 callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader512 is optimized for bufio.Reader with Size() in the range (512, 1024], but it accepts
// also other sizes.
func PutBufioReader512(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 512 || l >= 1024 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr512(r)
	return true
}

// PutBufioWriter512 recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter512 is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter512 callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter512 is optimized for bufio.Writer with Size() in the range (512, 1024], but it accepts
// also other sizes.
func PutBufioWriter512(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 512 || l >= 1024 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw512(w)
	return true
}

// BufferPool512 is a httputil.BufferPool that provides byte slices of 512 bytes.
type BufferPool512 struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool512) Get() []byte {
	return GetBytesSlice512()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool512) Put(b []byte) {
	PutBytesSlice512(b)
}

// BufferPtrPool512 is like BufferPool512, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool512 struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr512 for details.
func (_ BufferPtrPool512) Get() *[]byte {
	return GetBytesSlicePtr512()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr512 for details.
func (_ BufferPtrPool512) Put(b *[]byte) {
	PutBytesSlicePtr512(b)
}

var pool1K sync.Pool  // *[]byte, 1024 <= cap < 2048
var poolb1K sync.Pool // *bytes.Buffer, 1024 <= Cap < 2048
var poolr1K sync.Pool // *bufio.Reader, 1024 <= Size < 2048
var poolw1K sync.Pool // *bufio.Writer, 1024 <= Size < 2048

func get1K() *[]byte {
	p, _ := pool1K.Get().(*[]byte)
	return p
}

func getb1K() *bytes.Buffer {
	b, _ := poolb1K.Get().(*bytes.Buffer)
	return b
}

func getr1K() *bufio.Reader {
	r, _ := poolr1K.Get().(*bufio.Reader)
	return r
}

func getw1K() *bufio.Writer {
	w, _ := poolw1K.Get().(*bufio.Writer)
	return w
}

func put1K(b *[]byte) {
	pool1K.Put(b)
}

func putb1K(b *bytes.Buffer) {
	poolb1K.Put(b)
}

func putr1K(r *bufio.Reader) {
	poolr1K.Put(r)
}

func putw1K(w *bufio.Writer) {
	poolw1K.Put(w)
}

// GetBytesBuffer1K gets a bytes.Buffer with a capacity of at least 1K bytes.
func GetBytesBuffer1K() *bytes.Buffer {
	if b := getb1K(); b != nil {
		return b
	}
	if p := get1K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 1024))
}

// GetBytesSlice1K gets a byte slice with a capacity of at least 1K bytes and length of 1K bytes.
// GetBytesSlice1K is somewhat slower than GetBytesSlicePtr1K, but it is significantly easier to use.
func GetBytesSlice1K() []byte {
	if p := get1K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb1K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 1024)
	return p
}

// GetBytesSlicePtr1K is like GetBytesSlice1K but returns a pointer to the slice instead.
// GetBytesSlicePtr1K is somewhat faster than GetBytesSlice1K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr1K the original pointer returned by GetBytesSlicePtr1K to recycle the slice.
func GetBytesSlicePtr1K() *[]byte {
	if p := get1K(); p != nil {
		return p
	}
	if b := getb1K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 1024)
	return &p
}

// GetBufioReader1K returns a bufio.Reader with an internal buffer size of at least 1024.
func GetBufioReader1K(pr io.Reader) *bufio.Reader {
	if r := getr1K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 1024)
}

// GetBufioWriter1K returns a bufio.Writer with an internal buffer size of at least 1024.
func GetBufioWriter1K(pw io.Writer) *bufio.Writer {
	if w := getw1K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 1024)
}

// PutBytesBuffer1K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer1K is optimized for bytes.Buffer of capacity [1024, 2048) but will accepts other
// sizes as well.
func PutBytesBuffer1K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 1024 || l >= 2048 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb1K(b)
	return true
}

// PutBytesSlice1K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice1K is optimized for byte slice of capacity [1024, 2048) but will accepts other
// sizes as well.
// PutBytesSlice1K, contrary to PutBytesSlicePtr1K, will perform a pointer-sized allocation for each call.
func PutBytesSlice1K(p []byte) bool {
	if l := cap(p); l < 1024 || l >= 2048 {
		return PutBytesSlice(p)
	}
	p = p[0:1024]
	put1K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr1K is like PutBytesSlice1K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr1K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 1024 || l >= 2048 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:1024]
	put1K(p)
	return true
}

// PutBufioReader1K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader1K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader1K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader1K is optimized for bufio.Reader with Size() in the range (1024, 2048], but it accepts
// also other sizes.
func PutBufioReader1K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 1024 || l >= 2048 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr1K(r)
	return true
}

// PutBufioWriter1K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter1K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter1K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter1K is optimized for bufio.Writer with Size() in the range (1024, 2048], but it accepts
// also other sizes.
func PutBufioWriter1K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 1024 || l >= 2048 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw1K(w)
	return true
}

// BufferPool1K is a httputil.BufferPool that provides byte slices of 1K bytes.
type BufferPool1K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool1K) Get() []byte {
	return GetBytesSlice1K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool1K) Put(b []byte) {
	PutBytesSlice1K(b)
}

// BufferPtrPool1K is like BufferPool1K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool1K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr1K for details.
func (_ BufferPtrPool1K) Get() *[]byte {
	return GetBytesSlicePtr1K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr1K for details.
func (_ BufferPtrPool1K) Put(b *[]byte) {
	PutBytesSlicePtr1K(b)
}

var pool2K sync.Pool  // *[]byte, 2048 <= cap < 4096
var poolb2K sync.Pool // *bytes.Buffer, 2048 <= Cap < 4096
var poolr2K sync.Pool // *bufio.Reader, 2048 <= Size < 4096
var poolw2K sync.Pool // *bufio.Writer, 2048 <= Size < 4096

func get2K() *[]byte {
	p, _ := pool2K.Get().(*[]byte)
	return p
}

func getb2K() *bytes.Buffer {
	b, _ := poolb2K.Get().(*bytes.Buffer)
	return b
}

func getr2K() *bufio.Reader {
	r, _ := poolr2K.Get().(*bufio.Reader)
	return r
}

func getw2K() *bufio.Writer {
	w, _ := poolw2K.Get().(*bufio.Writer)
	return w
}

func put2K(b *[]byte) {
	pool2K.Put(b)
}

func putb2K(b *bytes.Buffer) {
	poolb2K.Put(b)
}

func putr2K(r *bufio.Reader) {
	poolr2K.Put(r)
}

func putw2K(w *bufio.Writer) {
	poolw2K.Put(w)
}

// GetBytesBuffer2K gets a bytes.Buffer with a capacity of at least 2K bytes.
func GetBytesBuffer2K() *bytes.Buffer {
	if b := getb2K(); b != nil {
		return b
	}
	if p := get2K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 2048))
}

// GetBytesSlice2K gets a byte slice with a capacity of at least 2K bytes and length of 2K bytes.
// GetBytesSlice2K is somewhat slower than GetBytesSlicePtr2K, but it is significantly easier to use.
func GetBytesSlice2K() []byte {
	if p := get2K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb2K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 2048)
	return p
}

// GetBytesSlicePtr2K is like GetBytesSlice2K but returns a pointer to the slice instead.
// GetBytesSlicePtr2K is somewhat faster than GetBytesSlice2K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr2K the original pointer returned by GetBytesSlicePtr2K to recycle the slice.
func GetBytesSlicePtr2K() *[]byte {
	if p := get2K(); p != nil {
		return p
	}
	if b := getb2K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 2048)
	return &p
}

// GetBufioReader2K returns a bufio.Reader with an internal buffer size of at least 2048.
func GetBufioReader2K(pr io.Reader) *bufio.Reader {
	if r := getr2K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 2048)
}

// GetBufioWriter2K returns a bufio.Writer with an internal buffer size of at least 2048.
func GetBufioWriter2K(pw io.Writer) *bufio.Writer {
	if w := getw2K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 2048)
}

// PutBytesBuffer2K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer2K is optimized for bytes.Buffer of capacity [2048, 4096) but will accepts other
// sizes as well.
func PutBytesBuffer2K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 2048 || l >= 4096 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb2K(b)
	return true
}

// PutBytesSlice2K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice2K is optimized for byte slice of capacity [2048, 4096) but will accepts other
// sizes as well.
// PutBytesSlice2K, contrary to PutBytesSlicePtr2K, will perform a pointer-sized allocation for each call.
func PutBytesSlice2K(p []byte) bool {
	if l := cap(p); l < 2048 || l >= 4096 {
		return PutBytesSlice(p)
	}
	p = p[0:2048]
	put2K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr2K is like PutBytesSlice2K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr2K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 2048 || l >= 4096 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:2048]
	put2K(p)
	return true
}

// PutBufioReader2K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader2K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader2K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader2K is optimized for bufio.Reader with Size() in the range (2048, 4096], but it accepts
// also other sizes.
func PutBufioReader2K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 2048 || l >= 4096 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr2K(r)
	return true
}

// PutBufioWriter2K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter2K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter2K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter2K is optimized for bufio.Writer with Size() in the range (2048, 4096], but it accepts
// also other sizes.
func PutBufioWriter2K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 2048 || l >= 4096 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw2K(w)
	return true
}

// BufferPool2K is a httputil.BufferPool that provides byte slices of 2K bytes.
type BufferPool2K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool2K) Get() []byte {
	return GetBytesSlice2K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool2K) Put(b []byte) {
	PutBytesSlice2K(b)
}

// BufferPtrPool2K is like BufferPool2K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool2K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr2K for details.
func (_ BufferPtrPool2K) Get() *[]byte {
	return GetBytesSlicePtr2K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr2K for details.
func (_ BufferPtrPool2K) Put(b *[]byte) {
	PutBytesSlicePtr2K(b)
}

var pool4K sync.Pool  // *[]byte, 4096 <= cap < 8192
var poolb4K sync.Pool // *bytes.Buffer, 4096 <= Cap < 8192
var poolr4K sync.Pool // *bufio.Reader, 4096 <= Size < 8192
var poolw4K sync.Pool // *bufio.Writer, 4096 <= Size < 8192

func get4K() *[]byte {
	p, _ := pool4K.Get().(*[]byte)
	return p
}

func getb4K() *bytes.Buffer {
	b, _ := poolb4K.Get().(*bytes.Buffer)
	return b
}

func getr4K() *bufio.Reader {
	r, _ := poolr4K.Get().(*bufio.Reader)
	return r
}

func getw4K() *bufio.Writer {
	w, _ := poolw4K.Get().(*bufio.Writer)
	return w
}

func put4K(b *[]byte) {
	pool4K.Put(b)
}

func putb4K(b *bytes.Buffer) {
	poolb4K.Put(b)
}

func putr4K(r *bufio.Reader) {
	poolr4K.Put(r)
}

func putw4K(w *bufio.Writer) {
	poolw4K.Put(w)
}

// GetBytesBuffer4K gets a bytes.Buffer with a capacity of at least 4K bytes.
func GetBytesBuffer4K() *bytes.Buffer {
	if b := getb4K(); b != nil {
		return b
	}
	if p := get4K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 4096))
}

// GetBytesSlice4K gets a byte slice with a capacity of at least 4K bytes and length of 4K bytes.
// GetBytesSlice4K is somewhat slower than GetBytesSlicePtr4K, but it is significantly easier to use.
func GetBytesSlice4K() []byte {
	if p := get4K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb4K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 4096)
	return p
}

// GetBytesSlicePtr4K is like GetBytesSlice4K but returns a pointer to the slice instead.
// GetBytesSlicePtr4K is somewhat faster than GetBytesSlice4K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr4K the original pointer returned by GetBytesSlicePtr4K to recycle the slice.
func GetBytesSlicePtr4K() *[]byte {
	if p := get4K(); p != nil {
		return p
	}
	if b := getb4K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 4096)
	return &p
}

// GetBufioReader4K returns a bufio.Reader with an internal buffer size of at least 4096.
func GetBufioReader4K(pr io.Reader) *bufio.Reader {
	if r := getr4K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 4096)
}

// GetBufioWriter4K returns a bufio.Writer with an internal buffer size of at least 4096.
func GetBufioWriter4K(pw io.Writer) *bufio.Writer {
	if w := getw4K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 4096)
}

// PutBytesBuffer4K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer4K is optimized for bytes.Buffer of capacity [4096, 8192) but will accepts other
// sizes as well.
func PutBytesBuffer4K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 4096 || l >= 8192 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb4K(b)
	return true
}

// PutBytesSlice4K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice4K is optimized for byte slice of capacity [4096, 8192) but will accepts other
// sizes as well.
// PutBytesSlice4K, contrary to PutBytesSlicePtr4K, will perform a pointer-sized allocation for each call.
func PutBytesSlice4K(p []byte) bool {
	if l := cap(p); l < 4096 || l >= 8192 {
		return PutBytesSlice(p)
	}
	p = p[0:4096]
	put4K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr4K is like PutBytesSlice4K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr4K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 4096 || l >= 8192 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:4096]
	put4K(p)
	return true
}

// PutBufioReader4K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader4K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader4K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader4K is optimized for bufio.Reader with Size() in the range (4096, 8192], but it accepts
// also other sizes.
func PutBufioReader4K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 4096 || l >= 8192 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr4K(r)
	return true
}

// PutBufioWriter4K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter4K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter4K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter4K is optimized for bufio.Writer with Size() in the range (4096, 8192], but it accepts
// also other sizes.
func PutBufioWriter4K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 4096 || l >= 8192 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw4K(w)
	return true
}

// BufferPool4K is a httputil.BufferPool that provides byte slices of 4K bytes.
type BufferPool4K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool4K) Get() []byte {
	return GetBytesSlice4K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool4K) Put(b []byte) {
	PutBytesSlice4K(b)
}

// BufferPtrPool4K is like BufferPool4K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool4K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr4K for details.
func (_ BufferPtrPool4K) Get() *[]byte {
	return GetBytesSlicePtr4K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr4K for details.
func (_ BufferPtrPool4K) Put(b *[]byte) {
	PutBytesSlicePtr4K(b)
}

var pool8K sync.Pool  // *[]byte, 8192 <= cap < 16384
var poolb8K sync.Pool // *bytes.Buffer, 8192 <= Cap < 16384
var poolr8K sync.Pool // *bufio.Reader, 8192 <= Size < 16384
var poolw8K sync.Pool // *bufio.Writer, 8192 <= Size < 16384

func get8K() *[]byte {
	p, _ := pool8K.Get().(*[]byte)
	return p
}

func getb8K() *bytes.Buffer {
	b, _ := poolb8K.Get().(*bytes.Buffer)
	return b
}

func getr8K() *bufio.Reader {
	r, _ := poolr8K.Get().(*bufio.Reader)
	return r
}

func getw8K() *bufio.Writer {
	w, _ := poolw8K.Get().(*bufio.Writer)
	return w
}

func put8K(b *[]byte) {
	pool8K.Put(b)
}

func putb8K(b *bytes.Buffer) {
	poolb8K.Put(b)
}

func putr8K(r *bufio.Reader) {
	poolr8K.Put(r)
}

func putw8K(w *bufio.Writer) {
	poolw8K.Put(w)
}

// GetBytesBuffer8K gets a bytes.Buffer with a capacity of at least 8K bytes.
func GetBytesBuffer8K() *bytes.Buffer {
	if b := getb8K(); b != nil {
		return b
	}
	if p := get8K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 8192))
}

// GetBytesSlice8K gets a byte slice with a capacity of at least 8K bytes and length of 8K bytes.
// GetBytesSlice8K is somewhat slower than GetBytesSlicePtr8K, but it is significantly easier to use.
func GetBytesSlice8K() []byte {
	if p := get8K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb8K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 8192)
	return p
}

// GetBytesSlicePtr8K is like GetBytesSlice8K but returns a pointer to the slice instead.
// GetBytesSlicePtr8K is somewhat faster than GetBytesSlice8K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr8K the original pointer returned by GetBytesSlicePtr8K to recycle the slice.
func GetBytesSlicePtr8K() *[]byte {
	if p := get8K(); p != nil {
		return p
	}
	if b := getb8K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 8192)
	return &p
}

// GetBufioReader8K returns a bufio.Reader with an internal buffer size of at least 8192.
func GetBufioReader8K(pr io.Reader) *bufio.Reader {
	if r := getr8K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 8192)
}

// GetBufioWriter8K returns a bufio.Writer with an internal buffer size of at least 8192.
func GetBufioWriter8K(pw io.Writer) *bufio.Writer {
	if w := getw8K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 8192)
}

// PutBytesBuffer8K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer8K is optimized for bytes.Buffer of capacity [8192, 16384) but will accepts other
// sizes as well.
func PutBytesBuffer8K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 8192 || l >= 16384 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb8K(b)
	return true
}

// PutBytesSlice8K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice8K is optimized for byte slice of capacity [8192, 16384) but will accepts other
// sizes as well.
// PutBytesSlice8K, contrary to PutBytesSlicePtr8K, will perform a pointer-sized allocation for each call.
func PutBytesSlice8K(p []byte) bool {
	if l := cap(p); l < 8192 || l >= 16384 {
		return PutBytesSlice(p)
	}
	p = p[0:8192]
	put8K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr8K is like PutBytesSlice8K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr8K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 8192 || l >= 16384 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:8192]
	put8K(p)
	return true
}

// PutBufioReader8K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader8K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader8K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader8K is optimized for bufio.Reader with Size() in the range (8192, 16384], but it accepts
// also other sizes.
func PutBufioReader8K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 8192 || l >= 16384 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr8K(r)
	return true
}

// PutBufioWriter8K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter8K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter8K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter8K is optimized for bufio.Writer with Size() in the range (8192, 16384], but it accepts
// also other sizes.
func PutBufioWriter8K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 8192 || l >= 16384 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw8K(w)
	return true
}

// BufferPool8K is a httputil.BufferPool that provides byte slices of 8K bytes.
type BufferPool8K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool8K) Get() []byte {
	return GetBytesSlice8K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool8K) Put(b []byte) {
	PutBytesSlice8K(b)
}

// BufferPtrPool8K is like BufferPool8K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool8K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr8K for details.
func (_ BufferPtrPool8K) Get() *[]byte {
	return GetBytesSlicePtr8K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr8K for details.
func (_ BufferPtrPool8K) Put(b *[]byte) {
	PutBytesSlicePtr8K(b)
}

var pool16K sync.Pool  // *[]byte, 16384 <= cap < 32768
var poolb16K sync.Pool // *bytes.Buffer, 16384 <= Cap < 32768
var poolr16K sync.Pool // *bufio.Reader, 16384 <= Size < 32768
var poolw16K sync.Pool // *bufio.Writer, 16384 <= Size < 32768

func get16K() *[]byte {
	p, _ := pool16K.Get().(*[]byte)
	return p
}

func getb16K() *bytes.Buffer {
	b, _ := poolb16K.Get().(*bytes.Buffer)
	return b
}

func getr16K() *bufio.Reader {
	r, _ := poolr16K.Get().(*bufio.Reader)
	return r
}

func getw16K() *bufio.Writer {
	w, _ := poolw16K.Get().(*bufio.Writer)
	return w
}

func put16K(b *[]byte) {
	pool16K.Put(b)
}

func putb16K(b *bytes.Buffer) {
	poolb16K.Put(b)
}

func putr16K(r *bufio.Reader) {
	poolr16K.Put(r)
}

func putw16K(w *bufio.Writer) {
	poolw16K.Put(w)
}

// GetBytesBuffer16K gets a bytes.Buffer with a capacity of at least 16K bytes.
func GetBytesBuffer16K() *bytes.Buffer {
	if b := getb16K(); b != nil {
		return b
	}
	if p := get16K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 16384))
}

// GetBytesSlice16K gets a byte slice with a capacity of at least 16K bytes and length of 16K bytes.
// GetBytesSlice16K is somewhat slower than GetBytesSlicePtr16K, but it is significantly easier to use.
func GetBytesSlice16K() []byte {
	if p := get16K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb16K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 16384)
	return p
}

// GetBytesSlicePtr16K is like GetBytesSlice16K but returns a pointer to the slice instead.
// GetBytesSlicePtr16K is somewhat faster than GetBytesSlice16K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr16K the original pointer returned by GetBytesSlicePtr16K to recycle the slice.
func GetBytesSlicePtr16K() *[]byte {
	if p := get16K(); p != nil {
		return p
	}
	if b := getb16K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 16384)
	return &p
}

// GetBufioReader16K returns a bufio.Reader with an internal buffer size of at least 16384.
func GetBufioReader16K(pr io.Reader) *bufio.Reader {
	if r := getr16K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 16384)
}

// GetBufioWriter16K returns a bufio.Writer with an internal buffer size of at least 16384.
func GetBufioWriter16K(pw io.Writer) *bufio.Writer {
	if w := getw16K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 16384)
}

// PutBytesBuffer16K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer16K is optimized for bytes.Buffer of capacity [16384, 32768) but will accepts other
// sizes as well.
func PutBytesBuffer16K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 16384 || l >= 32768 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb16K(b)
	return true
}

// PutBytesSlice16K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice16K is optimized for byte slice of capacity [16384, 32768) but will accepts other
// sizes as well.
// PutBytesSlice16K, contrary to PutBytesSlicePtr16K, will perform a pointer-sized allocation for each call.
func PutBytesSlice16K(p []byte) bool {
	if l := cap(p); l < 16384 || l >= 32768 {
		return PutBytesSlice(p)
	}
	p = p[0:16384]
	put16K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr16K is like PutBytesSlice16K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr16K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 16384 || l >= 32768 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:16384]
	put16K(p)
	return true
}

// PutBufioReader16K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader16K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader16K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader16K is optimized for bufio.Reader with Size() in the range (16384, 32768], but it accepts
// also other sizes.
func PutBufioReader16K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 16384 || l >= 32768 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr16K(r)
	return true
}

// PutBufioWriter16K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter16K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter16K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter16K is optimized for bufio.Writer with Size() in the range (16384, 32768], but it accepts
// also other sizes.
func PutBufioWriter16K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 16384 || l >= 32768 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw16K(w)
	return true
}

// BufferPool16K is a httputil.BufferPool that provides byte slices of 16K bytes.
type BufferPool16K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool16K) Get() []byte {
	return GetBytesSlice16K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool16K) Put(b []byte) {
	PutBytesSlice16K(b)
}

// BufferPtrPool16K is like BufferPool16K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool16K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr16K for details.
func (_ BufferPtrPool16K) Get() *[]byte {
	return GetBytesSlicePtr16K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr16K for details.
func (_ BufferPtrPool16K) Put(b *[]byte) {
	PutBytesSlicePtr16K(b)
}

var pool32K sync.Pool  // *[]byte, 32768 <= cap < 65536
var poolb32K sync.Pool // *bytes.Buffer, 32768 <= Cap < 65536
var poolr32K sync.Pool // *bufio.Reader, 32768 <= Size < 65536
var poolw32K sync.Pool // *bufio.Writer, 32768 <= Size < 65536

func get32K() *[]byte {
	p, _ := pool32K.Get().(*[]byte)
	return p
}

func getb32K() *bytes.Buffer {
	b, _ := poolb32K.Get().(*bytes.Buffer)
	return b
}

func getr32K() *bufio.Reader {
	r, _ := poolr32K.Get().(*bufio.Reader)
	return r
}

func getw32K() *bufio.Writer {
	w, _ := poolw32K.Get().(*bufio.Writer)
	return w
}

func put32K(b *[]byte) {
	pool32K.Put(b)
}

func putb32K(b *bytes.Buffer) {
	poolb32K.Put(b)
}

func putr32K(r *bufio.Reader) {
	poolr32K.Put(r)
}

func putw32K(w *bufio.Writer) {
	poolw32K.Put(w)
}

// GetBytesBuffer32K gets a bytes.Buffer with a capacity of at least 32K bytes.
func GetBytesBuffer32K() *bytes.Buffer {
	if b := getb32K(); b != nil {
		return b
	}
	if p := get32K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 32768))
}

// GetBytesSlice32K gets a byte slice with a capacity of at least 32K bytes and length of 32K bytes.
// GetBytesSlice32K is somewhat slower than GetBytesSlicePtr32K, but it is significantly easier to use.
func GetBytesSlice32K() []byte {
	if p := get32K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb32K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 32768)
	return p
}

// GetBytesSlicePtr32K is like GetBytesSlice32K but returns a pointer to the slice instead.
// GetBytesSlicePtr32K is somewhat faster than GetBytesSlice32K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr32K the original pointer returned by GetBytesSlicePtr32K to recycle the slice.
func GetBytesSlicePtr32K() *[]byte {
	if p := get32K(); p != nil {
		return p
	}
	if b := getb32K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 32768)
	return &p
}

// GetBufioReader32K returns a bufio.Reader with an internal buffer size of at least 32768.
func GetBufioReader32K(pr io.Reader) *bufio.Reader {
	if r := getr32K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 32768)
}

// GetBufioWriter32K returns a bufio.Writer with an internal buffer size of at least 32768.
func GetBufioWriter32K(pw io.Writer) *bufio.Writer {
	if w := getw32K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 32768)
}

// PutBytesBuffer32K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer32K is optimized for bytes.Buffer of capacity [32768, 65536) but will accepts other
// sizes as well.
func PutBytesBuffer32K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 32768 || l >= 65536 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb32K(b)
	return true
}

// PutBytesSlice32K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice32K is optimized for byte slice of capacity [32768, 65536) but will accepts other
// sizes as well.
// PutBytesSlice32K, contrary to PutBytesSlicePtr32K, will perform a pointer-sized allocation for each call.
func PutBytesSlice32K(p []byte) bool {
	if l := cap(p); l < 32768 || l >= 65536 {
		return PutBytesSlice(p)
	}
	p = p[0:32768]
	put32K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr32K is like PutBytesSlice32K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr32K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 32768 || l >= 65536 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:32768]
	put32K(p)
	return true
}

// PutBufioReader32K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader32K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader32K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader32K is optimized for bufio.Reader with Size() in the range (32768, 65536], but it accepts
// also other sizes.
func PutBufioReader32K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 32768 || l >= 65536 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr32K(r)
	return true
}

// PutBufioWriter32K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter32K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter32K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter32K is optimized for bufio.Writer with Size() in the range (32768, 65536], but it accepts
// also other sizes.
func PutBufioWriter32K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 32768 || l >= 65536 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw32K(w)
	return true
}

// BufferPool32K is a httputil.BufferPool that provides byte slices of 32K bytes.
type BufferPool32K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool32K) Get() []byte {
	return GetBytesSlice32K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool32K) Put(b []byte) {
	PutBytesSlice32K(b)
}

// BufferPtrPool32K is like BufferPool32K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool32K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr32K for details.
func (_ BufferPtrPool32K) Get() *[]byte {
	return GetBytesSlicePtr32K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr32K for details.
func (_ BufferPtrPool32K) Put(b *[]byte) {
	PutBytesSlicePtr32K(b)
}

var pool64K sync.Pool  // *[]byte, 65536 <= cap < 131072
var poolb64K sync.Pool // *bytes.Buffer, 65536 <= Cap < 131072
var poolr64K sync.Pool // *bufio.Reader, 65536 <= Size < 131072
var poolw64K sync.Pool // *bufio.Writer, 65536 <= Size < 131072

func get64K() *[]byte {
	p, _ := pool64K.Get().(*[]byte)
	return p
}

func getb64K() *bytes.Buffer {
	b, _ := poolb64K.Get().(*bytes.Buffer)
	return b
}

func getr64K() *bufio.Reader {
	r, _ := poolr64K.Get().(*bufio.Reader)
	return r
}

func getw64K() *bufio.Writer {
	w, _ := poolw64K.Get().(*bufio.Writer)
	return w
}

func put64K(b *[]byte) {
	pool64K.Put(b)
}

func putb64K(b *bytes.Buffer) {
	poolb64K.Put(b)
}

func putr64K(r *bufio.Reader) {
	poolr64K.Put(r)
}

func putw64K(w *bufio.Writer) {
	poolw64K.Put(w)
}

// GetBytesBuffer64K gets a bytes.Buffer with a capacity of at least 64K bytes.
func GetBytesBuffer64K() *bytes.Buffer {
	if b := getb64K(); b != nil {
		return b
	}
	if p := get64K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 65536))
}

// GetBytesSlice64K gets a byte slice with a capacity of at least 64K bytes and length of 64K bytes.
// GetBytesSlice64K is somewhat slower than GetBytesSlicePtr64K, but it is significantly easier to use.
func GetBytesSlice64K() []byte {
	if p := get64K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb64K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 65536)
	return p
}

// GetBytesSlicePtr64K is like GetBytesSlice64K but returns a pointer to the slice instead.
// GetBytesSlicePtr64K is somewhat faster than GetBytesSlice64K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr64K the original pointer returned by GetBytesSlicePtr64K to recycle the slice.
func GetBytesSlicePtr64K() *[]byte {
	if p := get64K(); p != nil {
		return p
	}
	if b := getb64K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 65536)
	return &p
}

// GetBufioReader64K returns a bufio.Reader with an internal buffer size of at least 65536.
func GetBufioReader64K(pr io.Reader) *bufio.Reader {
	if r := getr64K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 65536)
}

// GetBufioWriter64K returns a bufio.Writer with an internal buffer size of at least 65536.
func GetBufioWriter64K(pw io.Writer) *bufio.Writer {
	if w := getw64K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 65536)
}

// PutBytesBuffer64K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer64K is optimized for bytes.Buffer of capacity [65536, 131072) but will accepts other
// sizes as well.
func PutBytesBuffer64K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 65536 || l >= 131072 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb64K(b)
	return true
}

// PutBytesSlice64K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice64K is optimized for byte slice of capacity [65536, 131072) but will accepts other
// sizes as well.
// PutBytesSlice64K, contrary to PutBytesSlicePtr64K, will perform a pointer-sized allocation for each call.
func PutBytesSlice64K(p []byte) bool {
	if l := cap(p); l < 65536 || l >= 131072 {
		return PutBytesSlice(p)
	}
	p = p[0:65536]
	put64K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr64K is like PutBytesSlice64K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr64K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 65536 || l >= 131072 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:65536]
	put64K(p)
	return true
}

// PutBufioReader64K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader64K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader64K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader64K is optimized for bufio.Reader with Size() in the range (65536, 131072], but it accepts
// also other sizes.
func PutBufioReader64K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 65536 || l >= 131072 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr64K(r)
	return true
}

// PutBufioWriter64K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter64K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter64K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter64K is optimized for bufio.Writer with Size() in the range (65536, 131072], but it accepts
// also other sizes.
func PutBufioWriter64K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 65536 || l >= 131072 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw64K(w)
	return true
}

// BufferPool64K is a httputil.BufferPool that provides byte slices of 64K bytes.
type BufferPool64K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool64K) Get() []byte {
	return GetBytesSlice64K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool64K) Put(b []byte) {
	PutBytesSlice64K(b)
}

// BufferPtrPool64K is like BufferPool64K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool64K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr64K for details.
func (_ BufferPtrPool64K) Get() *[]byte {
	return GetBytesSlicePtr64K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr64K for details.
func (_ BufferPtrPool64K) Put(b *[]byte) {
	PutBytesSlicePtr64K(b)
}

var pool128K sync.Pool  // *[]byte, 131072 <= cap < 262144
var poolb128K sync.Pool // *bytes.Buffer, 131072 <= Cap < 262144
var poolr128K sync.Pool // *bufio.Reader, 131072 <= Size < 262144
var poolw128K sync.Pool // *bufio.Writer, 131072 <= Size < 262144

func get128K() *[]byte {
	p, _ := pool128K.Get().(*[]byte)
	return p
}

func getb128K() *bytes.Buffer {
	b, _ := poolb128K.Get().(*bytes.Buffer)
	return b
}

func getr128K() *bufio.Reader {
	r, _ := poolr128K.Get().(*bufio.Reader)
	return r
}

func getw128K() *bufio.Writer {
	w, _ := poolw128K.Get().(*bufio.Writer)
	return w
}

func put128K(b *[]byte) {
	pool128K.Put(b)
}

func putb128K(b *bytes.Buffer) {
	poolb128K.Put(b)
}

func putr128K(r *bufio.Reader) {
	poolr128K.Put(r)
}

func putw128K(w *bufio.Writer) {
	poolw128K.Put(w)
}

// GetBytesBuffer128K gets a bytes.Buffer with a capacity of at least 128K bytes.
func GetBytesBuffer128K() *bytes.Buffer {
	if b := getb128K(); b != nil {
		return b
	}
	if p := get128K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 131072))
}

// GetBytesSlice128K gets a byte slice with a capacity of at least 128K bytes and length of 128K bytes.
// GetBytesSlice128K is somewhat slower than GetBytesSlicePtr128K, but it is significantly easier to use.
func GetBytesSlice128K() []byte {
	if p := get128K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb128K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 131072)
	return p
}

// GetBytesSlicePtr128K is like GetBytesSlice128K but returns a pointer to the slice instead.
// GetBytesSlicePtr128K is somewhat faster than GetBytesSlice128K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr128K the original pointer returned by GetBytesSlicePtr128K to recycle the slice.
func GetBytesSlicePtr128K() *[]byte {
	if p := get128K(); p != nil {
		return p
	}
	if b := getb128K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 131072)
	return &p
}

// GetBufioReader128K returns a bufio.Reader with an internal buffer size of at least 131072.
func GetBufioReader128K(pr io.Reader) *bufio.Reader {
	if r := getr128K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 131072)
}

// GetBufioWriter128K returns a bufio.Writer with an internal buffer size of at least 131072.
func GetBufioWriter128K(pw io.Writer) *bufio.Writer {
	if w := getw128K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 131072)
}

// PutBytesBuffer128K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer128K is optimized for bytes.Buffer of capacity [131072, 262144) but will accepts other
// sizes as well.
func PutBytesBuffer128K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 131072 || l >= 262144 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb128K(b)
	return true
}

// PutBytesSlice128K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice128K is optimized for byte slice of capacity [131072, 262144) but will accepts other
// sizes as well.
// PutBytesSlice128K, contrary to PutBytesSlicePtr128K, will perform a pointer-sized allocation for each call.
func PutBytesSlice128K(p []byte) bool {
	if l := cap(p); l < 131072 || l >= 262144 {
		return PutBytesSlice(p)
	}
	p = p[0:131072]
	put128K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr128K is like PutBytesSlice128K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr128K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 131072 || l >= 262144 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:131072]
	put128K(p)
	return true
}

// PutBufioReader128K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader128K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader128K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader128K is optimized for bufio.Reader with Size() in the range (131072, 262144], but it accepts
// also other sizes.
func PutBufioReader128K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 131072 || l >= 262144 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr128K(r)
	return true
}

// PutBufioWriter128K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter128K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter128K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter128K is optimized for bufio.Writer with Size() in the range (131072, 262144], but it accepts
// also other sizes.
func PutBufioWriter128K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 131072 || l >= 262144 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw128K(w)
	return true
}

// BufferPool128K is a httputil.BufferPool that provides byte slices of 128K bytes.
type BufferPool128K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool128K) Get() []byte {
	return GetBytesSlice128K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool128K) Put(b []byte) {
	PutBytesSlice128K(b)
}

// BufferPtrPool128K is like BufferPool128K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool128K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr128K for details.
func (_ BufferPtrPool128K) Get() *[]byte {
	return GetBytesSlicePtr128K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr128K for details.
func (_ BufferPtrPool128K) Put(b *[]byte) {
	PutBytesSlicePtr128K(b)
}

var pool256K sync.Pool  // *[]byte, 262144 <= cap < 524288
var poolb256K sync.Pool // *bytes.Buffer, 262144 <= Cap < 524288
var poolr256K sync.Pool // *bufio.Reader, 262144 <= Size < 524288
var poolw256K sync.Pool // *bufio.Writer, 262144 <= Size < 524288

func get256K() *[]byte {
	p, _ := pool256K.Get().(*[]byte)
	return p
}

func getb256K() *bytes.Buffer {
	b, _ := poolb256K.Get().(*bytes.Buffer)
	return b
}

func getr256K() *bufio.Reader {
	r, _ := poolr256K.Get().(*bufio.Reader)
	return r
}

func getw256K() *bufio.Writer {
	w, _ := poolw256K.Get().(*bufio.Writer)
	return w
}

func put256K(b *[]byte) {
	pool256K.Put(b)
}

func putb256K(b *bytes.Buffer) {
	poolb256K.Put(b)
}

func putr256K(r *bufio.Reader) {
	poolr256K.Put(r)
}

func putw256K(w *bufio.Writer) {
	poolw256K.Put(w)
}

// GetBytesBuffer256K gets a bytes.Buffer with a capacity of at least 256K bytes.
func GetBytesBuffer256K() *bytes.Buffer {
	if b := getb256K(); b != nil {
		return b
	}
	if p := get256K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 262144))
}

// GetBytesSlice256K gets a byte slice with a capacity of at least 256K bytes and length of 256K bytes.
// GetBytesSlice256K is somewhat slower than GetBytesSlicePtr256K, but it is significantly easier to use.
func GetBytesSlice256K() []byte {
	if p := get256K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb256K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 262144)
	return p
}

// GetBytesSlicePtr256K is like GetBytesSlice256K but returns a pointer to the slice instead.
// GetBytesSlicePtr256K is somewhat faster than GetBytesSlice256K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr256K the original pointer returned by GetBytesSlicePtr256K to recycle the slice.
func GetBytesSlicePtr256K() *[]byte {
	if p := get256K(); p != nil {
		return p
	}
	if b := getb256K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 262144)
	return &p
}

// GetBufioReader256K returns a bufio.Reader with an internal buffer size of at least 262144.
func GetBufioReader256K(pr io.Reader) *bufio.Reader {
	if r := getr256K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 262144)
}

// GetBufioWriter256K returns a bufio.Writer with an internal buffer size of at least 262144.
func GetBufioWriter256K(pw io.Writer) *bufio.Writer {
	if w := getw256K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 262144)
}

// PutBytesBuffer256K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer256K is optimized for bytes.Buffer of capacity [262144, 524288) but will accepts other
// sizes as well.
func PutBytesBuffer256K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 262144 || l >= 524288 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb256K(b)
	return true
}

// PutBytesSlice256K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice256K is optimized for byte slice of capacity [262144, 524288) but will accepts other
// sizes as well.
// PutBytesSlice256K, contrary to PutBytesSlicePtr256K, will perform a pointer-sized allocation for each call.
func PutBytesSlice256K(p []byte) bool {
	if l := cap(p); l < 262144 || l >= 524288 {
		return PutBytesSlice(p)
	}
	p = p[0:262144]
	put256K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr256K is like PutBytesSlice256K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr256K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 262144 || l >= 524288 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:262144]
	put256K(p)
	return true
}

// PutBufioReader256K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader256K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader256K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader256K is optimized for bufio.Reader with Size() in the range (262144, 524288], but it accepts
// also other sizes.
func PutBufioReader256K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 262144 || l >= 524288 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr256K(r)
	return true
}

// PutBufioWriter256K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter256K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter256K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter256K is optimized for bufio.Writer with Size() in the range (262144, 524288], but it accepts
// also other sizes.
func PutBufioWriter256K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 262144 || l >= 524288 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw256K(w)
	return true
}

// BufferPool256K is a httputil.BufferPool that provides byte slices of 256K bytes.
type BufferPool256K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool256K) Get() []byte {
	return GetBytesSlice256K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool256K) Put(b []byte) {
	PutBytesSlice256K(b)
}

// BufferPtrPool256K is like BufferPool256K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool256K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr256K for details.
func (_ BufferPtrPool256K) Get() *[]byte {
	return GetBytesSlicePtr256K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr256K for details.
func (_ BufferPtrPool256K) Put(b *[]byte) {
	PutBytesSlicePtr256K(b)
}

var pool512K sync.Pool  // *[]byte, 524288 <= cap < 1048576
var poolb512K sync.Pool // *bytes.Buffer, 524288 <= Cap < 1048576
var poolr512K sync.Pool // *bufio.Reader, 524288 <= Size < 1048576
var poolw512K sync.Pool // *bufio.Writer, 524288 <= Size < 1048576

func get512K() *[]byte {
	p, _ := pool512K.Get().(*[]byte)
	return p
}

func getb512K() *bytes.Buffer {
	b, _ := poolb512K.Get().(*bytes.Buffer)
	return b
}

func getr512K() *bufio.Reader {
	r, _ := poolr512K.Get().(*bufio.Reader)
	return r
}

func getw512K() *bufio.Writer {
	w, _ := poolw512K.Get().(*bufio.Writer)
	return w
}

func put512K(b *[]byte) {
	pool512K.Put(b)
}

func putb512K(b *bytes.Buffer) {
	poolb512K.Put(b)
}

func putr512K(r *bufio.Reader) {
	poolr512K.Put(r)
}

func putw512K(w *bufio.Writer) {
	poolw512K.Put(w)
}

// GetBytesBuffer512K gets a bytes.Buffer with a capacity of at least 512K bytes.
func GetBytesBuffer512K() *bytes.Buffer {
	if b := getb512K(); b != nil {
		return b
	}
	if p := get512K(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 524288))
}

// GetBytesSlice512K gets a byte slice with a capacity of at least 512K bytes and length of 512K bytes.
// GetBytesSlice512K is somewhat slower than GetBytesSlicePtr512K, but it is significantly easier to use.
func GetBytesSlice512K() []byte {
	if p := get512K(); p != nil {
		return internal.Puts(p)
	}
	if b := getb512K(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 524288)
	return p
}

// GetBytesSlicePtr512K is like GetBytesSlice512K but returns a pointer to the slice instead.
// GetBytesSlicePtr512K is somewhat faster than GetBytesSlice512K, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr512K the original pointer returned by GetBytesSlicePtr512K to recycle the slice.
func GetBytesSlicePtr512K() *[]byte {
	if p := get512K(); p != nil {
		return p
	}
	if b := getb512K(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 524288)
	return &p
}

// GetBufioReader512K returns a bufio.Reader with an internal buffer size of at least 524288.
func GetBufioReader512K(pr io.Reader) *bufio.Reader {
	if r := getr512K(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 524288)
}

// GetBufioWriter512K returns a bufio.Writer with an internal buffer size of at least 524288.
func GetBufioWriter512K(pw io.Writer) *bufio.Writer {
	if w := getw512K(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 524288)
}

// PutBytesBuffer512K recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer512K is optimized for bytes.Buffer of capacity [524288, 1048576) but will accepts other
// sizes as well.
func PutBytesBuffer512K(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 524288 || l >= 1048576 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb512K(b)
	return true
}

// PutBytesSlice512K recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice512K is optimized for byte slice of capacity [524288, 1048576) but will accepts other
// sizes as well.
// PutBytesSlice512K, contrary to PutBytesSlicePtr512K, will perform a pointer-sized allocation for each call.
func PutBytesSlice512K(p []byte) bool {
	if l := cap(p); l < 524288 || l >= 1048576 {
		return PutBytesSlice(p)
	}
	p = p[0:524288]
	put512K(internal.Gets(p))
	return true
}

// PutBytesSlicePtr512K is like PutBytesSlice512K, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr512K(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 524288 || l >= 1048576 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:524288]
	put512K(p)
	return true
}

// PutBufioReader512K recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader512K is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader512K callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader512K is optimized for bufio.Reader with Size() in the range (524288, 1048576], but it accepts
// also other sizes.
func PutBufioReader512K(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 524288 || l >= 1048576 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr512K(r)
	return true
}

// PutBufioWriter512K recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter512K is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter512K callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter512K is optimized for bufio.Writer with Size() in the range (524288, 1048576], but it accepts
// also other sizes.
func PutBufioWriter512K(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 524288 || l >= 1048576 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw512K(w)
	return true
}

// BufferPool512K is a httputil.BufferPool that provides byte slices of 512K bytes.
type BufferPool512K struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool512K) Get() []byte {
	return GetBytesSlice512K()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool512K) Put(b []byte) {
	PutBytesSlice512K(b)
}

// BufferPtrPool512K is like BufferPool512K, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool512K struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr512K for details.
func (_ BufferPtrPool512K) Get() *[]byte {
	return GetBytesSlicePtr512K()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr512K for details.
func (_ BufferPtrPool512K) Put(b *[]byte) {
	PutBytesSlicePtr512K(b)
}

var pool1M sync.Pool  // *[]byte, 1048576 <= cap < 2097152
var poolb1M sync.Pool // *bytes.Buffer, 1048576 <= Cap < 2097152
var poolr1M sync.Pool // *bufio.Reader, 1048576 <= Size < 2097152
var poolw1M sync.Pool // *bufio.Writer, 1048576 <= Size < 2097152

func get1M() *[]byte {
	p, _ := pool1M.Get().(*[]byte)
	return p
}

func getb1M() *bytes.Buffer {
	b, _ := poolb1M.Get().(*bytes.Buffer)
	return b
}

func getr1M() *bufio.Reader {
	r, _ := poolr1M.Get().(*bufio.Reader)
	return r
}

func getw1M() *bufio.Writer {
	w, _ := poolw1M.Get().(*bufio.Writer)
	return w
}

func put1M(b *[]byte) {
	pool1M.Put(b)
}

func putb1M(b *bytes.Buffer) {
	poolb1M.Put(b)
}

func putr1M(r *bufio.Reader) {
	poolr1M.Put(r)
}

func putw1M(w *bufio.Writer) {
	poolw1M.Put(w)
}

// GetBytesBuffer1M gets a bytes.Buffer with a capacity of at least 1M bytes.
func GetBytesBuffer1M() *bytes.Buffer {
	if b := getb1M(); b != nil {
		return b
	}
	if p := get1M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 1048576))
}

// GetBytesSlice1M gets a byte slice with a capacity of at least 1M bytes and length of 1M bytes.
// GetBytesSlice1M is somewhat slower than GetBytesSlicePtr1M, but it is significantly easier to use.
func GetBytesSlice1M() []byte {
	if p := get1M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb1M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 1048576)
	return p
}

// GetBytesSlicePtr1M is like GetBytesSlice1M but returns a pointer to the slice instead.
// GetBytesSlicePtr1M is somewhat faster than GetBytesSlice1M, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr1M the original pointer returned by GetBytesSlicePtr1M to recycle the slice.
func GetBytesSlicePtr1M() *[]byte {
	if p := get1M(); p != nil {
		return p
	}
	if b := getb1M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 1048576)
	return &p
}

// GetBufioReader1M returns a bufio.Reader with an internal buffer size of at least 1048576.
func GetBufioReader1M(pr io.Reader) *bufio.Reader {
	if r := getr1M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 1048576)
}

// GetBufioWriter1M returns a bufio.Writer with an internal buffer size of at least 1048576.
func GetBufioWriter1M(pw io.Writer) *bufio.Writer {
	if w := getw1M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 1048576)
}

// PutBytesBuffer1M recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer1M is optimized for bytes.Buffer of capacity [1048576, 2097152) but will accepts other
// sizes as well.
func PutBytesBuffer1M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 1048576 || l >= 2097152 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb1M(b)
	return true
}

// PutBytesSlice1M recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice1M is optimized for byte slice of capacity [1048576, 2097152) but will accepts other
// sizes as well.
// PutBytesSlice1M, contrary to PutBytesSlicePtr1M, will perform a pointer-sized allocation for each call.
func PutBytesSlice1M(p []byte) bool {
	if l := cap(p); l < 1048576 || l >= 2097152 {
		return PutBytesSlice(p)
	}
	p = p[0:1048576]
	put1M(internal.Gets(p))
	return true
}

// PutBytesSlicePtr1M is like PutBytesSlice1M, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr1M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 1048576 || l >= 2097152 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:1048576]
	put1M(p)
	return true
}

// PutBufioReader1M recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader1M is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader1M callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader1M is optimized for bufio.Reader with Size() in the range (1048576, 2097152], but it accepts
// also other sizes.
func PutBufioReader1M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 1048576 || l >= 2097152 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr1M(r)
	return true
}

// PutBufioWriter1M recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter1M is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter1M callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter1M is optimized for bufio.Writer with Size() in the range (1048576, 2097152], but it accepts
// also other sizes.
func PutBufioWriter1M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 1048576 || l >= 2097152 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw1M(w)
	return true
}

// BufferPool1M is a httputil.BufferPool that provides byte slices of 1M bytes.
type BufferPool1M struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool1M) Get() []byte {
	return GetBytesSlice1M()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool1M) Put(b []byte) {
	PutBytesSlice1M(b)
}

// BufferPtrPool1M is like BufferPool1M, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool1M struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr1M for details.
func (_ BufferPtrPool1M) Get() *[]byte {
	return GetBytesSlicePtr1M()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr1M for details.
func (_ BufferPtrPool1M) Put(b *[]byte) {
	PutBytesSlicePtr1M(b)
}

var pool2M sync.Pool  // *[]byte, 2097152 <= cap < 4194304
var poolb2M sync.Pool // *bytes.Buffer, 2097152 <= Cap < 4194304
var poolr2M sync.Pool // *bufio.Reader, 2097152 <= Size < 4194304
var poolw2M sync.Pool // *bufio.Writer, 2097152 <= Size < 4194304

func get2M() *[]byte {
	p, _ := pool2M.Get().(*[]byte)
	return p
}

func getb2M() *bytes.Buffer {
	b, _ := poolb2M.Get().(*bytes.Buffer)
	return b
}

func getr2M() *bufio.Reader {
	r, _ := poolr2M.Get().(*bufio.Reader)
	return r
}

func getw2M() *bufio.Writer {
	w, _ := poolw2M.Get().(*bufio.Writer)
	return w
}

func put2M(b *[]byte) {
	pool2M.Put(b)
}

func putb2M(b *bytes.Buffer) {
	poolb2M.Put(b)
}

func putr2M(r *bufio.Reader) {
	poolr2M.Put(r)
}

func putw2M(w *bufio.Writer) {
	poolw2M.Put(w)
}

// GetBytesBuffer2M gets a bytes.Buffer with a capacity of at least 2M bytes.
func GetBytesBuffer2M() *bytes.Buffer {
	if b := getb2M(); b != nil {
		return b
	}
	if p := get2M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 2097152))
}

// GetBytesSlice2M gets a byte slice with a capacity of at least 2M bytes and length of 2M bytes.
// GetBytesSlice2M is somewhat slower than GetBytesSlicePtr2M, but it is significantly easier to use.
func GetBytesSlice2M() []byte {
	if p := get2M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb2M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 2097152)
	return p
}

// GetBytesSlicePtr2M is like GetBytesSlice2M but returns a pointer to the slice instead.
// GetBytesSlicePtr2M is somewhat faster than GetBytesSlice2M, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr2M the original pointer returned by GetBytesSlicePtr2M to recycle the slice.
func GetBytesSlicePtr2M() *[]byte {
	if p := get2M(); p != nil {
		return p
	}
	if b := getb2M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 2097152)
	return &p
}

// GetBufioReader2M returns a bufio.Reader with an internal buffer size of at least 2097152.
func GetBufioReader2M(pr io.Reader) *bufio.Reader {
	if r := getr2M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 2097152)
}

// GetBufioWriter2M returns a bufio.Writer with an internal buffer size of at least 2097152.
func GetBufioWriter2M(pw io.Writer) *bufio.Writer {
	if w := getw2M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 2097152)
}

// PutBytesBuffer2M recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer2M is optimized for bytes.Buffer of capacity [2097152, 4194304) but will accepts other
// sizes as well.
func PutBytesBuffer2M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 2097152 || l >= 4194304 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb2M(b)
	return true
}

// PutBytesSlice2M recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice2M is optimized for byte slice of capacity [2097152, 4194304) but will accepts other
// sizes as well.
// PutBytesSlice2M, contrary to PutBytesSlicePtr2M, will perform a pointer-sized allocation for each call.
func PutBytesSlice2M(p []byte) bool {
	if l := cap(p); l < 2097152 || l >= 4194304 {
		return PutBytesSlice(p)
	}
	p = p[0:2097152]
	put2M(internal.Gets(p))
	return true
}

// PutBytesSlicePtr2M is like PutBytesSlice2M, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr2M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 2097152 || l >= 4194304 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:2097152]
	put2M(p)
	return true
}

// PutBufioReader2M recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader2M is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader2M callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader2M is optimized for bufio.Reader with Size() in the range (2097152, 4194304], but it accepts
// also other sizes.
func PutBufioReader2M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 2097152 || l >= 4194304 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr2M(r)
	return true
}

// PutBufioWriter2M recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter2M is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter2M callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter2M is optimized for bufio.Writer with Size() in the range (2097152, 4194304], but it accepts
// also other sizes.
func PutBufioWriter2M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 2097152 || l >= 4194304 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw2M(w)
	return true
}

// BufferPool2M is a httputil.BufferPool that provides byte slices of 2M bytes.
type BufferPool2M struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool2M) Get() []byte {
	return GetBytesSlice2M()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool2M) Put(b []byte) {
	PutBytesSlice2M(b)
}

// BufferPtrPool2M is like BufferPool2M, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool2M struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr2M for details.
func (_ BufferPtrPool2M) Get() *[]byte {
	return GetBytesSlicePtr2M()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr2M for details.
func (_ BufferPtrPool2M) Put(b *[]byte) {
	PutBytesSlicePtr2M(b)
}

var pool4M sync.Pool  // *[]byte, 4194304 <= cap < 8388608
var poolb4M sync.Pool // *bytes.Buffer, 4194304 <= Cap < 8388608
var poolr4M sync.Pool // *bufio.Reader, 4194304 <= Size < 8388608
var poolw4M sync.Pool // *bufio.Writer, 4194304 <= Size < 8388608

func get4M() *[]byte {
	p, _ := pool4M.Get().(*[]byte)
	return p
}

func getb4M() *bytes.Buffer {
	b, _ := poolb4M.Get().(*bytes.Buffer)
	return b
}

func getr4M() *bufio.Reader {
	r, _ := poolr4M.Get().(*bufio.Reader)
	return r
}

func getw4M() *bufio.Writer {
	w, _ := poolw4M.Get().(*bufio.Writer)
	return w
}

func put4M(b *[]byte) {
	pool4M.Put(b)
}

func putb4M(b *bytes.Buffer) {
	poolb4M.Put(b)
}

func putr4M(r *bufio.Reader) {
	poolr4M.Put(r)
}

func putw4M(w *bufio.Writer) {
	poolw4M.Put(w)
}

// GetBytesBuffer4M gets a bytes.Buffer with a capacity of at least 4M bytes.
func GetBytesBuffer4M() *bytes.Buffer {
	if b := getb4M(); b != nil {
		return b
	}
	if p := get4M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 4194304))
}

// GetBytesSlice4M gets a byte slice with a capacity of at least 4M bytes and length of 4M bytes.
// GetBytesSlice4M is somewhat slower than GetBytesSlicePtr4M, but it is significantly easier to use.
func GetBytesSlice4M() []byte {
	if p := get4M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb4M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 4194304)
	return p
}

// GetBytesSlicePtr4M is like GetBytesSlice4M but returns a pointer to the slice instead.
// GetBytesSlicePtr4M is somewhat faster than GetBytesSlice4M, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr4M the original pointer returned by GetBytesSlicePtr4M to recycle the slice.
func GetBytesSlicePtr4M() *[]byte {
	if p := get4M(); p != nil {
		return p
	}
	if b := getb4M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 4194304)
	return &p
}

// GetBufioReader4M returns a bufio.Reader with an internal buffer size of at least 4194304.
func GetBufioReader4M(pr io.Reader) *bufio.Reader {
	if r := getr4M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 4194304)
}

// GetBufioWriter4M returns a bufio.Writer with an internal buffer size of at least 4194304.
func GetBufioWriter4M(pw io.Writer) *bufio.Writer {
	if w := getw4M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 4194304)
}

// PutBytesBuffer4M recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer4M is optimized for bytes.Buffer of capacity [4194304, 8388608) but will accepts other
// sizes as well.
func PutBytesBuffer4M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 4194304 || l >= 8388608 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb4M(b)
	return true
}

// PutBytesSlice4M recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice4M is optimized for byte slice of capacity [4194304, 8388608) but will accepts other
// sizes as well.
// PutBytesSlice4M, contrary to PutBytesSlicePtr4M, will perform a pointer-sized allocation for each call.
func PutBytesSlice4M(p []byte) bool {
	if l := cap(p); l < 4194304 || l >= 8388608 {
		return PutBytesSlice(p)
	}
	p = p[0:4194304]
	put4M(internal.Gets(p))
	return true
}

// PutBytesSlicePtr4M is like PutBytesSlice4M, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr4M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 4194304 || l >= 8388608 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:4194304]
	put4M(p)
	return true
}

// PutBufioReader4M recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader4M is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader4M callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader4M is optimized for bufio.Reader with Size() in the range (4194304, 8388608], but it accepts
// also other sizes.
func PutBufioReader4M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 4194304 || l >= 8388608 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr4M(r)
	return true
}

// PutBufioWriter4M recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter4M is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter4M callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter4M is optimized for bufio.Writer with Size() in the range (4194304, 8388608], but it accepts
// also other sizes.
func PutBufioWriter4M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 4194304 || l >= 8388608 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw4M(w)
	return true
}

// BufferPool4M is a httputil.BufferPool that provides byte slices of 4M bytes.
type BufferPool4M struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool4M) Get() []byte {
	return GetBytesSlice4M()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool4M) Put(b []byte) {
	PutBytesSlice4M(b)
}

// BufferPtrPool4M is like BufferPool4M, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool4M struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr4M for details.
func (_ BufferPtrPool4M) Get() *[]byte {
	return GetBytesSlicePtr4M()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr4M for details.
func (_ BufferPtrPool4M) Put(b *[]byte) {
	PutBytesSlicePtr4M(b)
}

var pool8M sync.Pool  // *[]byte, 8388608 <= cap < 16777216
var poolb8M sync.Pool // *bytes.Buffer, 8388608 <= Cap < 16777216
var poolr8M sync.Pool // *bufio.Reader, 8388608 <= Size < 16777216
var poolw8M sync.Pool // *bufio.Writer, 8388608 <= Size < 16777216

func get8M() *[]byte {
	p, _ := pool8M.Get().(*[]byte)
	return p
}

func getb8M() *bytes.Buffer {
	b, _ := poolb8M.Get().(*bytes.Buffer)
	return b
}

func getr8M() *bufio.Reader {
	r, _ := poolr8M.Get().(*bufio.Reader)
	return r
}

func getw8M() *bufio.Writer {
	w, _ := poolw8M.Get().(*bufio.Writer)
	return w
}

func put8M(b *[]byte) {
	pool8M.Put(b)
}

func putb8M(b *bytes.Buffer) {
	poolb8M.Put(b)
}

func putr8M(r *bufio.Reader) {
	poolr8M.Put(r)
}

func putw8M(w *bufio.Writer) {
	poolw8M.Put(w)
}

// GetBytesBuffer8M gets a bytes.Buffer with a capacity of at least 8M bytes.
func GetBytesBuffer8M() *bytes.Buffer {
	if b := getb8M(); b != nil {
		return b
	}
	if p := get8M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 8388608))
}

// GetBytesSlice8M gets a byte slice with a capacity of at least 8M bytes and length of 8M bytes.
// GetBytesSlice8M is somewhat slower than GetBytesSlicePtr8M, but it is significantly easier to use.
func GetBytesSlice8M() []byte {
	if p := get8M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb8M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 8388608)
	return p
}

// GetBytesSlicePtr8M is like GetBytesSlice8M but returns a pointer to the slice instead.
// GetBytesSlicePtr8M is somewhat faster than GetBytesSlice8M, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr8M the original pointer returned by GetBytesSlicePtr8M to recycle the slice.
func GetBytesSlicePtr8M() *[]byte {
	if p := get8M(); p != nil {
		return p
	}
	if b := getb8M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 8388608)
	return &p
}

// GetBufioReader8M returns a bufio.Reader with an internal buffer size of at least 8388608.
func GetBufioReader8M(pr io.Reader) *bufio.Reader {
	if r := getr8M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 8388608)
}

// GetBufioWriter8M returns a bufio.Writer with an internal buffer size of at least 8388608.
func GetBufioWriter8M(pw io.Writer) *bufio.Writer {
	if w := getw8M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 8388608)
}

// PutBytesBuffer8M recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer8M is optimized for bytes.Buffer of capacity [8388608, 16777216) but will accepts other
// sizes as well.
func PutBytesBuffer8M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 8388608 || l >= 16777216 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb8M(b)
	return true
}

// PutBytesSlice8M recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice8M is optimized for byte slice of capacity [8388608, 16777216) but will accepts other
// sizes as well.
// PutBytesSlice8M, contrary to PutBytesSlicePtr8M, will perform a pointer-sized allocation for each call.
func PutBytesSlice8M(p []byte) bool {
	if l := cap(p); l < 8388608 || l >= 16777216 {
		return PutBytesSlice(p)
	}
	p = p[0:8388608]
	put8M(internal.Gets(p))
	return true
}

// PutBytesSlicePtr8M is like PutBytesSlice8M, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr8M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 8388608 || l >= 16777216 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:8388608]
	put8M(p)
	return true
}

// PutBufioReader8M recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader8M is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader8M callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader8M is optimized for bufio.Reader with Size() in the range (8388608, 16777216], but it accepts
// also other sizes.
func PutBufioReader8M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 8388608 || l >= 16777216 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr8M(r)
	return true
}

// PutBufioWriter8M recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter8M is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter8M callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter8M is optimized for bufio.Writer with Size() in the range (8388608, 16777216], but it accepts
// also other sizes.
func PutBufioWriter8M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 8388608 || l >= 16777216 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw8M(w)
	return true
}

// BufferPool8M is a httputil.BufferPool that provides byte slices of 8M bytes.
type BufferPool8M struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool8M) Get() []byte {
	return GetBytesSlice8M()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool8M) Put(b []byte) {
	PutBytesSlice8M(b)
}

// BufferPtrPool8M is like BufferPool8M, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool8M struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr8M for details.
func (_ BufferPtrPool8M) Get() *[]byte {
	return GetBytesSlicePtr8M()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr8M for details.
func (_ BufferPtrPool8M) Put(b *[]byte) {
	PutBytesSlicePtr8M(b)
}

var pool16M sync.Pool  // *[]byte, 16777216 <= cap < 33554432
var poolb16M sync.Pool // *bytes.Buffer, 16777216 <= Cap < 33554432
var poolr16M sync.Pool // *bufio.Reader, 16777216 <= Size < 33554432
var poolw16M sync.Pool // *bufio.Writer, 16777216 <= Size < 33554432

func get16M() *[]byte {
	p, _ := pool16M.Get().(*[]byte)
	return p
}

func getb16M() *bytes.Buffer {
	b, _ := poolb16M.Get().(*bytes.Buffer)
	return b
}

func getr16M() *bufio.Reader {
	r, _ := poolr16M.Get().(*bufio.Reader)
	return r
}

func getw16M() *bufio.Writer {
	w, _ := poolw16M.Get().(*bufio.Writer)
	return w
}

func put16M(b *[]byte) {
	pool16M.Put(b)
}

func putb16M(b *bytes.Buffer) {
	poolb16M.Put(b)
}

func putr16M(r *bufio.Reader) {
	poolr16M.Put(r)
}

func putw16M(w *bufio.Writer) {
	poolw16M.Put(w)
}

// GetBytesBuffer16M gets a bytes.Buffer with a capacity of at least 16M bytes.
func GetBytesBuffer16M() *bytes.Buffer {
	if b := getb16M(); b != nil {
		return b
	}
	if p := get16M(); p != nil {
		return bytes.NewBuffer(internal.Puts(p))
	}
	return bytes.NewBuffer(make([]byte, 16777216))
}

// GetBytesSlice16M gets a byte slice with a capacity of at least 16M bytes and length of 16M bytes.
// GetBytesSlice16M is somewhat slower than GetBytesSlicePtr16M, but it is significantly easier to use.
func GetBytesSlice16M() []byte {
	if p := get16M(); p != nil {
		return internal.Puts(p)
	}
	if b := getb16M(); b != nil {
		return internal.Bb2bs(b)
	}
	p := make([]byte, 16777216)
	return p
}

// GetBytesSlicePtr16M is like GetBytesSlice16M but returns a pointer to the slice instead.
// GetBytesSlicePtr16M is somewhat faster than GetBytesSlice16M, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr16M the original pointer returned by GetBytesSlicePtr16M to recycle the slice.
func GetBytesSlicePtr16M() *[]byte {
	if p := get16M(); p != nil {
		return p
	}
	if b := getb16M(); b != nil {
		p := internal.Bb2bs(b)
		return internal.Gets(p)
	}
	p := make([]byte, 16777216)
	return &p
}

// GetBufioReader16M returns a bufio.Reader with an internal buffer size of at least 16777216.
func GetBufioReader16M(pr io.Reader) *bufio.Reader {
	if r := getr16M(); r != nil {
		r.Reset(pr)
		return r
	}
	return bufio.NewReaderSize(pr, 16777216)
}

// GetBufioWriter16M returns a bufio.Writer with an internal buffer size of at least 16777216.
func GetBufioWriter16M(pw io.Writer) *bufio.Writer {
	if w := getw16M(); w != nil {
		w.Reset(pw)
		return w
	}
	return bufio.NewWriterSize(pw, 16777216)
}

// PutBytesBuffer16M recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
// PutBytesBuffer16M is optimized for bytes.Buffer of capacity [16777216, 33554432) but will accepts other
// sizes as well.
func PutBytesBuffer16M(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	if l := b.Cap(); l < 16777216 || l >= 33554432 {
		return PutBytesBuffer(b)
	}
	b.Reset()
	putb16M(b)
	return true
}

// PutBytesSlice16M recycles the passed byte slice. If the byte slice can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is returned unmodified, otherwise the byte slice is
// recycled and true is returned. In the latter case, the caller should never use again the passed byte slice.
// PutBytesSlice16M is optimized for byte slice of capacity [16777216, 33554432) but will accepts other
// sizes as well.
// PutBytesSlice16M, contrary to PutBytesSlicePtr16M, will perform a pointer-sized allocation for each call.
func PutBytesSlice16M(p []byte) bool {
	if l := cap(p); l < 16777216 || l >= 33554432 {
		return PutBytesSlice(p)
	}
	p = p[0:16777216]
	put16M(internal.Gets(p))
	return true
}

// PutBytesSlicePtr16M is like PutBytesSlice16M, but it accepts a pointer to the byte slice and does not perform
// a pointer-sized allocation for each call.
func PutBytesSlicePtr16M(p *[]byte) bool {
	if p == nil {
		return false
	}
	if l := cap(*p); l < 16777216 || l >= 33554432 {
		return PutBytesSlicePtr(p)
	}
	*p = (*p)[0:16777216]
	put16M(p)
	return true
}

// PutBufioReader16M recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader16M is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader16M callers should
// not use the bufio.Reader anymore and drop all references to it.
// PutBufioReader16M is optimized for bufio.Reader with Size() in the range (16777216, 33554432], but it accepts
// also other sizes.
func PutBufioReader16M(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	if l := r.Size(); l < 16777216 || l >= 33554432 {
		return PutBufioReader(r)
	}
	r.Reset(nil) // to not keep the parent reader alive
	putr16M(r)
	return true
}

// PutBufioWriter16M recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter16M is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter16M callers should
// not use the bufio.Writer anymore and drop all references to it.
// PutBufioWriter16M is optimized for bufio.Writer with Size() in the range (16777216, 33554432], but it accepts
// also other sizes.
func PutBufioWriter16M(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	if l := w.Size(); l < 16777216 || l >= 33554432 {
		return PutBufioWriter(w)
	}
	w.Reset(nil) // to not keep the parent writer alive
	putw16M(w)
	return true
}

// BufferPool16M is a httputil.BufferPool that provides byte slices of 16M bytes.
type BufferPool16M struct {
	httputil.BufferPool
}

// Get implements httputil.BufferPool.Get
func (_ BufferPool16M) Get() []byte {
	return GetBytesSlice16M()
}

// Put implements httputil.BufferPool.Put
func (_ BufferPool16M) Put(b []byte) {
	PutBytesSlice16M(b)
}

// BufferPtrPool16M is like BufferPool16M, but using pointer to byte slices instead (to avoid allocations during Put).
// For this reason it is not compatible with httputil.BufferPool.
type BufferPtrPool16M struct{}

// Get gets a byte slice from the pool. See GetBytesSlicePtr16M for details.
func (_ BufferPtrPool16M) Get() *[]byte {
	return GetBytesSlicePtr16M()
}

// Put inserts a byte slice in the pool. See PutBytesSlicePtr16M for details.
func (_ BufferPtrPool16M) Put(b *[]byte) {
	PutBytesSlicePtr16M(b)
}

// GetBytesBuffer returns a bytes.Buffer with at least size bytes of capacity.
// If your code uses buffers of static size, it is more performant to call one of the GetBytesBufferXxx functions instead.
// Calling GetBytesBuffer with a negative size panics.
func GetBytesBuffer(size int) *bytes.Buffer {
	switch {

	case size > 0 && size <= 256:
		return GetBytesBuffer256()

	case size > 256 && size <= 512:
		return GetBytesBuffer512()

	case size > 512 && size <= 1024:
		return GetBytesBuffer1K()

	case size > 1024 && size <= 2048:
		return GetBytesBuffer2K()

	case size > 2048 && size <= 4096:
		return GetBytesBuffer4K()

	case size > 4096 && size <= 8192:
		return GetBytesBuffer8K()

	case size > 8192 && size <= 16384:
		return GetBytesBuffer16K()

	case size > 16384 && size <= 32768:
		return GetBytesBuffer32K()

	case size > 32768 && size <= 65536:
		return GetBytesBuffer64K()

	case size > 65536 && size <= 131072:
		return GetBytesBuffer128K()

	case size > 131072 && size <= 262144:
		return GetBytesBuffer256K()

	case size > 262144 && size <= 524288:
		return GetBytesBuffer512K()

	case size > 524288 && size <= 1048576:
		return GetBytesBuffer1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesBuffer2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesBuffer4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesBuffer8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesBuffer16M()

	default:
		return bytes.NewBuffer(make([]byte, size))
	}
}

// GetBytesSlice returns a byte slice with at least size bytes of capacity and length size.
// If your code uses buffers of static size, it is more performant to call one of the GetBytesSliceXxx functions instead.
// GetBytesSlice is somewhat slower than GetBytesSlicePtr, but it is significantly easier to use.
// Calling GetBytesSlice with a negative size panics.
func GetBytesSlice(size int) []byte {
	switch {

	case size > 0 && size <= 256:
		return GetBytesSlice256()

	case size > 256 && size <= 512:
		return GetBytesSlice512()

	case size > 512 && size <= 1024:
		return GetBytesSlice1K()

	case size > 1024 && size <= 2048:
		return GetBytesSlice2K()

	case size > 2048 && size <= 4096:
		return GetBytesSlice4K()

	case size > 4096 && size <= 8192:
		return GetBytesSlice8K()

	case size > 8192 && size <= 16384:
		return GetBytesSlice16K()

	case size > 16384 && size <= 32768:
		return GetBytesSlice32K()

	case size > 32768 && size <= 65536:
		return GetBytesSlice64K()

	case size > 65536 && size <= 131072:
		return GetBytesSlice128K()

	case size > 131072 && size <= 262144:
		return GetBytesSlice256K()

	case size > 262144 && size <= 524288:
		return GetBytesSlice512K()

	case size > 524288 && size <= 1048576:
		return GetBytesSlice1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesSlice2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesSlice4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesSlice8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesSlice16M()

	default:
		return make([]byte, size)
	}
}

// GetBytesSlicePtr is like GetBytesSlice but returns a pointer to the byte slice.
// GetBytesSlicePtr is somewhat faster than GetBytesSlice, but it is significantly more complicated to use, as you need to
// provide to PutBytesSlicePtr the original pointer returned by GetBytesSlicePtr to recycle the slice.
func GetBytesSlicePtr(size int) *[]byte {
	switch {

	case size > 0 && size <= 256:
		return GetBytesSlicePtr256()

	case size > 256 && size <= 512:
		return GetBytesSlicePtr512()

	case size > 512 && size <= 1024:
		return GetBytesSlicePtr1K()

	case size > 1024 && size <= 2048:
		return GetBytesSlicePtr2K()

	case size > 2048 && size <= 4096:
		return GetBytesSlicePtr4K()

	case size > 4096 && size <= 8192:
		return GetBytesSlicePtr8K()

	case size > 8192 && size <= 16384:
		return GetBytesSlicePtr16K()

	case size > 16384 && size <= 32768:
		return GetBytesSlicePtr32K()

	case size > 32768 && size <= 65536:
		return GetBytesSlicePtr64K()

	case size > 65536 && size <= 131072:
		return GetBytesSlicePtr128K()

	case size > 131072 && size <= 262144:
		return GetBytesSlicePtr256K()

	case size > 262144 && size <= 524288:
		return GetBytesSlicePtr512K()

	case size > 524288 && size <= 1048576:
		return GetBytesSlicePtr1M()

	case size > 1048576 && size <= 2097152:
		return GetBytesSlicePtr2M()

	case size > 2097152 && size <= 4194304:
		return GetBytesSlicePtr4M()

	case size > 4194304 && size <= 8388608:
		return GetBytesSlicePtr8M()

	case size > 8388608 && size <= 16777216:
		return GetBytesSlicePtr16M()

	default:
		p := make([]byte, size)
		return &p
	}
}

// GetBufferPool returns a httputil.BufferPool that returns byte slices of capacity
// greater or equal than size, and of size size.
func GetBufferPool(size int) httputil.BufferPool {
	bp := internal.BufferPool{Sz: size}
	switch {

	case size > 0 && size <= 256:
		bp.P = BufferPool256{}

	case size > 256 && size <= 512:
		bp.P = BufferPool512{}

	case size > 512 && size <= 1024:
		bp.P = BufferPool1K{}

	case size > 1024 && size <= 2048:
		bp.P = BufferPool2K{}

	case size > 2048 && size <= 4096:
		bp.P = BufferPool4K{}

	case size > 4096 && size <= 8192:
		bp.P = BufferPool8K{}

	case size > 8192 && size <= 16384:
		bp.P = BufferPool16K{}

	case size > 16384 && size <= 32768:
		bp.P = BufferPool32K{}

	case size > 32768 && size <= 65536:
		bp.P = BufferPool64K{}

	case size > 65536 && size <= 131072:
		bp.P = BufferPool128K{}

	case size > 131072 && size <= 262144:
		bp.P = BufferPool256K{}

	case size > 262144 && size <= 524288:
		bp.P = BufferPool512K{}

	case size > 524288 && size <= 1048576:
		bp.P = BufferPool1M{}

	case size > 1048576 && size <= 2097152:
		bp.P = BufferPool2M{}

	case size > 2097152 && size <= 4194304:
		bp.P = BufferPool4M{}

	case size > 4194304 && size <= 8388608:
		bp.P = BufferPool8M{}

	case size > 8388608 && size <= 16777216:
		bp.P = BufferPool16M{}

	default:
		return &internal.SingleSizeBufferPool{Sz: size}
	}
	return bp
}

// GetBufioReader returns a bufio.Reader of at least the specified size.
func GetBufioReader(pr io.Reader, size int) *bufio.Reader {
	switch {

	case size > 0 && size <= 256:
		return GetBufioReader256(pr)

	case size > 256 && size <= 512:
		return GetBufioReader512(pr)

	case size > 512 && size <= 1024:
		return GetBufioReader1K(pr)

	case size > 1024 && size <= 2048:
		return GetBufioReader2K(pr)

	case size > 2048 && size <= 4096:
		return GetBufioReader4K(pr)

	case size > 4096 && size <= 8192:
		return GetBufioReader8K(pr)

	case size > 8192 && size <= 16384:
		return GetBufioReader16K(pr)

	case size > 16384 && size <= 32768:
		return GetBufioReader32K(pr)

	case size > 32768 && size <= 65536:
		return GetBufioReader64K(pr)

	case size > 65536 && size <= 131072:
		return GetBufioReader128K(pr)

	case size > 131072 && size <= 262144:
		return GetBufioReader256K(pr)

	case size > 262144 && size <= 524288:
		return GetBufioReader512K(pr)

	case size > 524288 && size <= 1048576:
		return GetBufioReader1M(pr)

	case size > 1048576 && size <= 2097152:
		return GetBufioReader2M(pr)

	case size > 2097152 && size <= 4194304:
		return GetBufioReader4M(pr)

	case size > 4194304 && size <= 8388608:
		return GetBufioReader8M(pr)

	case size > 8388608 && size <= 16777216:
		return GetBufioReader16M(pr)

	default:
		return bufio.NewReaderSize(pr, size)
	}
}

// GetBufioWriter returns a bufio.Writer of at least the specified size.
func GetBufioWriter(pw io.Writer, size int) *bufio.Writer {
	switch {

	case size > 0 && size <= 256:
		return GetBufioWriter256(pw)

	case size > 256 && size <= 512:
		return GetBufioWriter512(pw)

	case size > 512 && size <= 1024:
		return GetBufioWriter1K(pw)

	case size > 1024 && size <= 2048:
		return GetBufioWriter2K(pw)

	case size > 2048 && size <= 4096:
		return GetBufioWriter4K(pw)

	case size > 4096 && size <= 8192:
		return GetBufioWriter8K(pw)

	case size > 8192 && size <= 16384:
		return GetBufioWriter16K(pw)

	case size > 16384 && size <= 32768:
		return GetBufioWriter32K(pw)

	case size > 32768 && size <= 65536:
		return GetBufioWriter64K(pw)

	case size > 65536 && size <= 131072:
		return GetBufioWriter128K(pw)

	case size > 131072 && size <= 262144:
		return GetBufioWriter256K(pw)

	case size > 262144 && size <= 524288:
		return GetBufioWriter512K(pw)

	case size > 524288 && size <= 1048576:
		return GetBufioWriter1M(pw)

	case size > 1048576 && size <= 2097152:
		return GetBufioWriter2M(pw)

	case size > 2097152 && size <= 4194304:
		return GetBufioWriter4M(pw)

	case size > 4194304 && size <= 8388608:
		return GetBufioWriter8M(pw)

	case size > 8388608 && size <= 16777216:
		return GetBufioWriter16M(pw)

	default:
		return bufio.NewWriterSize(pw, size)
	}
}

// PutBytesBuffer recycles the passed bytes.Buffer. If the bytes.Buffer can not be recycled (e.g. because its capacity
// is too small or too big) false is returned and the bytes.Buffer is unmodified, otherwise the bytes.Buffer is
// recycled and true is returned. In the latter case, the caller should never use again the passed bytes.Buffer.
func PutBytesBuffer(b *bytes.Buffer) bool {
	if b == nil {
		return false
	}
	size := b.Cap()
	switch {

	case size >= 256 && size < 512:
		b.Reset()
		putb256(b)

	case size >= 512 && size < 1024:
		b.Reset()
		putb512(b)

	case size >= 1024 && size < 2048:
		b.Reset()
		putb1K(b)

	case size >= 2048 && size < 4096:
		b.Reset()
		putb2K(b)

	case size >= 4096 && size < 8192:
		b.Reset()
		putb4K(b)

	case size >= 8192 && size < 16384:
		b.Reset()
		putb8K(b)

	case size >= 16384 && size < 32768:
		b.Reset()
		putb16K(b)

	case size >= 32768 && size < 65536:
		b.Reset()
		putb32K(b)

	case size >= 65536 && size < 131072:
		b.Reset()
		putb64K(b)

	case size >= 131072 && size < 262144:
		b.Reset()
		putb128K(b)

	case size >= 262144 && size < 524288:
		b.Reset()
		putb256K(b)

	case size >= 524288 && size < 1048576:
		b.Reset()
		putb512K(b)

	case size >= 1048576 && size < 2097152:
		b.Reset()
		putb1M(b)

	case size >= 2097152 && size < 4194304:
		b.Reset()
		putb2M(b)

	case size >= 4194304 && size < 8388608:
		b.Reset()
		putb4M(b)

	case size >= 8388608 && size < 16777216:
		b.Reset()
		putb8M(b)

	case size >= 16777216 && size < 33554432:
		b.Reset()
		putb16M(b)

	default:
		return false
	}
	return true
}

func PutBytesSlice(b []byte) bool {
	size := cap(b)
	switch {

	case size >= 256 && size < 512:
		b = b[0:256]
		put256(internal.Gets(b))

	case size >= 512 && size < 1024:
		b = b[0:512]
		put512(internal.Gets(b))

	case size >= 1024 && size < 2048:
		b = b[0:1024]
		put1K(internal.Gets(b))

	case size >= 2048 && size < 4096:
		b = b[0:2048]
		put2K(internal.Gets(b))

	case size >= 4096 && size < 8192:
		b = b[0:4096]
		put4K(internal.Gets(b))

	case size >= 8192 && size < 16384:
		b = b[0:8192]
		put8K(internal.Gets(b))

	case size >= 16384 && size < 32768:
		b = b[0:16384]
		put16K(internal.Gets(b))

	case size >= 32768 && size < 65536:
		b = b[0:32768]
		put32K(internal.Gets(b))

	case size >= 65536 && size < 131072:
		b = b[0:65536]
		put64K(internal.Gets(b))

	case size >= 131072 && size < 262144:
		b = b[0:131072]
		put128K(internal.Gets(b))

	case size >= 262144 && size < 524288:
		b = b[0:262144]
		put256K(internal.Gets(b))

	case size >= 524288 && size < 1048576:
		b = b[0:524288]
		put512K(internal.Gets(b))

	case size >= 1048576 && size < 2097152:
		b = b[0:1048576]
		put1M(internal.Gets(b))

	case size >= 2097152 && size < 4194304:
		b = b[0:2097152]
		put2M(internal.Gets(b))

	case size >= 4194304 && size < 8388608:
		b = b[0:4194304]
		put4M(internal.Gets(b))

	case size >= 8388608 && size < 16777216:
		b = b[0:8388608]
		put8M(internal.Gets(b))

	case size >= 16777216 && size < 33554432:
		b = b[0:16777216]
		put16M(internal.Gets(b))

	default:
		return false
	}
	return true
}

func PutBytesSlicePtr(b *[]byte) bool {
	if b == nil {
		return false
	}
	size := cap(*b)
	switch {

	case size >= 256 && size < 512:
		*b = (*b)[0:256]
		put256(b)

	case size >= 512 && size < 1024:
		*b = (*b)[0:512]
		put512(b)

	case size >= 1024 && size < 2048:
		*b = (*b)[0:1024]
		put1K(b)

	case size >= 2048 && size < 4096:
		*b = (*b)[0:2048]
		put2K(b)

	case size >= 4096 && size < 8192:
		*b = (*b)[0:4096]
		put4K(b)

	case size >= 8192 && size < 16384:
		*b = (*b)[0:8192]
		put8K(b)

	case size >= 16384 && size < 32768:
		*b = (*b)[0:16384]
		put16K(b)

	case size >= 32768 && size < 65536:
		*b = (*b)[0:32768]
		put32K(b)

	case size >= 65536 && size < 131072:
		*b = (*b)[0:65536]
		put64K(b)

	case size >= 131072 && size < 262144:
		*b = (*b)[0:131072]
		put128K(b)

	case size >= 262144 && size < 524288:
		*b = (*b)[0:262144]
		put256K(b)

	case size >= 524288 && size < 1048576:
		*b = (*b)[0:524288]
		put512K(b)

	case size >= 1048576 && size < 2097152:
		*b = (*b)[0:1048576]
		put1M(b)

	case size >= 2097152 && size < 4194304:
		*b = (*b)[0:2097152]
		put2M(b)

	case size >= 4194304 && size < 8388608:
		*b = (*b)[0:4194304]
		put4M(b)

	case size >= 8388608 && size < 16777216:
		*b = (*b)[0:8388608]
		put8M(b)

	case size >= 16777216 && size < 33554432:
		*b = (*b)[0:16777216]
		put16M(b)

	default:
		return false
	}
	return true
}

// PutBufioReader recycles the passed bufio.Reader. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Reader.Reset() is called internally, so calling Reset before PutBufioReader is not required. If
// it is not recycled, the bufio.Reader is left untouched. After a succesfull call to PutBufioReader callers should
// not use the bufio.Reader anymore and drop all references to it.
// If you statically know the Size() of the bufio.Reader, it may be more performant to call PutBufioReaderXXX.
func PutBufioReader(r *bufio.Reader) bool {
	if r == nil {
		return false
	}
	size := r.Size()
	switch {

	case size >= 256 && size < 512:
		r.Reset(nil) // to not keep the parent reader alive
		putr256(r)

	case size >= 512 && size < 1024:
		r.Reset(nil) // to not keep the parent reader alive
		putr512(r)

	case size >= 1024 && size < 2048:
		r.Reset(nil) // to not keep the parent reader alive
		putr1K(r)

	case size >= 2048 && size < 4096:
		r.Reset(nil) // to not keep the parent reader alive
		putr2K(r)

	case size >= 4096 && size < 8192:
		r.Reset(nil) // to not keep the parent reader alive
		putr4K(r)

	case size >= 8192 && size < 16384:
		r.Reset(nil) // to not keep the parent reader alive
		putr8K(r)

	case size >= 16384 && size < 32768:
		r.Reset(nil) // to not keep the parent reader alive
		putr16K(r)

	case size >= 32768 && size < 65536:
		r.Reset(nil) // to not keep the parent reader alive
		putr32K(r)

	case size >= 65536 && size < 131072:
		r.Reset(nil) // to not keep the parent reader alive
		putr64K(r)

	case size >= 131072 && size < 262144:
		r.Reset(nil) // to not keep the parent reader alive
		putr128K(r)

	case size >= 262144 && size < 524288:
		r.Reset(nil) // to not keep the parent reader alive
		putr256K(r)

	case size >= 524288 && size < 1048576:
		r.Reset(nil) // to not keep the parent reader alive
		putr512K(r)

	case size >= 1048576 && size < 2097152:
		r.Reset(nil) // to not keep the parent reader alive
		putr1M(r)

	case size >= 2097152 && size < 4194304:
		r.Reset(nil) // to not keep the parent reader alive
		putr2M(r)

	case size >= 4194304 && size < 8388608:
		r.Reset(nil) // to not keep the parent reader alive
		putr4M(r)

	case size >= 8388608 && size < 16777216:
		r.Reset(nil) // to not keep the parent reader alive
		putr8M(r)

	case size >= 16777216 && size < 33554432:
		r.Reset(nil) // to not keep the parent reader alive
		putr16M(r)

	default:
		return false
	}
	return true
}

// PutBufioWriter recycles the passed bufio.Writer. It returns true if it's recycled, and false otherwise. If it's
// recycled, bufio.Writer.Reset() is called internally, so calling Reset before PutBufioWriter is not required. If
// it is not recycled, the bufio.Writer is left untouched. After a succesfull call to PutBufioWriter callers should
// not use the bufio.Writer anymore and drop all references to it.
// If you statically know the Size() of the bufio.Writer, it may be more performant to call PutBufioWriterXXX.
func PutBufioWriter(w *bufio.Writer) bool {
	if w == nil {
		return false
	}
	size := w.Size()
	switch {

	case size >= 256 && size < 512:
		w.Reset(nil) // to not keep the parent writer alive
		putw256(w)

	case size >= 512 && size < 1024:
		w.Reset(nil) // to not keep the parent writer alive
		putw512(w)

	case size >= 1024 && size < 2048:
		w.Reset(nil) // to not keep the parent writer alive
		putw1K(w)

	case size >= 2048 && size < 4096:
		w.Reset(nil) // to not keep the parent writer alive
		putw2K(w)

	case size >= 4096 && size < 8192:
		w.Reset(nil) // to not keep the parent writer alive
		putw4K(w)

	case size >= 8192 && size < 16384:
		w.Reset(nil) // to not keep the parent writer alive
		putw8K(w)

	case size >= 16384 && size < 32768:
		w.Reset(nil) // to not keep the parent writer alive
		putw16K(w)

	case size >= 32768 && size < 65536:
		w.Reset(nil) // to not keep the parent writer alive
		putw32K(w)

	case size >= 65536 && size < 131072:
		w.Reset(nil) // to not keep the parent writer alive
		putw64K(w)

	case size >= 131072 && size < 262144:
		w.Reset(nil) // to not keep the parent writer alive
		putw128K(w)

	case size >= 262144 && size < 524288:
		w.Reset(nil) // to not keep the parent writer alive
		putw256K(w)

	case size >= 524288 && size < 1048576:
		w.Reset(nil) // to not keep the parent writer alive
		putw512K(w)

	case size >= 1048576 && size < 2097152:
		w.Reset(nil) // to not keep the parent writer alive
		putw1M(w)

	case size >= 2097152 && size < 4194304:
		w.Reset(nil) // to not keep the parent writer alive
		putw2M(w)

	case size >= 4194304 && size < 8388608:
		w.Reset(nil) // to not keep the parent writer alive
		putw4M(w)

	case size >= 8388608 && size < 16777216:
		w.Reset(nil) // to not keep the parent writer alive
		putw8M(w)

	case size >= 16777216 && size < 33554432:
		w.Reset(nil) // to not keep the parent writer alive
		putw16M(w)

	default:
		return false
	}
	return true
}
