mirror of
https://github.com/mindoc-org/mindoc.git
synced 2026-02-27 17:03:57 +08:00
添加依赖库
This commit is contained in:
60
vendor/github.com/cznic/internal/buffer/Makefile
generated
vendored
Normal file
60
vendor/github.com/cznic/internal/buffer/Makefile
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# Copyright 2016 The Internal Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
.PHONY: all clean cover cpu editor internalError later mem nuke todo edit
|
||||
|
||||
grep=--include=*.go --include=*.l --include=*.y --include=*.yy
|
||||
ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go'
|
||||
|
||||
all: editor
|
||||
go vet 2>&1 | grep -v $(ngrep) || true
|
||||
go vet 2>&1 | grep -v $(ngrep) || true
|
||||
golint 2>&1 | grep -v $(ngrep) || true
|
||||
make todo
|
||||
unused . || true
|
||||
misspell *.go
|
||||
gosimple || true
|
||||
codesweep || true
|
||||
maligned || true
|
||||
unconvert -apply
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -f *~ *.test *.out
|
||||
|
||||
cover:
|
||||
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
||||
|
||||
cpu: clean
|
||||
go test -run @ -bench . -cpuprofile cpu.out
|
||||
go tool pprof -lines *.test cpu.out
|
||||
|
||||
edit:
|
||||
@ 1>/dev/null 2>/dev/null gvim -p Makefile log *.go
|
||||
|
||||
editor:
|
||||
gofmt -l -s -w *.go
|
||||
go test -i
|
||||
go test 2>&1 | tee log
|
||||
go install
|
||||
|
||||
internalError:
|
||||
egrep -ho '"internal error.*"' *.go | sort | cat -n
|
||||
|
||||
later:
|
||||
@grep -n $(grep) LATER * || true
|
||||
@grep -n $(grep) MAYBE * || true
|
||||
|
||||
mem: clean
|
||||
go test -run @ -bench . -memprofile mem.out -memprofilerate 1 -timeout 24h
|
||||
go tool pprof -lines -web -alloc_space *.test mem.out
|
||||
|
||||
nuke: clean
|
||||
go clean -i
|
||||
|
||||
todo:
|
||||
@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) TODO * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) BUG * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true
|
||||
146
vendor/github.com/cznic/internal/buffer/buffer.go
generated
vendored
Normal file
146
vendor/github.com/cznic/internal/buffer/buffer.go
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2016 The Internal Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package buffer implements a pool of pointers to byte slices.
|
||||
//
|
||||
// Example usage pattern
|
||||
//
|
||||
// p := buffer.Get(size)
|
||||
// b := *p // Now you can use b in any way you need.
|
||||
// ...
|
||||
// // When b will not be used anymore
|
||||
// buffer.Put(p)
|
||||
// ...
|
||||
// // If b or p are not going out of scope soon, optionally
|
||||
// b = nil
|
||||
// p = nil
|
||||
//
|
||||
// Otherwise the pool cannot release the buffer on garbage collection.
|
||||
//
|
||||
// Do not do
|
||||
//
|
||||
// p := buffer.Get(size)
|
||||
// b := *p
|
||||
// ...
|
||||
// buffer.Put(&b)
|
||||
//
|
||||
// or
|
||||
//
|
||||
// b := *buffer.Get(size)
|
||||
// ...
|
||||
// buffer.Put(&b)
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"github.com/cznic/internal/slice"
|
||||
"io"
|
||||
)
|
||||
|
||||
// CGet returns a pointer to a byte slice of len size. The pointed to byte
|
||||
// slice is zeroed up to its cap. CGet panics for size < 0.
|
||||
//
|
||||
// CGet is safe for concurrent use by multiple goroutines.
|
||||
func CGet(size int) *[]byte { return slice.Bytes.CGet(size).(*[]byte) }
|
||||
|
||||
// Get returns a pointer to a byte slice of len size. The pointed to byte slice
|
||||
// is not zeroed. Get panics for size < 0.
|
||||
//
|
||||
// Get is safe for concurrent use by multiple goroutines.
|
||||
func Get(size int) *[]byte { return slice.Bytes.Get(size).(*[]byte) }
|
||||
|
||||
// Put puts a pointer to a byte slice into a pool for possible later reuse by
|
||||
// CGet or Get.
|
||||
//
|
||||
// Put is safe for concurrent use by multiple goroutines.
|
||||
func Put(p *[]byte) { slice.Bytes.Put(p) }
|
||||
|
||||
// Bytes is similar to bytes.Buffer but may generate less garbage when properly
|
||||
// Closed. Zero value is ready to use.
|
||||
type Bytes struct {
|
||||
p *[]byte
|
||||
}
|
||||
|
||||
// Bytes return the content of b. The result is R/O.
|
||||
func (b *Bytes) Bytes() []byte {
|
||||
if b.p != nil {
|
||||
return *b.p
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close will recycle the underlying storage, if any. After Close, b is again
|
||||
// the zero value.
|
||||
func (b *Bytes) Close() error {
|
||||
if b.p != nil {
|
||||
Put(b.p)
|
||||
b.p = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Len returns the size of content in b.
|
||||
func (b *Bytes) Len() int {
|
||||
if b.p != nil {
|
||||
return len(*b.p)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Reset discard the content of Bytes while keeping the internal storage, if any.
|
||||
func (b *Bytes) Reset() {
|
||||
if b.p != nil {
|
||||
*b.p = (*b.p)[:0]
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes p into b and returns (len(p), nil).
|
||||
func (b *Bytes) Write(p []byte) (int, error) {
|
||||
n := b.Len()
|
||||
b.grow(n + len(p))
|
||||
copy((*b.p)[n:], p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// WriteByte writes p into b and returns nil.
|
||||
func (b *Bytes) WriteByte(p byte) error {
|
||||
n := b.Len()
|
||||
b.grow(n + 1)
|
||||
(*b.p)[n] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTo writes b's content to w and returns the number of bytes written to w
|
||||
// and an error, if any.
|
||||
func (b *Bytes) WriteTo(w io.Writer) (int64, error) {
|
||||
n, err := w.Write(b.Bytes())
|
||||
return int64(n), err
|
||||
}
|
||||
|
||||
// WriteString writes s to b and returns (len(s), nil).
|
||||
func (b *Bytes) WriteString(s string) (int, error) {
|
||||
n := b.Len()
|
||||
b.grow(n + len(s))
|
||||
copy((*b.p)[n:], s)
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
func (b *Bytes) grow(n int) {
|
||||
if b.p != nil {
|
||||
if n <= cap(*b.p) {
|
||||
*b.p = (*b.p)[:n]
|
||||
return
|
||||
}
|
||||
|
||||
np := Get(2 * n)
|
||||
*np = (*np)[:n]
|
||||
copy(*np, *b.p)
|
||||
Put(b.p)
|
||||
b.p = np
|
||||
return
|
||||
}
|
||||
|
||||
b.p = Get(n)
|
||||
}
|
||||
55
vendor/github.com/cznic/internal/file/Makefile
generated
vendored
Normal file
55
vendor/github.com/cznic/internal/file/Makefile
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# Copyright 2016 The Internal Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
.PHONY: all clean cover cpu editor internalError later mem nuke todo edit
|
||||
|
||||
grep=--include=*.go --include=*.l --include=*.y --include=*.yy
|
||||
ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go'
|
||||
|
||||
all: editor
|
||||
go vet 2>&1 | grep -v $(ngrep) || true
|
||||
golint 2>&1 | grep -v $(ngrep) || true
|
||||
make todo
|
||||
unused . || true
|
||||
misspell *.go
|
||||
gosimple || true
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -f *~ *.test *.out
|
||||
|
||||
cover:
|
||||
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
||||
|
||||
cpu: clean
|
||||
go test -run @ -bench . -cpuprofile cpu.out
|
||||
go tool pprof -lines *.test cpu.out
|
||||
|
||||
edit:
|
||||
@ 1>/dev/null 2>/dev/null gvim -p Makefile log *.go
|
||||
|
||||
editor:
|
||||
gofmt -l -s -w *.go
|
||||
go test 2>&1 | tee log
|
||||
go build
|
||||
|
||||
internalError:
|
||||
egrep -ho '"internal error.*"' *.go | sort | cat -n
|
||||
|
||||
later:
|
||||
@grep -n $(grep) LATER * || true
|
||||
@grep -n $(grep) MAYBE * || true
|
||||
|
||||
mem: clean
|
||||
go test -run @ -bench BenchmarkReadWrite -benchmem -memprofile mem.out -memprofilerate 1 -timeout 24h
|
||||
go tool pprof -lines -web -alloc_space *.test mem.out
|
||||
|
||||
nuke: clean
|
||||
go clean -i
|
||||
|
||||
todo:
|
||||
@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) TODO * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) BUG * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true
|
||||
434
vendor/github.com/cznic/internal/file/file.go
generated
vendored
Normal file
434
vendor/github.com/cznic/internal/file/file.go
generated
vendored
Normal file
@@ -0,0 +1,434 @@
|
||||
// Copyright 2016 The Internal Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package file provides an os.File-like interface of a memory mapped file.
|
||||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cznic/fileutil"
|
||||
"github.com/cznic/internal/buffer"
|
||||
"github.com/cznic/mathutil"
|
||||
"github.com/edsrzf/mmap-go"
|
||||
)
|
||||
|
||||
const copyBufSize = 1 << 20 // 1 MB.
|
||||
|
||||
var (
|
||||
_ Interface = (*mem)(nil)
|
||||
_ Interface = (*file)(nil)
|
||||
|
||||
_ os.FileInfo = stat{}
|
||||
|
||||
sysPage = os.Getpagesize()
|
||||
)
|
||||
|
||||
// Interface is a os.File-like entity.
|
||||
type Interface interface {
|
||||
io.ReaderAt
|
||||
io.ReaderFrom
|
||||
io.WriterAt
|
||||
io.WriterTo
|
||||
|
||||
Close() error
|
||||
Stat() (os.FileInfo, error)
|
||||
Sync() error
|
||||
Truncate(int64) error
|
||||
}
|
||||
|
||||
// Open returns a new Interface backed by f, or an error, if any.
|
||||
func Open(f *os.File) (Interface, error) { return newFile(f, 1<<30, 20) }
|
||||
|
||||
// OpenMem returns a new Interface, or an error, if any. The Interface content
|
||||
// is volatile, it's backed only by process' memory.
|
||||
func OpenMem(name string) (Interface, error) { return newMem(name, 18), nil }
|
||||
|
||||
type memMap map[int64]*[]byte
|
||||
|
||||
type mem struct {
|
||||
m memMap
|
||||
modTime time.Time
|
||||
name string
|
||||
pgBits uint
|
||||
pgMask int
|
||||
pgSize int
|
||||
size int64
|
||||
}
|
||||
|
||||
func newMem(name string, pgBits uint) *mem {
|
||||
pgSize := 1 << pgBits
|
||||
return &mem{
|
||||
m: memMap{},
|
||||
modTime: time.Now(),
|
||||
name: name,
|
||||
pgBits: pgBits,
|
||||
pgMask: pgSize - 1,
|
||||
pgSize: pgSize,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *mem) IsDir() bool { return false }
|
||||
func (f *mem) Mode() os.FileMode { return os.ModeTemporary + 0600 }
|
||||
func (f *mem) ModTime() time.Time { return f.modTime }
|
||||
func (f *mem) Name() string { return f.name }
|
||||
func (f *mem) ReadFrom(r io.Reader) (n int64, err error) { return readFrom(f, r) }
|
||||
func (f *mem) Size() (n int64) { return f.size }
|
||||
func (f *mem) Stat() (os.FileInfo, error) { return f, nil }
|
||||
func (f *mem) Sync() error { return nil }
|
||||
func (f *mem) Sys() interface{} { return nil }
|
||||
func (f *mem) WriteTo(w io.Writer) (n int64, err error) { return writeTo(f, w) }
|
||||
|
||||
func (f *mem) Close() error {
|
||||
f.Truncate(0)
|
||||
f.m = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *mem) ReadAt(b []byte, off int64) (n int, err error) {
|
||||
avail := f.size - off
|
||||
pi := off >> f.pgBits
|
||||
po := int(off) & f.pgMask
|
||||
rem := len(b)
|
||||
if int64(rem) >= avail {
|
||||
rem = int(avail)
|
||||
err = io.EOF
|
||||
}
|
||||
var zeroPage *[]byte
|
||||
for rem != 0 && avail > 0 {
|
||||
pg := f.m[pi]
|
||||
if pg == nil {
|
||||
if zeroPage == nil {
|
||||
zeroPage = buffer.CGet(f.pgSize)
|
||||
defer buffer.Put(zeroPage)
|
||||
}
|
||||
pg = zeroPage
|
||||
}
|
||||
nc := copy(b[:mathutil.Min(rem, f.pgSize)], (*pg)[po:])
|
||||
pi++
|
||||
po = 0
|
||||
rem -= nc
|
||||
n += nc
|
||||
b = b[nc:]
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (f *mem) Truncate(size int64) (err error) {
|
||||
if size < 0 {
|
||||
return fmt.Errorf("invalid truncate size: %d", size)
|
||||
}
|
||||
|
||||
first := size >> f.pgBits
|
||||
if size&int64(f.pgMask) != 0 {
|
||||
first++
|
||||
}
|
||||
last := f.size >> f.pgBits
|
||||
if f.size&int64(f.pgMask) != 0 {
|
||||
last++
|
||||
}
|
||||
for ; first <= last; first++ {
|
||||
if p := f.m[first]; p != nil {
|
||||
buffer.Put(p)
|
||||
}
|
||||
delete(f.m, first)
|
||||
}
|
||||
|
||||
f.size = size
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *mem) WriteAt(b []byte, off int64) (n int, err error) {
|
||||
pi := off >> f.pgBits
|
||||
po := int(off) & f.pgMask
|
||||
n = len(b)
|
||||
rem := n
|
||||
var nc int
|
||||
for rem != 0 {
|
||||
pg := f.m[pi]
|
||||
if pg == nil {
|
||||
pg = buffer.CGet(f.pgSize)
|
||||
f.m[pi] = pg
|
||||
}
|
||||
nc = copy((*pg)[po:], b)
|
||||
pi++
|
||||
po = 0
|
||||
rem -= nc
|
||||
b = b[nc:]
|
||||
}
|
||||
f.size = mathutil.MaxInt64(f.size, off+int64(n))
|
||||
return n, nil
|
||||
}
|
||||
|
||||
type stat struct {
|
||||
os.FileInfo
|
||||
size int64
|
||||
}
|
||||
|
||||
func (s stat) Size() int64 { return s.size }
|
||||
|
||||
type fileMap map[int64]mmap.MMap
|
||||
|
||||
type file struct {
|
||||
f *os.File
|
||||
m fileMap
|
||||
maxPages int
|
||||
pgBits uint
|
||||
pgMask int
|
||||
pgSize int
|
||||
size int64
|
||||
fsize int64
|
||||
}
|
||||
|
||||
func newFile(f *os.File, maxSize int64, pgBits uint) (*file, error) {
|
||||
if maxSize < 0 {
|
||||
panic("internal error")
|
||||
}
|
||||
|
||||
pgSize := 1 << pgBits
|
||||
switch {
|
||||
case sysPage > pgSize:
|
||||
pgBits = uint(mathutil.Log2Uint64(uint64(sysPage)))
|
||||
default:
|
||||
pgBits = uint(mathutil.Log2Uint64(uint64(pgSize / sysPage * sysPage)))
|
||||
}
|
||||
pgSize = 1 << pgBits
|
||||
fi := &file{
|
||||
f: f,
|
||||
m: fileMap{},
|
||||
maxPages: int(mathutil.MinInt64(
|
||||
1024,
|
||||
mathutil.MaxInt64(maxSize/int64(pgSize), 1)),
|
||||
),
|
||||
pgBits: pgBits,
|
||||
pgMask: pgSize - 1,
|
||||
pgSize: pgSize,
|
||||
}
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = fi.Truncate(info.Size()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fi, nil
|
||||
}
|
||||
|
||||
func (f *file) ReadFrom(r io.Reader) (n int64, err error) { return readFrom(f, r) }
|
||||
func (f *file) Sync() (err error) { return f.f.Sync() }
|
||||
func (f *file) WriteTo(w io.Writer) (n int64, err error) { return writeTo(f, w) }
|
||||
|
||||
func (f *file) Close() (err error) {
|
||||
for _, p := range f.m {
|
||||
if err = p.Unmap(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = f.f.Truncate(f.size); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = f.f.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = f.f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.m = nil
|
||||
f.f = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *file) page(index int64) (mmap.MMap, error) {
|
||||
if len(f.m) == f.maxPages {
|
||||
for i, p := range f.m {
|
||||
if err := p.Unmap(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delete(f.m, i)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
off := index << f.pgBits
|
||||
fsize := off + int64(f.pgSize)
|
||||
if fsize > f.fsize {
|
||||
if err := f.f.Truncate(fsize); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.fsize = fsize
|
||||
}
|
||||
p, err := mmap.MapRegion(f.f, f.pgSize, mmap.RDWR, 0, off)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.m[index] = p
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (f *file) ReadAt(b []byte, off int64) (n int, err error) {
|
||||
avail := f.size - off
|
||||
pi := off >> f.pgBits
|
||||
po := int(off) & f.pgMask
|
||||
rem := len(b)
|
||||
if int64(rem) >= avail {
|
||||
rem = int(avail)
|
||||
err = io.EOF
|
||||
}
|
||||
for rem != 0 && avail > 0 {
|
||||
pg := f.m[pi]
|
||||
if pg == nil {
|
||||
if pg, err = f.page(pi); err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
nc := copy(b[:mathutil.Min(rem, f.pgSize)], pg[po:])
|
||||
pi++
|
||||
po = 0
|
||||
rem -= nc
|
||||
n += nc
|
||||
b = b[nc:]
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (f *file) Stat() (os.FileInfo, error) {
|
||||
fi, err := f.f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stat{fi, f.size}, nil
|
||||
}
|
||||
|
||||
func (f *file) Truncate(size int64) (err error) {
|
||||
if size < 0 {
|
||||
return fmt.Errorf("invalid truncate size: %d", size)
|
||||
}
|
||||
|
||||
first := size >> f.pgBits
|
||||
if size&int64(f.pgMask) != 0 {
|
||||
first++
|
||||
}
|
||||
last := f.size >> f.pgBits
|
||||
if f.size&int64(f.pgMask) != 0 {
|
||||
last++
|
||||
}
|
||||
for ; first <= last; first++ {
|
||||
if p := f.m[first]; p != nil {
|
||||
if err := p.Unmap(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
delete(f.m, first)
|
||||
}
|
||||
|
||||
f.size = size
|
||||
fsize := (size + int64(f.pgSize) - 1) &^ int64(f.pgMask)
|
||||
if fsize != f.fsize {
|
||||
if err := f.f.Truncate(fsize); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
f.fsize = fsize
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *file) WriteAt(b []byte, off int64) (n int, err error) {
|
||||
pi := off >> f.pgBits
|
||||
po := int(off) & f.pgMask
|
||||
n = len(b)
|
||||
rem := n
|
||||
var nc int
|
||||
for rem != 0 {
|
||||
pg := f.m[pi]
|
||||
if pg == nil {
|
||||
pg, err = f.page(pi)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
nc = copy(pg[po:], b)
|
||||
pi++
|
||||
po = 0
|
||||
rem -= nc
|
||||
b = b[nc:]
|
||||
}
|
||||
f.size = mathutil.MaxInt64(f.size, off+int64(n))
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func readFrom(f Interface, r io.Reader) (n int64, err error) {
|
||||
f.Truncate(0)
|
||||
p := buffer.Get(copyBufSize)
|
||||
b := *p
|
||||
defer buffer.Put(p)
|
||||
|
||||
var off int64
|
||||
var werr error
|
||||
for {
|
||||
rn, rerr := r.Read(b)
|
||||
if rn != 0 {
|
||||
_, werr = f.WriteAt(b[:rn], off)
|
||||
n += int64(rn)
|
||||
off += int64(rn)
|
||||
}
|
||||
if rerr != nil {
|
||||
if !fileutil.IsEOF(rerr) {
|
||||
err = rerr
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if werr != nil {
|
||||
err = werr
|
||||
break
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func writeTo(f Interface, w io.Writer) (n int64, err error) {
|
||||
p := buffer.Get(copyBufSize)
|
||||
b := *p
|
||||
defer buffer.Put(p)
|
||||
|
||||
var off int64
|
||||
var werr error
|
||||
for {
|
||||
rn, rerr := f.ReadAt(b, off)
|
||||
if rn != 0 {
|
||||
_, werr = w.Write(b[:rn])
|
||||
n += int64(rn)
|
||||
off += int64(rn)
|
||||
}
|
||||
if rerr != nil {
|
||||
if !fileutil.IsEOF(rerr) {
|
||||
err = rerr
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if werr != nil {
|
||||
err = werr
|
||||
break
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
55
vendor/github.com/cznic/internal/slice/Makefile
generated
vendored
Normal file
55
vendor/github.com/cznic/internal/slice/Makefile
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# Copyright 2016 The Internal Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
.PHONY: all clean cover cpu editor internalError later mem nuke todo edit
|
||||
|
||||
grep=--include=*.go --include=*.l --include=*.y --include=*.yy
|
||||
ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go'
|
||||
|
||||
all: editor
|
||||
go vet 2>&1 | grep -v $(ngrep) || true
|
||||
golint 2>&1 | grep -v $(ngrep) || true
|
||||
make todo
|
||||
unused . || true
|
||||
misspell *.go
|
||||
gosimple || true
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -f *~ *.test *.out
|
||||
|
||||
cover:
|
||||
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
||||
|
||||
cpu: clean
|
||||
go test -run @ -bench . -cpuprofile cpu.out
|
||||
go tool pprof -lines *.test cpu.out
|
||||
|
||||
edit:
|
||||
@ 1>/dev/null 2>/dev/null gvim -p Makefile log *.go
|
||||
|
||||
editor:
|
||||
gofmt -l -s -w *.go
|
||||
go test 2>&1 | tee log
|
||||
go build
|
||||
|
||||
internalError:
|
||||
egrep -ho '"internal error.*"' *.go | sort | cat -n
|
||||
|
||||
later:
|
||||
@grep -n $(grep) LATER * || true
|
||||
@grep -n $(grep) MAYBE * || true
|
||||
|
||||
mem: clean
|
||||
go test -run @ -bench . -memprofile mem.out -memprofilerate 1 -timeout 24h
|
||||
go tool pprof -lines -web -alloc_space *.test mem.out
|
||||
|
||||
nuke: clean
|
||||
go clean -i
|
||||
|
||||
todo:
|
||||
@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) TODO * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) BUG * | grep -v $(ngrep) || true
|
||||
@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true
|
||||
173
vendor/github.com/cznic/internal/slice/pool.go
generated
vendored
Normal file
173
vendor/github.com/cznic/internal/slice/pool.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// Copyright 2016 The Internal Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package slice implements pools of pointers to slices.
|
||||
package slice
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/cznic/mathutil"
|
||||
)
|
||||
|
||||
var (
|
||||
// Bytes is a ready to use *[]byte Pool.
|
||||
Bytes *Pool
|
||||
// Ints is a ready to use *[]int Pool.
|
||||
Ints *Pool
|
||||
)
|
||||
|
||||
func init() {
|
||||
Bytes = newBytes()
|
||||
Ints = NewPool(
|
||||
func(size int) interface{} { // create
|
||||
b := make([]int, size)
|
||||
return &b
|
||||
},
|
||||
func(s interface{}) { // clear
|
||||
b := *s.(*[]int)
|
||||
b = b[:cap(b)]
|
||||
for i := range b {
|
||||
b[i] = 0
|
||||
}
|
||||
},
|
||||
func(s interface{}, size int) { // setSize
|
||||
p := s.(*[]int)
|
||||
*p = (*p)[:size]
|
||||
},
|
||||
func(s interface{}) int { return cap(*s.(*[]int)) }, // cap
|
||||
)
|
||||
}
|
||||
|
||||
func newBytes() *Pool {
|
||||
return NewPool(
|
||||
func(size int) interface{} { // create
|
||||
b := make([]byte, size)
|
||||
return &b
|
||||
},
|
||||
func(s interface{}) { // clear
|
||||
b := *s.(*[]byte)
|
||||
b = b[:cap(b)]
|
||||
for i := range b {
|
||||
b[i] = 0
|
||||
}
|
||||
},
|
||||
func(s interface{}, size int) { // setSize
|
||||
p := s.(*[]byte)
|
||||
*p = (*p)[:size]
|
||||
},
|
||||
func(s interface{}) int { return cap(*s.(*[]byte)) }, // cap
|
||||
)
|
||||
}
|
||||
|
||||
// Pool implements a pool of pointers to slices.
|
||||
//
|
||||
// Example usage pattern (assuming pool is, for example, a *[]byte Pool)
|
||||
//
|
||||
// p := pool.Get(size).(*[]byte)
|
||||
// b := *p // Now you can use b in any way you need.
|
||||
// ...
|
||||
// // When b will not be used anymore
|
||||
// pool.Put(p)
|
||||
// ...
|
||||
// // If b or p are not going out of scope soon, optionally
|
||||
// b = nil
|
||||
// p = nil
|
||||
//
|
||||
// Otherwise the pool cannot release the slice on garbage collection.
|
||||
//
|
||||
// Do not do
|
||||
//
|
||||
// p := pool.Get(size).(*[]byte)
|
||||
// b := *p
|
||||
// ...
|
||||
// pool.Put(&b)
|
||||
//
|
||||
// or
|
||||
//
|
||||
// b := *pool.Get(size).(*[]byte)
|
||||
// ...
|
||||
// pool.Put(&b)
|
||||
type Pool struct {
|
||||
cap func(interface{}) int
|
||||
clear func(interface{})
|
||||
m [63]sync.Pool
|
||||
null interface{}
|
||||
setSize func(interface{}, int)
|
||||
}
|
||||
|
||||
// NewPool returns a newly created Pool. Assuming the desired slice type is
|
||||
// []T:
|
||||
//
|
||||
// The create function returns a *[]T of len == cap == size.
|
||||
//
|
||||
// The argument of clear is *[]T and the function sets all the slice elements
|
||||
// to the respective zero value.
|
||||
//
|
||||
// The setSize function gets a *[]T and sets its len to size.
|
||||
//
|
||||
// The cap function gets a *[]T and returns its capacity.
|
||||
func NewPool(
|
||||
create func(size int) interface{},
|
||||
clear func(interface{}),
|
||||
setSize func(p interface{}, size int),
|
||||
cap func(p interface{}) int,
|
||||
) *Pool {
|
||||
p := &Pool{clear: clear, setSize: setSize, cap: cap, null: create(0)}
|
||||
for i := range p.m {
|
||||
size := 1 << uint(i)
|
||||
p.m[i] = sync.Pool{New: func() interface{} {
|
||||
// 0: 1 - 1
|
||||
// 1: 10 - 10
|
||||
// 2: 11 - 100
|
||||
// 3: 101 - 1000
|
||||
// 4: 1001 - 10000
|
||||
// 5: 10001 - 100000
|
||||
return create(size)
|
||||
}}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// CGet returns a *[]T of len size. The pointed to slice is zeroed up to its
|
||||
// cap. CGet panics for size < 0.
|
||||
//
|
||||
// CGet is safe for concurrent use by multiple goroutines.
|
||||
func (p *Pool) CGet(size int) interface{} {
|
||||
s := p.Get(size)
|
||||
p.clear(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Get returns a *[]T of len size. The pointed to slice is not zeroed. Get
|
||||
// panics for size < 0.
|
||||
//
|
||||
// Get is safe for concurrent use by multiple goroutines.
|
||||
func (p *Pool) Get(size int) interface{} {
|
||||
var index int
|
||||
switch {
|
||||
case size < 0:
|
||||
panic("Pool.Get: negative size")
|
||||
case size == 0:
|
||||
return p.null
|
||||
case size > 1:
|
||||
index = mathutil.Log2Uint64(uint64(size-1)) + 1
|
||||
}
|
||||
s := p.m[index].Get()
|
||||
p.setSize(s, size)
|
||||
return s
|
||||
}
|
||||
|
||||
// Put puts a *[]T into a pool for possible later reuse by CGet or Get. Put
|
||||
// panics is its argument is not of type *[]T.
|
||||
//
|
||||
// Put is safe for concurrent use by multiple goroutines.
|
||||
func (p *Pool) Put(b interface{}) {
|
||||
size := p.cap(b)
|
||||
if size == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
p.m[mathutil.Log2Uint64(uint64(size))].Put(b)
|
||||
}
|
||||
Reference in New Issue
Block a user