open-vault/vendor/github.com/dsnet/compress/internal/prefix/wrap.go
Calvin Leung Huang d2dbb8c963
Vault Debug (#7375)
* cli: initial work on debug; server-status target

* debug: add metrics capture target (#7376)

* check against DR secondary

* debug: add compression

* refactor check into preflight func

* debug: set short test time on tests, fix exit code bug

* debug: use temp dir for output on tests

* debug: use mholt/archiver for compression

* first pass on adding pprof

* use logger for output

* refactor polling target capture logic

* debug: poll and collect replication status

* debug: poll and collect host-info; rename output files and collection refactor

* fix comments

* add archive test; fix bugs found

* rename flag name to singular target

* add target output test; scaffold other tests cases

* debug/test: add pprof and index file tests

* debug/test: add min timing check tests

* debug: fix index gen race and collection goroutine race

* debug: extend archive tests, handle race between program exit and polling goroutines

* update docstring

* debug: correctly add to pollingWg

* debug: add config target support

* debug: don't wait on interrupt shutdown; add file exists unit tests

* move pprof bits into its goroutine

* debug: skip empty metrics and some pprof file creation if permission denied, add matching unit test

* address comments and feedback

* Vault debug using run.Group (#7658)

* debug: switch to use oklog/run.Group

* debug: use context to cancel requests and interrupt rungroups.

* debug: trigger the first interval properly

* debug: metrics collection should use metrics interval

* debug: add missing continue on metrics error

* debug: remove the use of buffered chan to trigger first interval

* debug: don't shadow BaseCommand's client, properly block on interval capture failures

* debug: actually use c.cachedClient everywhere

* go mod vendor

* debug: run all pprof in goroutines; bump pprof timings in tests to reduce flakiness

* debug: update help text
2019-10-15 15:39:19 -07:00

147 lines
2.8 KiB
Go

// Copyright 2015, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.
package prefix
import (
"bytes"
"io"
"strings"
)
// For some of the common Readers, we wrap and extend them to satisfy the
// compress.BufferedReader interface to improve performance.
type buffer struct {
*bytes.Buffer
}
type bytesReader struct {
*bytes.Reader
pos int64
buf []byte
arr [512]byte
}
type stringReader struct {
*strings.Reader
pos int64
buf []byte
arr [512]byte
}
func (r *buffer) Buffered() int {
return r.Len()
}
func (r *buffer) Peek(n int) ([]byte, error) {
b := r.Bytes()
if len(b) < n {
return b, io.EOF
}
return b[:n], nil
}
func (r *buffer) Discard(n int) (int, error) {
b := r.Next(n)
if len(b) < n {
return len(b), io.EOF
}
return n, nil
}
func (r *bytesReader) Buffered() int {
r.update()
if r.Len() > len(r.buf) {
return len(r.buf)
}
return r.Len()
}
func (r *bytesReader) Peek(n int) ([]byte, error) {
if n > len(r.arr) {
return nil, io.ErrShortBuffer
}
// Return sub-slice of local buffer if possible.
r.update()
if len(r.buf) >= n {
return r.buf[:n], nil
}
// Fill entire local buffer, and return appropriate sub-slice.
cnt, err := r.ReadAt(r.arr[:], r.pos)
r.buf = r.arr[:cnt]
if cnt < n {
return r.arr[:cnt], err
}
return r.arr[:n], nil
}
func (r *bytesReader) Discard(n int) (int, error) {
var err error
if n > r.Len() {
n, err = r.Len(), io.EOF
}
r.Seek(int64(n), io.SeekCurrent)
return n, err
}
// update reslices the internal buffer to be consistent with the read offset.
func (r *bytesReader) update() {
pos, _ := r.Seek(0, io.SeekCurrent)
if off := pos - r.pos; off >= 0 && off < int64(len(r.buf)) {
r.buf, r.pos = r.buf[off:], pos
} else {
r.buf, r.pos = nil, pos
}
}
func (r *stringReader) Buffered() int {
r.update()
if r.Len() > len(r.buf) {
return len(r.buf)
}
return r.Len()
}
func (r *stringReader) Peek(n int) ([]byte, error) {
if n > len(r.arr) {
return nil, io.ErrShortBuffer
}
// Return sub-slice of local buffer if possible.
r.update()
if len(r.buf) >= n {
return r.buf[:n], nil
}
// Fill entire local buffer, and return appropriate sub-slice.
cnt, err := r.ReadAt(r.arr[:], r.pos)
r.buf = r.arr[:cnt]
if cnt < n {
return r.arr[:cnt], err
}
return r.arr[:n], nil
}
func (r *stringReader) Discard(n int) (int, error) {
var err error
if n > r.Len() {
n, err = r.Len(), io.EOF
}
r.Seek(int64(n), io.SeekCurrent)
return n, err
}
// update reslices the internal buffer to be consistent with the read offset.
func (r *stringReader) update() {
pos, _ := r.Seek(0, io.SeekCurrent)
if off := pos - r.pos; off >= 0 && off < int64(len(r.buf)) {
r.buf, r.pos = r.buf[off:], pos
} else {
r.buf, r.pos = nil, pos
}
}