func (z *Writer) Write(p []byte) (int, error) {
	if z.checkError() != nil {
		return 0, z.err
	}
	if !z.wroteHeader {
		z.wroteHeader = true
		z.buf[0] = gzipID1
		z.buf[1] = gzipID2
		z.buf[2] = gzipDeflate
		z.buf[3] = 0
		if z.Extra != nil {
			z.buf[3] |= 0x04
		}
		if z.Name != "" {
			z.buf[3] |= 0x08
		}
		if z.Comment != "" {
			z.buf[3] |= 0x10
		}
		put4(z.buf[4:8], uint32(z.ModTime.Unix()))
		if z.level == BestCompression {
			z.buf[8] = 2
		} else if z.level == BestSpeed {
			z.buf[8] = 4
		} else {
			z.buf[8] = 0
		}
		z.buf[9] = z.OS
		var n int
		n, z.err = z.w.Write(z.buf[0:10])
		if z.err != nil {
			return n, z.err
		}
		if z.Extra != nil {
			z.err = z.writeBytes(z.Extra)
			if z.err != nil {
				return n, z.err
			}
		}
		if z.Name != "" {
			z.err = z.writeString(z.Name)
			if z.err != nil {
				return n, z.err
			}
		}
		if z.Comment != "" {
			z.err = z.writeString(z.Comment)
			if z.err != nil {
				return n, z.err
			}
		}
		go func() {
			listen := z.results
			for {
				r, ok := <-listen
				if !ok {
					return
				}
				buf := <-r.result
				n, err := z.w.Write(buf)
				if err != nil {
					z.pushError(err)
					close(r.notifyWritten)
					return
				}
				if n != len(buf) {
					z.pushError(fmt.Errorf("gzip: short write %d should be %d", n, len(buf)))
					close(r.notifyWritten)
					return
				}
				z.dstPool.Put(buf)
				close(r.notifyWritten)
			}
		}()
		z.currentBuffer = make([]byte, 0, z.blockSize+(z.blockSize/4))
	}
	if len(p) > z.blockSize*z.blocks {
		q := p
		for len(q) > 0 {
			length := len(q)
			if length > z.blockSize {
				length = z.blockSize
			}
			z.digest.Write(q[:length])
			z.currentBuffer = append(z.currentBuffer, q[:length]...)
			if len(z.currentBuffer) >= z.blockSize {
				z.compressCurrent(false)
				if z.err != nil {
					return len(p) - len(q) - length, z.err
				}
			}
			z.size += length
			q = q[length:]
		}
		return len(p), z.err
	} else {
		z.size += len(p)
		z.digest.Write(p)
		z.currentBuffer = append(z.currentBuffer, p...)
		if len(z.currentBuffer) >= z.blockSize {
			z.compressCurrent(false)
		}
		return len(p), z.err
	}
}
Write writes a compressed form of p to the underlying io.Writer. The
compressed bytes are not necessarily flushed to output until
the Writer is closed or Flush() is called.

The function will return quickly, if there are unused buffers.
The sent slice (p) is copied, and the caller is free to re-use the buffer
when the function returns.

Errors that occur during compression will be reported later, and a nil error
does not signify that the compression succeeded (since it is most likely still running)
That means that the call that returns an error may not be the call that caused it.
Only Flush and Close functions are guaranteed to return any errors up to that point.
package pgzip
import (
	"bytes"
	"errors"
	"fmt"
	"hash"
	"io"
	"sync"
	"github.com/klauspost/compress/flate"
	"github.com/klauspost/crc32"
)
const (
	defaultBlockSize = 250000
	tailSize         = 16384
	defaultBlocks    = 16
)
const (
	NoCompression       = flate.NoCompression
	BestSpeed           = flate.BestSpeed
	BestCompression     = flate.BestCompression
	DefaultCompression  = flate.DefaultCompression
	ConstantCompression = flate.ConstantCompression
)
type Writer struct {
	Header
	w             io.Writer
	level         int
	wroteHeader   bool
	blockSize     int
	blocks        int
	currentBuffer []byte
	prevTail      []byte
	digest        hash.Hash32
	size          int
	closed        bool
	buf           [10]byte
	err           error
	pushedErr     chan error
	results       chan result
	dictFlatePool *sync.Pool
	dstPool       *sync.Pool
}
type result struct {
	result        chan []byte
	notifyWritten chan struct{}
}
func (z *Writer) SetConcurrency(blockSize, blocks int) error {
	if blockSize <= tailSize {
		return fmt.Errorf("gzip: block size cannot be less than or equal to %d", tailSize)
	}
	if blocks <= 0 {
		return errors.New("gzip: blocks cannot be zero or less")
	}
	z.blockSize = blockSize
	z.results = make(chan result, blocks)
	z.blocks = blocks
	return nil
}
func NewWriter(w io.Writer) *Writer {
	z, _ := NewWriterLevel(w, DefaultCompression)
	return z
}
func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
	if level < ConstantCompression || level > BestCompression {
		return nil, fmt.Errorf("gzip: invalid compression level: %d", level)
	}
	z := new(Writer)
	z.SetConcurrency(defaultBlockSize, defaultBlocks)
	z.init(w, level)
	return z, nil
}
func (z *Writer) pushError(err error) {
	z.pushedErr <- err
	close(z.pushedErr)
}
func (z *Writer) init(w io.Writer, level int) {
	digest := z.digest
	if digest != nil {
		digest.Reset()
	} else {
		digest = crc32.NewIEEE()
	}
	*z = Writer{
		Header: Header{
			OS: 255,  
		},
		w:         w,
		level:     level,
		digest:    digest,
		pushedErr: make(chan error, 1),
		results:   make(chan result, z.blocks),
		blockSize: z.blockSize,
		blocks:    z.blocks,
	}
	z.dictFlatePool = &sync.Pool{
		New: func() interface{} {
			f, _ := flate.NewWriterDict(w, level, nil)
			return f
		},
	}
	z.dstPool = &sync.Pool{New: func() interface{} { return make([]byte, 0, z.blockSize) }}
}
func (z *Writer) Reset(w io.Writer) {
	if z.results != nil && !z.closed {
		close(z.results)
	}
	z.SetConcurrency(defaultBlockSize, defaultBlocks)
	z.init(w, z.level)
}
func put2(p []byte, v uint16) {
	p[0] = uint8(v >> 0)
	p[1] = uint8(v >> 8)
}
func put4(p []byte, v uint32) {
	p[0] = uint8(v >> 0)
	p[1] = uint8(v >> 8)
	p[2] = uint8(v >> 16)
	p[3] = uint8(v >> 24)
}
func (z *Writer) writeBytes(b []byte) error {
	if len(b) > 0xffff {
		return errors.New("gzip.Write: Extra data is too large")
	}
	put2(z.buf[0:2], uint16(len(b)))
	_, err := z.w.Write(z.buf[0:2])
	if err != nil {
		return err
	}
	_, err = z.w.Write(b)
	return err
}
func (z *Writer) writeString(s string) (err error) {
	needconv := false
	for _, v := range s {
		if v == 0 || v > 0xff {
			return errors.New("gzip.Write: non-Latin-1 header string")
		}
		if v > 0x7f {
			needconv = true
		}
	}
	if needconv {
		b := make([]byte, 0, len(s))
		for _, v := range s {
			b = append(b, byte(v))
		}
		_, err = z.w.Write(b)
	} else {
		_, err = io.WriteString(z.w, s)
	}
	if err != nil {
		return err
	}
	z.buf[0] = 0
	_, err = z.w.Write(z.buf[0:1])
	return err
}
func (z *Writer) compressCurrent(flush bool) {
	r := result{}
	r.result = make(chan []byte, 1)
	r.notifyWritten = make(chan struct{}, 0)
	z.results <- r
	c := z.currentBuffer
	if len(c) > z.blockSize*2 {
		c = c[:z.blockSize]
		go compressBlock(c, z.prevTail, *z, r)
		z.prevTail = c[len(c)-tailSize:]
		z.currentBuffer = z.currentBuffer[z.blockSize:]
		z.compressCurrent(flush)
		return
	}
	go compressBlock(c, z.prevTail, *z, r)
	if len(c) > tailSize {
		z.prevTail = c[len(c)-tailSize:]
	} else {
		z.prevTail = nil
	}
	z.currentBuffer = make([]byte, 0, z.blockSize+(z.blockSize/4))
	if flush {
		_ = <-r.notifyWritten
	}
}
func (z *Writer) checkError() error {
	if z.err != nil {
		return z.err
	}
	select {
	case err := <-z.pushedErr:
		z.err = err
	default:
	}
	return z.err
}