mirror of
https://github.com/astaxie/beego.git
synced 2025-07-01 08:40:19 +00:00
only add golang.org vendor
This commit is contained in:
20
vendor/github.com/siddontang/go/LICENSE
generated
vendored
20
vendor/github.com/siddontang/go/LICENSE
generated
vendored
@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 siddontang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
vendor/github.com/siddontang/go/filelock/LICENSE
generated
vendored
27
vendor/github.com/siddontang/go/filelock/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
17
vendor/github.com/siddontang/go/filelock/file_lock_generic.go
generated
vendored
17
vendor/github.com/siddontang/go/filelock/file_lock_generic.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
// Copyright 2012 The LevelDB-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
|
||||
|
||||
package filelock
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func Lock(name string) (io.Closer, error) {
|
||||
return nil, fmt.Errorf("leveldb/db: file locking is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
43
vendor/github.com/siddontang/go/filelock/file_lock_solaris.go
generated
vendored
43
vendor/github.com/siddontang/go/filelock/file_lock_solaris.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2014 The LevelDB-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build solaris
|
||||
|
||||
package filelock
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// lockCloser hides all of an os.File's methods, except for Close.
|
||||
type lockCloser struct {
|
||||
f *os.File
|
||||
}
|
||||
|
||||
func (l lockCloser) Close() error {
|
||||
return l.f.Close()
|
||||
}
|
||||
|
||||
func Lock(name string) (io.Closer, error) {
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spec := syscall.Flock_t{
|
||||
Type: syscall.F_WRLCK,
|
||||
Whence: int16(os.SEEK_SET),
|
||||
Start: 0,
|
||||
Len: 0, // 0 means to lock the entire file.
|
||||
Pid: int32(os.Getpid()),
|
||||
}
|
||||
if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &spec); err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return lockCloser{f}, nil
|
||||
}
|
51
vendor/github.com/siddontang/go/filelock/file_lock_unix.go
generated
vendored
51
vendor/github.com/siddontang/go/filelock/file_lock_unix.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
// Copyright 2014 The LevelDB-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||
|
||||
package filelock
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// lockCloser hides all of an os.File's methods, except for Close.
|
||||
type lockCloser struct {
|
||||
f *os.File
|
||||
}
|
||||
|
||||
func (l lockCloser) Close() error {
|
||||
return l.f.Close()
|
||||
}
|
||||
|
||||
func Lock(name string) (io.Closer, error) {
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/*
|
||||
Some people tell me FcntlFlock does not exist, so use flock here
|
||||
*/
|
||||
if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// spec := syscall.Flock_t{
|
||||
// Type: syscall.F_WRLCK,
|
||||
// Whence: int16(os.SEEK_SET),
|
||||
// Start: 0,
|
||||
// Len: 0, // 0 means to lock the entire file.
|
||||
// Pid: int32(os.Getpid()),
|
||||
// }
|
||||
// if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &spec); err != nil {
|
||||
// f.Close()
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return lockCloser{f}, nil
|
||||
}
|
36
vendor/github.com/siddontang/go/filelock/file_lock_windows.go
generated
vendored
36
vendor/github.com/siddontang/go/filelock/file_lock_windows.go
generated
vendored
@ -1,36 +0,0 @@
|
||||
// Copyright 2013 The LevelDB-Go 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 filelock
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// lockCloser hides all of an syscall.Handle's methods, except for Close.
|
||||
type lockCloser struct {
|
||||
fd syscall.Handle
|
||||
}
|
||||
|
||||
func (l lockCloser) Close() error {
|
||||
return syscall.Close(l.fd)
|
||||
}
|
||||
|
||||
func Lock(name string) (io.Closer, error) {
|
||||
p, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fd, err := syscall.CreateFile(p,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
||||
0, nil, syscall.CREATE_ALWAYS,
|
||||
syscall.FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lockCloser{fd: fd}, nil
|
||||
}
|
27
vendor/github.com/siddontang/go/hack/hack.go
generated
vendored
27
vendor/github.com/siddontang/go/hack/hack.go
generated
vendored
@ -1,27 +0,0 @@
|
||||
package hack
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// no copy to change slice to string
|
||||
// use your own risk
|
||||
func String(b []byte) (s string) {
|
||||
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
pstring.Data = pbytes.Data
|
||||
pstring.Len = pbytes.Len
|
||||
return
|
||||
}
|
||||
|
||||
// no copy to change string to slice
|
||||
// use your own risk
|
||||
func Slice(s string) (b []byte) {
|
||||
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
pbytes.Data = pstring.Data
|
||||
pbytes.Len = pstring.Len
|
||||
pbytes.Cap = pstring.Len
|
||||
return
|
||||
}
|
39
vendor/github.com/siddontang/go/ioutil2/ioutil.go
generated
vendored
39
vendor/github.com/siddontang/go/ioutil2/ioutil.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Copyright 2012, Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ioutil2
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// Write file to temp and atomically move when everything else succeeds.
|
||||
func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error {
|
||||
dir, name := path.Dir(filename), path.Base(filename)
|
||||
f, err := ioutil.TempFile(dir, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err := f.Write(data)
|
||||
f.Close()
|
||||
if err == nil && n < len(data) {
|
||||
err = io.ErrShortWrite
|
||||
} else {
|
||||
err = os.Chmod(f.Name(), perm)
|
||||
}
|
||||
if err != nil {
|
||||
os.Remove(f.Name())
|
||||
return err
|
||||
}
|
||||
return os.Rename(f.Name(), filename)
|
||||
}
|
||||
|
||||
// Check file exists or not
|
||||
func FileExists(name string) bool {
|
||||
_, err := os.Stat(name)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
69
vendor/github.com/siddontang/go/ioutil2/sectionwriter.go
generated
vendored
69
vendor/github.com/siddontang/go/ioutil2/sectionwriter.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
package ioutil2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var ErrExceedLimit = errors.New("write exceed limit")
|
||||
|
||||
func NewSectionWriter(w io.WriterAt, off int64, n int64) *SectionWriter {
|
||||
return &SectionWriter{w, off, off, off + n}
|
||||
}
|
||||
|
||||
type SectionWriter struct {
|
||||
w io.WriterAt
|
||||
base int64
|
||||
off int64
|
||||
limit int64
|
||||
}
|
||||
|
||||
func (s *SectionWriter) Write(p []byte) (n int, err error) {
|
||||
if s.off >= s.limit {
|
||||
return 0, ErrExceedLimit
|
||||
}
|
||||
|
||||
if max := s.limit - s.off; int64(len(p)) > max {
|
||||
return 0, ErrExceedLimit
|
||||
}
|
||||
|
||||
n, err = s.w.WriteAt(p, s.off)
|
||||
s.off += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
var errWhence = errors.New("Seek: invalid whence")
|
||||
var errOffset = errors.New("Seek: invalid offset")
|
||||
|
||||
func (s *SectionWriter) Seek(offset int64, whence int) (int64, error) {
|
||||
switch whence {
|
||||
default:
|
||||
return 0, errWhence
|
||||
case 0:
|
||||
offset += s.base
|
||||
case 1:
|
||||
offset += s.off
|
||||
case 2:
|
||||
offset += s.limit
|
||||
}
|
||||
if offset < s.base {
|
||||
return 0, errOffset
|
||||
}
|
||||
s.off = offset
|
||||
return offset - s.base, nil
|
||||
}
|
||||
|
||||
func (s *SectionWriter) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
if off < 0 || off >= s.limit-s.base {
|
||||
return 0, errOffset
|
||||
}
|
||||
off += s.base
|
||||
if max := s.limit - off; int64(len(p)) > max {
|
||||
return 0, ErrExceedLimit
|
||||
}
|
||||
|
||||
return s.w.WriteAt(p, off)
|
||||
}
|
||||
|
||||
// Size returns the size of the section in bytes.
|
||||
func (s *SectionWriter) Size() int64 { return s.limit - s.base }
|
21
vendor/github.com/siddontang/go/log/doc.go
generated
vendored
21
vendor/github.com/siddontang/go/log/doc.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
// log package supplies more advanced features than go orign log package.
|
||||
//
|
||||
// It supports log different level: trace, debug, info, warn, error, fatal.
|
||||
//
|
||||
// It also supports different log handlers which you can log to stdout, file, socket, etc...
|
||||
//
|
||||
// Use
|
||||
//
|
||||
// import "github.com/siddontang/go/log"
|
||||
//
|
||||
// //log with different level
|
||||
// log.Info("hello world")
|
||||
// log.Error("hello world")
|
||||
//
|
||||
// //create a logger with specified handler
|
||||
// h := NewStreamHandler(os.Stdout)
|
||||
// l := log.NewDefault(h)
|
||||
// l.Info("hello world")
|
||||
// l.Infof("%s %d", "hello", 123)
|
||||
//
|
||||
package log
|
200
vendor/github.com/siddontang/go/log/filehandler.go
generated
vendored
200
vendor/github.com/siddontang/go/log/filehandler.go
generated
vendored
@ -1,200 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
//FileHandler writes log to a file.
|
||||
type FileHandler struct {
|
||||
fd *os.File
|
||||
}
|
||||
|
||||
func NewFileHandler(fileName string, flag int) (*FileHandler, error) {
|
||||
dir := path.Dir(fileName)
|
||||
os.Mkdir(dir, 0777)
|
||||
|
||||
f, err := os.OpenFile(fileName, flag, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h := new(FileHandler)
|
||||
|
||||
h.fd = f
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *FileHandler) Write(b []byte) (n int, err error) {
|
||||
return h.fd.Write(b)
|
||||
}
|
||||
|
||||
func (h *FileHandler) Close() error {
|
||||
return h.fd.Close()
|
||||
}
|
||||
|
||||
//RotatingFileHandler writes log a file, if file size exceeds maxBytes,
|
||||
//it will backup current file and open a new one.
|
||||
//
|
||||
//max backup file number is set by backupCount, it will delete oldest if backups too many.
|
||||
type RotatingFileHandler struct {
|
||||
fd *os.File
|
||||
|
||||
fileName string
|
||||
maxBytes int
|
||||
backupCount int
|
||||
}
|
||||
|
||||
func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
|
||||
dir := path.Dir(fileName)
|
||||
os.Mkdir(dir, 0777)
|
||||
|
||||
h := new(RotatingFileHandler)
|
||||
|
||||
if maxBytes <= 0 {
|
||||
return nil, fmt.Errorf("invalid max bytes")
|
||||
}
|
||||
|
||||
h.fileName = fileName
|
||||
h.maxBytes = maxBytes
|
||||
h.backupCount = backupCount
|
||||
|
||||
var err error
|
||||
h.fd, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *RotatingFileHandler) Write(p []byte) (n int, err error) {
|
||||
h.doRollover()
|
||||
return h.fd.Write(p)
|
||||
}
|
||||
|
||||
func (h *RotatingFileHandler) Close() error {
|
||||
if h.fd != nil {
|
||||
return h.fd.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *RotatingFileHandler) doRollover() {
|
||||
f, err := h.fd.Stat()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if h.maxBytes <= 0 {
|
||||
return
|
||||
} else if f.Size() < int64(h.maxBytes) {
|
||||
return
|
||||
}
|
||||
|
||||
if h.backupCount > 0 {
|
||||
h.fd.Close()
|
||||
|
||||
for i := h.backupCount - 1; i > 0; i-- {
|
||||
sfn := fmt.Sprintf("%s.%d", h.fileName, i)
|
||||
dfn := fmt.Sprintf("%s.%d", h.fileName, i+1)
|
||||
|
||||
os.Rename(sfn, dfn)
|
||||
}
|
||||
|
||||
dfn := fmt.Sprintf("%s.1", h.fileName)
|
||||
os.Rename(h.fileName, dfn)
|
||||
|
||||
h.fd, _ = os.OpenFile(h.fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
}
|
||||
}
|
||||
|
||||
//TimeRotatingFileHandler writes log to a file,
|
||||
//it will backup current and open a new one, with a period time you sepecified.
|
||||
//
|
||||
//refer: http://docs.python.org/2/library/logging.handlers.html.
|
||||
//same like python TimedRotatingFileHandler.
|
||||
type TimeRotatingFileHandler struct {
|
||||
fd *os.File
|
||||
|
||||
baseName string
|
||||
interval int64
|
||||
suffix string
|
||||
rolloverAt int64
|
||||
}
|
||||
|
||||
const (
|
||||
WhenSecond = iota
|
||||
WhenMinute
|
||||
WhenHour
|
||||
WhenDay
|
||||
)
|
||||
|
||||
func NewTimeRotatingFileHandler(baseName string, when int8, interval int) (*TimeRotatingFileHandler, error) {
|
||||
dir := path.Dir(baseName)
|
||||
os.Mkdir(dir, 0777)
|
||||
|
||||
h := new(TimeRotatingFileHandler)
|
||||
|
||||
h.baseName = baseName
|
||||
|
||||
switch when {
|
||||
case WhenSecond:
|
||||
h.interval = 1
|
||||
h.suffix = "2006-01-02_15-04-05"
|
||||
case WhenMinute:
|
||||
h.interval = 60
|
||||
h.suffix = "2006-01-02_15-04"
|
||||
case WhenHour:
|
||||
h.interval = 3600
|
||||
h.suffix = "2006-01-02_15"
|
||||
case WhenDay:
|
||||
h.interval = 3600 * 24
|
||||
h.suffix = "2006-01-02"
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid when_rotate: %d", when)
|
||||
}
|
||||
|
||||
h.interval = h.interval * int64(interval)
|
||||
|
||||
var err error
|
||||
h.fd, err = os.OpenFile(h.baseName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fInfo, _ := h.fd.Stat()
|
||||
h.rolloverAt = fInfo.ModTime().Unix() + h.interval
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *TimeRotatingFileHandler) doRollover() {
|
||||
//refer http://hg.python.org/cpython/file/2.7/Lib/logging/handlers.py
|
||||
now := time.Now()
|
||||
|
||||
if h.rolloverAt <= now.Unix() {
|
||||
fName := h.baseName + now.Format(h.suffix)
|
||||
h.fd.Close()
|
||||
e := os.Rename(h.baseName, fName)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
h.fd, _ = os.OpenFile(h.baseName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
|
||||
h.rolloverAt = time.Now().Unix() + h.interval
|
||||
}
|
||||
}
|
||||
|
||||
func (h *TimeRotatingFileHandler) Write(b []byte) (n int, err error) {
|
||||
h.doRollover()
|
||||
return h.fd.Write(b)
|
||||
}
|
||||
|
||||
func (h *TimeRotatingFileHandler) Close() error {
|
||||
return h.fd.Close()
|
||||
}
|
48
vendor/github.com/siddontang/go/log/handler.go
generated
vendored
48
vendor/github.com/siddontang/go/log/handler.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
//Handler writes logs to somewhere
|
||||
type Handler interface {
|
||||
Write(p []byte) (n int, err error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
//StreamHandler writes logs to a specified io Writer, maybe stdout, stderr, etc...
|
||||
type StreamHandler struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func NewStreamHandler(w io.Writer) (*StreamHandler, error) {
|
||||
h := new(StreamHandler)
|
||||
|
||||
h.w = w
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *StreamHandler) Write(b []byte) (n int, err error) {
|
||||
return h.w.Write(b)
|
||||
}
|
||||
|
||||
func (h *StreamHandler) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//NullHandler does nothing, it discards anything.
|
||||
type NullHandler struct {
|
||||
}
|
||||
|
||||
func NewNullHandler() (*NullHandler, error) {
|
||||
return new(NullHandler), nil
|
||||
}
|
||||
|
||||
func (h *NullHandler) Write(b []byte) (n int, err error) {
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (h *NullHandler) Close() {
|
||||
|
||||
}
|
366
vendor/github.com/siddontang/go/log/log.go
generated
vendored
366
vendor/github.com/siddontang/go/log/log.go
generated
vendored
@ -1,366 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
//log level, from low to high, more high means more serious
|
||||
const (
|
||||
LevelTrace = iota
|
||||
LevelDebug
|
||||
LevelInfo
|
||||
LevelWarn
|
||||
LevelError
|
||||
LevelFatal
|
||||
)
|
||||
|
||||
const (
|
||||
Ltime = 1 << iota //time format "2006/01/02 15:04:05"
|
||||
Lfile //file.go:123
|
||||
Llevel //[Trace|Debug|Info...]
|
||||
)
|
||||
|
||||
var LevelName [6]string = [6]string{"Trace", "Debug", "Info", "Warn", "Error", "Fatal"}
|
||||
|
||||
const TimeFormat = "2006/01/02 15:04:05"
|
||||
|
||||
const maxBufPoolSize = 16
|
||||
|
||||
type atomicInt32 int32
|
||||
|
||||
func (i *atomicInt32) Set(n int) {
|
||||
atomic.StoreInt32((*int32)(i), int32(n))
|
||||
}
|
||||
|
||||
func (i *atomicInt32) Get() int {
|
||||
return int(atomic.LoadInt32((*int32)(i)))
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
level atomicInt32
|
||||
flag int
|
||||
|
||||
hMutex sync.Mutex
|
||||
handler Handler
|
||||
|
||||
quit chan struct{}
|
||||
msg chan []byte
|
||||
|
||||
bufMutex sync.Mutex
|
||||
bufs [][]byte
|
||||
|
||||
wg sync.WaitGroup
|
||||
|
||||
closed atomicInt32
|
||||
}
|
||||
|
||||
//new a logger with specified handler and flag
|
||||
func New(handler Handler, flag int) *Logger {
|
||||
var l = new(Logger)
|
||||
|
||||
l.level.Set(LevelInfo)
|
||||
l.handler = handler
|
||||
|
||||
l.flag = flag
|
||||
|
||||
l.quit = make(chan struct{})
|
||||
l.closed.Set(0)
|
||||
|
||||
l.msg = make(chan []byte, 1024)
|
||||
|
||||
l.bufs = make([][]byte, 0, 16)
|
||||
|
||||
l.wg.Add(1)
|
||||
go l.run()
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
//new a default logger with specified handler and flag: Ltime|Lfile|Llevel
|
||||
func NewDefault(handler Handler) *Logger {
|
||||
return New(handler, Ltime|Lfile|Llevel)
|
||||
}
|
||||
|
||||
func newStdHandler() *StreamHandler {
|
||||
h, _ := NewStreamHandler(os.Stdout)
|
||||
return h
|
||||
}
|
||||
|
||||
var std = NewDefault(newStdHandler())
|
||||
|
||||
func (l *Logger) run() {
|
||||
defer l.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case msg := <-l.msg:
|
||||
l.hMutex.Lock()
|
||||
l.handler.Write(msg)
|
||||
l.hMutex.Unlock()
|
||||
l.putBuf(msg)
|
||||
case <-l.quit:
|
||||
//we must log all msg
|
||||
if len(l.msg) == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) popBuf() []byte {
|
||||
l.bufMutex.Lock()
|
||||
var buf []byte
|
||||
if len(l.bufs) == 0 {
|
||||
buf = make([]byte, 0, 1024)
|
||||
} else {
|
||||
buf = l.bufs[len(l.bufs)-1]
|
||||
l.bufs = l.bufs[0 : len(l.bufs)-1]
|
||||
}
|
||||
l.bufMutex.Unlock()
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
func (l *Logger) putBuf(buf []byte) {
|
||||
l.bufMutex.Lock()
|
||||
if len(l.bufs) < maxBufPoolSize {
|
||||
buf = buf[0:0]
|
||||
l.bufs = append(l.bufs, buf)
|
||||
}
|
||||
l.bufMutex.Unlock()
|
||||
}
|
||||
|
||||
func (l *Logger) Close() {
|
||||
if l.closed.Get() == 1 {
|
||||
return
|
||||
}
|
||||
l.closed.Set(1)
|
||||
|
||||
close(l.quit)
|
||||
|
||||
l.wg.Wait()
|
||||
|
||||
l.quit = nil
|
||||
|
||||
l.handler.Close()
|
||||
}
|
||||
|
||||
//set log level, any log level less than it will not log
|
||||
func (l *Logger) SetLevel(level int) {
|
||||
l.level.Set(level)
|
||||
}
|
||||
|
||||
// name can be in ["trace", "debug", "info", "warn", "error", "fatal"]
|
||||
func (l *Logger) SetLevelByName(name string) {
|
||||
name = strings.ToLower(name)
|
||||
switch name {
|
||||
case "trace":
|
||||
l.SetLevel(LevelTrace)
|
||||
case "debug":
|
||||
l.SetLevel(LevelDebug)
|
||||
case "info":
|
||||
l.SetLevel(LevelInfo)
|
||||
case "warn":
|
||||
l.SetLevel(LevelWarn)
|
||||
case "error":
|
||||
l.SetLevel(LevelError)
|
||||
case "fatal":
|
||||
l.SetLevel(LevelFatal)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) SetHandler(h Handler) {
|
||||
if l.closed.Get() == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
l.hMutex.Lock()
|
||||
if l.handler != nil {
|
||||
l.handler.Close()
|
||||
}
|
||||
l.handler = h
|
||||
l.hMutex.Unlock()
|
||||
}
|
||||
|
||||
func (l *Logger) Output(callDepth int, level int, s string) {
|
||||
if l.closed.Get() == 1 {
|
||||
// closed
|
||||
return
|
||||
}
|
||||
|
||||
if l.level.Get() > level {
|
||||
// higher level can be logged
|
||||
return
|
||||
}
|
||||
|
||||
buf := l.popBuf()
|
||||
|
||||
if l.flag&Ltime > 0 {
|
||||
now := time.Now().Format(TimeFormat)
|
||||
buf = append(buf, '[')
|
||||
buf = append(buf, now...)
|
||||
buf = append(buf, "] "...)
|
||||
}
|
||||
|
||||
if l.flag&Lfile > 0 {
|
||||
_, file, line, ok := runtime.Caller(callDepth)
|
||||
if !ok {
|
||||
file = "???"
|
||||
line = 0
|
||||
} else {
|
||||
for i := len(file) - 1; i > 0; i-- {
|
||||
if file[i] == '/' {
|
||||
file = file[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf = append(buf, file...)
|
||||
buf = append(buf, ':')
|
||||
|
||||
buf = strconv.AppendInt(buf, int64(line), 10)
|
||||
buf = append(buf, ' ')
|
||||
}
|
||||
|
||||
if l.flag&Llevel > 0 {
|
||||
buf = append(buf, '[')
|
||||
buf = append(buf, LevelName[level]...)
|
||||
buf = append(buf, "] "...)
|
||||
}
|
||||
|
||||
buf = append(buf, s...)
|
||||
|
||||
if s[len(s)-1] != '\n' {
|
||||
buf = append(buf, '\n')
|
||||
}
|
||||
|
||||
l.msg <- buf
|
||||
}
|
||||
|
||||
//log with Trace level
|
||||
func (l *Logger) Trace(v ...interface{}) {
|
||||
l.Output(2, LevelTrace, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with Debug level
|
||||
func (l *Logger) Debug(v ...interface{}) {
|
||||
l.Output(2, LevelDebug, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with info level
|
||||
func (l *Logger) Info(v ...interface{}) {
|
||||
l.Output(2, LevelInfo, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with warn level
|
||||
func (l *Logger) Warn(v ...interface{}) {
|
||||
l.Output(2, LevelWarn, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with error level
|
||||
func (l *Logger) Error(v ...interface{}) {
|
||||
l.Output(2, LevelError, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with fatal level
|
||||
func (l *Logger) Fatal(v ...interface{}) {
|
||||
l.Output(2, LevelFatal, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
//log with Trace level
|
||||
func (l *Logger) Tracef(format string, v ...interface{}) {
|
||||
l.Output(2, LevelTrace, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
//log with Debug level
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
l.Output(2, LevelDebug, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
//log with info level
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
l.Output(2, LevelInfo, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
//log with warn level
|
||||
func (l *Logger) Warnf(format string, v ...interface{}) {
|
||||
l.Output(2, LevelWarn, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
//log with error level
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
l.Output(2, LevelError, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
//log with fatal level
|
||||
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
||||
l.Output(2, LevelFatal, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func SetLevel(level int) {
|
||||
std.SetLevel(level)
|
||||
}
|
||||
|
||||
// name can be in ["trace", "debug", "info", "warn", "error", "fatal"]
|
||||
func SetLevelByName(name string) {
|
||||
std.SetLevelByName(name)
|
||||
}
|
||||
|
||||
func SetHandler(h Handler) {
|
||||
std.SetHandler(h)
|
||||
}
|
||||
|
||||
func Trace(v ...interface{}) {
|
||||
std.Output(2, LevelTrace, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Debug(v ...interface{}) {
|
||||
std.Output(2, LevelDebug, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Info(v ...interface{}) {
|
||||
std.Output(2, LevelInfo, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Warn(v ...interface{}) {
|
||||
std.Output(2, LevelWarn, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Error(v ...interface{}) {
|
||||
std.Output(2, LevelError, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Fatal(v ...interface{}) {
|
||||
std.Output(2, LevelFatal, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func Tracef(format string, v ...interface{}) {
|
||||
std.Output(2, LevelTrace, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
std.Output(2, LevelDebug, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Infof(format string, v ...interface{}) {
|
||||
std.Output(2, LevelInfo, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
std.Output(2, LevelWarn, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
std.Output(2, LevelError, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Fatalf(format string, v ...interface{}) {
|
||||
std.Output(2, LevelFatal, fmt.Sprintf(format, v...))
|
||||
}
|
65
vendor/github.com/siddontang/go/log/sockethandler.go
generated
vendored
65
vendor/github.com/siddontang/go/log/sockethandler.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
//SocketHandler writes log to a connectionl.
|
||||
//Network protocol is simple: log length + log | log length + log. log length is uint32, bigendian.
|
||||
//you must implement your own log server, maybe you can use logd instead simply.
|
||||
type SocketHandler struct {
|
||||
c net.Conn
|
||||
protocol string
|
||||
addr string
|
||||
}
|
||||
|
||||
func NewSocketHandler(protocol string, addr string) (*SocketHandler, error) {
|
||||
s := new(SocketHandler)
|
||||
|
||||
s.protocol = protocol
|
||||
s.addr = addr
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (h *SocketHandler) Write(p []byte) (n int, err error) {
|
||||
if err = h.connect(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, len(p)+4)
|
||||
|
||||
binary.BigEndian.PutUint32(buf, uint32(len(p)))
|
||||
|
||||
copy(buf[4:], p)
|
||||
|
||||
n, err = h.c.Write(buf)
|
||||
if err != nil {
|
||||
h.c.Close()
|
||||
h.c = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (h *SocketHandler) Close() error {
|
||||
if h.c != nil {
|
||||
h.c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *SocketHandler) connect() error {
|
||||
if h.c != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
h.c, err = net.DialTimeout(h.protocol, h.addr, 20*time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
67
vendor/github.com/siddontang/go/num/bytes.go
generated
vendored
67
vendor/github.com/siddontang/go/num/bytes.go
generated
vendored
@ -1,67 +0,0 @@
|
||||
package num
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
//all are bigendian format
|
||||
|
||||
func BytesToUint16(b []byte) uint16 {
|
||||
return binary.BigEndian.Uint16(b)
|
||||
}
|
||||
|
||||
func Uint16ToBytes(u uint16) []byte {
|
||||
buf := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(buf, u)
|
||||
return buf
|
||||
}
|
||||
|
||||
func BytesToUint32(b []byte) uint32 {
|
||||
return binary.BigEndian.Uint32(b)
|
||||
}
|
||||
|
||||
func Uint32ToBytes(u uint32) []byte {
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, u)
|
||||
return buf
|
||||
}
|
||||
|
||||
func BytesToUint64(b []byte) uint64 {
|
||||
return binary.BigEndian.Uint64(b)
|
||||
}
|
||||
|
||||
func Uint64ToBytes(u uint64) []byte {
|
||||
buf := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(buf, u)
|
||||
return buf
|
||||
}
|
||||
|
||||
func BytesToInt16(b []byte) int16 {
|
||||
return int16(binary.BigEndian.Uint16(b))
|
||||
}
|
||||
|
||||
func Int16ToBytes(u int16) []byte {
|
||||
buf := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(buf, uint16(u))
|
||||
return buf
|
||||
}
|
||||
|
||||
func BytesToInt32(b []byte) int32 {
|
||||
return int32(binary.BigEndian.Uint32(b))
|
||||
}
|
||||
|
||||
func Int32ToBytes(u int32) []byte {
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, uint32(u))
|
||||
return buf
|
||||
}
|
||||
|
||||
func BytesToInt64(b []byte) int64 {
|
||||
return int64(binary.BigEndian.Uint64(b))
|
||||
}
|
||||
|
||||
func Int64ToBytes(u int64) []byte {
|
||||
buf := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(buf, uint64(u))
|
||||
return buf
|
||||
}
|
161
vendor/github.com/siddontang/go/num/cmp.go
generated
vendored
161
vendor/github.com/siddontang/go/num/cmp.go
generated
vendored
@ -1,161 +0,0 @@
|
||||
package num
|
||||
|
||||
func MinUint(a uint, b uint) uint {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxUint(a uint, b uint) uint {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinInt(a int, b int) int {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxInt(a int, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinUint8(a uint8, b uint8) uint8 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxUint8(a uint8, b uint8) uint8 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinInt8(a int8, b int8) int8 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxInt8(a int8, b int8) int8 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinUint16(a uint16, b uint16) uint16 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxUint16(a uint16, b uint16) uint16 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinInt16(a int16, b int16) int16 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxInt16(a int16, b int16) int16 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinUint32(a uint32, b uint32) uint32 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxUint32(a uint32, b uint32) uint32 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinInt32(a int32, b int32) int32 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxInt32(a int32, b int32) int32 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinUint64(a uint64, b uint64) uint64 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxUint64(a uint64, b uint64) uint64 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func MinInt64(a int64, b int64) int64 {
|
||||
if a > b {
|
||||
return b
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func MaxInt64(a int64, b int64) int64 {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
157
vendor/github.com/siddontang/go/num/str.go
generated
vendored
157
vendor/github.com/siddontang/go/num/str.go
generated
vendored
@ -1,157 +0,0 @@
|
||||
package num
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ParseUint(s string) (uint, error) {
|
||||
if v, err := strconv.ParseUint(s, 10, 0); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return uint(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseUint8(s string) (uint8, error) {
|
||||
if v, err := strconv.ParseUint(s, 10, 8); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return uint8(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseUint16(s string) (uint16, error) {
|
||||
if v, err := strconv.ParseUint(s, 10, 16); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return uint16(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseUint32(s string) (uint32, error) {
|
||||
if v, err := strconv.ParseUint(s, 10, 32); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return uint32(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseUint64(s string) (uint64, error) {
|
||||
return strconv.ParseUint(s, 10, 64)
|
||||
}
|
||||
|
||||
func ParseInt(s string) (int, error) {
|
||||
if v, err := strconv.ParseInt(s, 10, 0); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return int(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseInt8(s string) (int8, error) {
|
||||
if v, err := strconv.ParseInt(s, 10, 8); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return int8(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseInt16(s string) (int16, error) {
|
||||
if v, err := strconv.ParseInt(s, 10, 16); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return int16(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseInt32(s string) (int32, error) {
|
||||
if v, err := strconv.ParseInt(s, 10, 32); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return int32(v), nil
|
||||
}
|
||||
}
|
||||
|
||||
func ParseInt64(s string) (int64, error) {
|
||||
return strconv.ParseInt(s, 10, 64)
|
||||
}
|
||||
|
||||
func FormatInt(v int) string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt8(v int8) string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt16(v int16) string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt32(v int32) string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt64(v int64) string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint(v uint) string {
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint8(v uint8) string {
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint16(v uint16) string {
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint32(v uint32) string {
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint64(v uint64) string {
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatIntToSlice(v int) []byte {
|
||||
return strconv.AppendInt(nil, int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt8ToSlice(v int8) []byte {
|
||||
return strconv.AppendInt(nil, int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt16ToSlice(v int16) []byte {
|
||||
return strconv.AppendInt(nil, int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt32ToSlice(v int32) []byte {
|
||||
return strconv.AppendInt(nil, int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatInt64ToSlice(v int64) []byte {
|
||||
return strconv.AppendInt(nil, int64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUintToSlice(v uint) []byte {
|
||||
return strconv.AppendUint(nil, uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint8ToSlice(v uint8) []byte {
|
||||
return strconv.AppendUint(nil, uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint16ToSlice(v uint16) []byte {
|
||||
return strconv.AppendUint(nil, uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint32ToSlice(v uint32) []byte {
|
||||
return strconv.AppendUint(nil, uint64(v), 10)
|
||||
}
|
||||
|
||||
func FormatUint64ToSlice(v uint64) []byte {
|
||||
return strconv.AppendUint(nil, uint64(v), 10)
|
||||
}
|
27
vendor/github.com/siddontang/go/snappy/LICENSE
generated
vendored
27
vendor/github.com/siddontang/go/snappy/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
124
vendor/github.com/siddontang/go/snappy/decode.go
generated
vendored
124
vendor/github.com/siddontang/go/snappy/decode.go
generated
vendored
@ -1,124 +0,0 @@
|
||||
// Copyright 2011 The Snappy-Go 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 snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrCorrupt reports that the input is invalid.
|
||||
var ErrCorrupt = errors.New("snappy: corrupt input")
|
||||
|
||||
// DecodedLen returns the length of the decoded block.
|
||||
func DecodedLen(src []byte) (int, error) {
|
||||
v, _, err := decodedLen(src)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// decodedLen returns the length of the decoded block and the number of bytes
|
||||
// that the length header occupied.
|
||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
||||
v, n := binary.Uvarint(src)
|
||||
if n == 0 {
|
||||
return 0, 0, ErrCorrupt
|
||||
}
|
||||
if uint64(int(v)) != v {
|
||||
return 0, 0, errors.New("snappy: decoded block is too large")
|
||||
}
|
||||
return int(v), n, nil
|
||||
}
|
||||
|
||||
// Decode returns the decoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire decoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Decode(dst, src []byte) ([]byte, error) {
|
||||
dLen, s, err := decodedLen(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) < dLen {
|
||||
dst = make([]byte, dLen)
|
||||
}
|
||||
|
||||
var d, offset, length int
|
||||
for s < len(src) {
|
||||
switch src[s] & 0x03 {
|
||||
case tagLiteral:
|
||||
x := uint(src[s] >> 2)
|
||||
switch {
|
||||
case x < 60:
|
||||
s += 1
|
||||
case x == 60:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-1])
|
||||
case x == 61:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-2]) | uint(src[s-1])<<8
|
||||
case x == 62:
|
||||
s += 4
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16
|
||||
case x == 63:
|
||||
s += 5
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24
|
||||
}
|
||||
length = int(x + 1)
|
||||
if length <= 0 {
|
||||
return nil, errors.New("snappy: unsupported literal length")
|
||||
}
|
||||
if length > len(dst)-d || length > len(src)-s {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
copy(dst[d:], src[s:s+length])
|
||||
d += length
|
||||
s += length
|
||||
continue
|
||||
|
||||
case tagCopy1:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 4 + int(src[s-2])>>2&0x7
|
||||
offset = int(src[s-2])&0xe0<<3 | int(src[s-1])
|
||||
|
||||
case tagCopy2:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 1 + int(src[s-3])>>2
|
||||
offset = int(src[s-2]) | int(src[s-1])<<8
|
||||
|
||||
case tagCopy4:
|
||||
return nil, errors.New("snappy: unsupported COPY_4 tag")
|
||||
}
|
||||
|
||||
end := d + length
|
||||
if offset > d || end > len(dst) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
for ; d < end; d++ {
|
||||
dst[d] = dst[d-offset]
|
||||
}
|
||||
}
|
||||
if d != dLen {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
174
vendor/github.com/siddontang/go/snappy/encode.go
generated
vendored
174
vendor/github.com/siddontang/go/snappy/encode.go
generated
vendored
@ -1,174 +0,0 @@
|
||||
// Copyright 2011 The Snappy-Go 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 snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// We limit how far copy back-references can go, the same as the C++ code.
|
||||
const maxOffset = 1 << 15
|
||||
|
||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
||||
func emitLiteral(dst, lit []byte) int {
|
||||
i, n := 0, uint(len(lit)-1)
|
||||
switch {
|
||||
case n < 60:
|
||||
dst[0] = uint8(n)<<2 | tagLiteral
|
||||
i = 1
|
||||
case n < 1<<8:
|
||||
dst[0] = 60<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
i = 2
|
||||
case n < 1<<16:
|
||||
dst[0] = 61<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
i = 3
|
||||
case n < 1<<24:
|
||||
dst[0] = 62<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
i = 4
|
||||
case int64(n) < 1<<32:
|
||||
dst[0] = 63<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
dst[4] = uint8(n >> 24)
|
||||
i = 5
|
||||
default:
|
||||
panic("snappy: source buffer is too long")
|
||||
}
|
||||
if copy(dst[i:], lit) != len(lit) {
|
||||
panic("snappy: destination buffer is too short")
|
||||
}
|
||||
return i + len(lit)
|
||||
}
|
||||
|
||||
// emitCopy writes a copy chunk and returns the number of bytes written.
|
||||
func emitCopy(dst []byte, offset, length int) int {
|
||||
i := 0
|
||||
for length > 0 {
|
||||
x := length - 4
|
||||
if 0 <= x && x < 1<<3 && offset < 1<<11 {
|
||||
dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1
|
||||
dst[i+1] = uint8(offset)
|
||||
i += 2
|
||||
break
|
||||
}
|
||||
|
||||
x = length
|
||||
if x > 1<<6 {
|
||||
x = 1 << 6
|
||||
}
|
||||
dst[i+0] = uint8(x-1)<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
i += 3
|
||||
length -= x
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire encoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Encode(dst, src []byte) ([]byte, error) {
|
||||
if n := MaxEncodedLen(len(src)); len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
||||
// The block starts with the varint-encoded length of the decompressed bytes.
|
||||
d := binary.PutUvarint(dst, uint64(len(src)))
|
||||
|
||||
// Return early if src is short.
|
||||
if len(src) <= 4 {
|
||||
if len(src) != 0 {
|
||||
d += emitLiteral(dst[d:], src)
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
||||
const maxTableSize = 1 << 14
|
||||
shift, tableSize := uint(32-8), 1<<8
|
||||
for tableSize < maxTableSize && tableSize < len(src) {
|
||||
shift--
|
||||
tableSize *= 2
|
||||
}
|
||||
var table [maxTableSize]int
|
||||
|
||||
// Iterate over the source bytes.
|
||||
var (
|
||||
s int // The iterator position.
|
||||
t int // The last position with the same hash as s.
|
||||
lit int // The start position of any pending literal bytes.
|
||||
)
|
||||
for s+3 < len(src) {
|
||||
// Update the hash table.
|
||||
b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3]
|
||||
h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24
|
||||
p := &table[(h*0x1e35a7bd)>>shift]
|
||||
// We need to to store values in [-1, inf) in table. To save
|
||||
// some initialization time, (re)use the table's zero value
|
||||
// and shift the values against this zero: add 1 on writes,
|
||||
// subtract 1 on reads.
|
||||
t, *p = *p-1, s+1
|
||||
// If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte.
|
||||
if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] {
|
||||
s++
|
||||
continue
|
||||
}
|
||||
// Otherwise, we have a match. First, emit any pending literal bytes.
|
||||
if lit != s {
|
||||
d += emitLiteral(dst[d:], src[lit:s])
|
||||
}
|
||||
// Extend the match to be as long as possible.
|
||||
s0 := s
|
||||
s, t = s+4, t+4
|
||||
for s < len(src) && src[s] == src[t] {
|
||||
s++
|
||||
t++
|
||||
}
|
||||
// Emit the copied bytes.
|
||||
d += emitCopy(dst[d:], s-t, s-s0)
|
||||
lit = s
|
||||
}
|
||||
|
||||
// Emit any final pending literal bytes and return.
|
||||
if lit != len(src) {
|
||||
d += emitLiteral(dst[d:], src[lit:])
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
||||
// uncompressed length.
|
||||
func MaxEncodedLen(srcLen int) int {
|
||||
// Compressed data can be defined as:
|
||||
// compressed := item* literal*
|
||||
// item := literal* copy
|
||||
//
|
||||
// The trailing literal sequence has a space blowup of at most 62/60
|
||||
// since a literal of length 60 needs one tag byte + one extra byte
|
||||
// for length information.
|
||||
//
|
||||
// Item blowup is trickier to measure. Suppose the "copy" op copies
|
||||
// 4 bytes of data. Because of a special check in the encoding code,
|
||||
// we produce a 4-byte copy only if the offset is < 65536. Therefore
|
||||
// the copy op takes 3 bytes to encode, and this type of item leads
|
||||
// to at most the 62/60 blowup for representing literals.
|
||||
//
|
||||
// Suppose the "copy" op copies 5 bytes of data. If the offset is big
|
||||
// enough, it will take 5 bytes to encode the copy op. Therefore the
|
||||
// worst case here is a one-byte literal followed by a five-byte copy.
|
||||
// That is, 6 bytes of input turn into 7 bytes of "compressed" data.
|
||||
//
|
||||
// This last factor dominates the blowup, so the final estimate is:
|
||||
return 32 + srcLen + srcLen/6
|
||||
}
|
38
vendor/github.com/siddontang/go/snappy/snappy.go
generated
vendored
38
vendor/github.com/siddontang/go/snappy/snappy.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
// Copyright 2011 The Snappy-Go 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 snappy implements the snappy block-based compression format.
|
||||
// It aims for very high speeds and reasonable compression.
|
||||
//
|
||||
// The C++ snappy implementation is at http://code.google.com/p/snappy/
|
||||
package snappy
|
||||
|
||||
/*
|
||||
Each encoded block begins with the varint-encoded length of the decoded data,
|
||||
followed by a sequence of chunks. Chunks begin and end on byte boundaries. The
|
||||
first byte of each chunk is broken into its 2 least and 6 most significant bits
|
||||
called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.
|
||||
Zero means a literal tag. All other values mean a copy tag.
|
||||
|
||||
For literal tags:
|
||||
- If m < 60, the next 1 + m bytes are literal bytes.
|
||||
- Otherwise, let n be the little-endian unsigned integer denoted by the next
|
||||
m - 59 bytes. The next 1 + n bytes after that are literal bytes.
|
||||
|
||||
For copy tags, length bytes are copied from offset bytes ago, in the style of
|
||||
Lempel-Ziv compression algorithms. In particular:
|
||||
- For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).
|
||||
The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10
|
||||
of the offset. The next byte is bits 0-7 of the offset.
|
||||
- For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).
|
||||
The length is 1 + m. The offset is the little-endian unsigned integer
|
||||
denoted by the next 2 bytes.
|
||||
- For l == 3, this tag is a legacy format that is no longer supported.
|
||||
*/
|
||||
const (
|
||||
tagLiteral = 0x00
|
||||
tagCopy1 = 0x01
|
||||
tagCopy2 = 0x02
|
||||
tagCopy4 = 0x03
|
||||
)
|
146
vendor/github.com/siddontang/go/sync2/atomic.go
generated
vendored
146
vendor/github.com/siddontang/go/sync2/atomic.go
generated
vendored
@ -1,146 +0,0 @@
|
||||
// Copyright 2013, Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sync2
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AtomicInt32 int32
|
||||
|
||||
func (i *AtomicInt32) Add(n int32) int32 {
|
||||
return atomic.AddInt32((*int32)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicInt32) Set(n int32) {
|
||||
atomic.StoreInt32((*int32)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicInt32) Get() int32 {
|
||||
return atomic.LoadInt32((*int32)(i))
|
||||
}
|
||||
|
||||
func (i *AtomicInt32) CompareAndSwap(oldval, newval int32) (swapped bool) {
|
||||
return atomic.CompareAndSwapInt32((*int32)(i), oldval, newval)
|
||||
}
|
||||
|
||||
type AtomicUint32 uint32
|
||||
|
||||
func (i *AtomicUint32) Add(n uint32) uint32 {
|
||||
return atomic.AddUint32((*uint32)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicUint32) Set(n uint32) {
|
||||
atomic.StoreUint32((*uint32)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicUint32) Get() uint32 {
|
||||
return atomic.LoadUint32((*uint32)(i))
|
||||
}
|
||||
|
||||
func (i *AtomicUint32) CompareAndSwap(oldval, newval uint32) (swapped bool) {
|
||||
return atomic.CompareAndSwapUint32((*uint32)(i), oldval, newval)
|
||||
}
|
||||
|
||||
type AtomicInt64 int64
|
||||
|
||||
func (i *AtomicInt64) Add(n int64) int64 {
|
||||
return atomic.AddInt64((*int64)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicInt64) Set(n int64) {
|
||||
atomic.StoreInt64((*int64)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicInt64) Get() int64 {
|
||||
return atomic.LoadInt64((*int64)(i))
|
||||
}
|
||||
|
||||
func (i *AtomicInt64) CompareAndSwap(oldval, newval int64) (swapped bool) {
|
||||
return atomic.CompareAndSwapInt64((*int64)(i), oldval, newval)
|
||||
}
|
||||
|
||||
type AtomicUint64 uint64
|
||||
|
||||
func (i *AtomicUint64) Add(n uint64) uint64 {
|
||||
return atomic.AddUint64((*uint64)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicUint64) Set(n uint64) {
|
||||
atomic.StoreUint64((*uint64)(i), n)
|
||||
}
|
||||
|
||||
func (i *AtomicUint64) Get() uint64 {
|
||||
return atomic.LoadUint64((*uint64)(i))
|
||||
}
|
||||
|
||||
func (i *AtomicUint64) CompareAndSwap(oldval, newval uint64) (swapped bool) {
|
||||
return atomic.CompareAndSwapUint64((*uint64)(i), oldval, newval)
|
||||
}
|
||||
|
||||
type AtomicDuration int64
|
||||
|
||||
func (d *AtomicDuration) Add(duration time.Duration) time.Duration {
|
||||
return time.Duration(atomic.AddInt64((*int64)(d), int64(duration)))
|
||||
}
|
||||
|
||||
func (d *AtomicDuration) Set(duration time.Duration) {
|
||||
atomic.StoreInt64((*int64)(d), int64(duration))
|
||||
}
|
||||
|
||||
func (d *AtomicDuration) Get() time.Duration {
|
||||
return time.Duration(atomic.LoadInt64((*int64)(d)))
|
||||
}
|
||||
|
||||
func (d *AtomicDuration) CompareAndSwap(oldval, newval time.Duration) (swapped bool) {
|
||||
return atomic.CompareAndSwapInt64((*int64)(d), int64(oldval), int64(newval))
|
||||
}
|
||||
|
||||
// AtomicString gives you atomic-style APIs for string, but
|
||||
// it's only a convenience wrapper that uses a mutex. So, it's
|
||||
// not as efficient as the rest of the atomic types.
|
||||
type AtomicString struct {
|
||||
mu sync.Mutex
|
||||
str string
|
||||
}
|
||||
|
||||
func (s *AtomicString) Set(str string) {
|
||||
s.mu.Lock()
|
||||
s.str = str
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *AtomicString) Get() string {
|
||||
s.mu.Lock()
|
||||
str := s.str
|
||||
s.mu.Unlock()
|
||||
return str
|
||||
}
|
||||
|
||||
func (s *AtomicString) CompareAndSwap(oldval, newval string) (swapped bool) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if s.str == oldval {
|
||||
s.str = newval
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type AtomicBool int32
|
||||
|
||||
func (b *AtomicBool) Set(v bool) {
|
||||
if v {
|
||||
atomic.StoreInt32((*int32)(b), 1)
|
||||
} else {
|
||||
atomic.StoreInt32((*int32)(b), 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *AtomicBool) Get() bool {
|
||||
return atomic.LoadInt32((*int32)(b)) == 1
|
||||
}
|
65
vendor/github.com/siddontang/go/sync2/semaphore.go
generated
vendored
65
vendor/github.com/siddontang/go/sync2/semaphore.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
package sync2
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewSemaphore(initialCount int) *Semaphore {
|
||||
res := &Semaphore{
|
||||
counter: int64(initialCount),
|
||||
}
|
||||
res.cond.L = &res.lock
|
||||
return res
|
||||
}
|
||||
|
||||
type Semaphore struct {
|
||||
lock sync.Mutex
|
||||
cond sync.Cond
|
||||
counter int64
|
||||
}
|
||||
|
||||
func (s *Semaphore) Release() {
|
||||
s.lock.Lock()
|
||||
s.counter += 1
|
||||
if s.counter >= 0 {
|
||||
s.cond.Signal()
|
||||
}
|
||||
s.lock.Unlock()
|
||||
}
|
||||
|
||||
func (s *Semaphore) Acquire() {
|
||||
s.lock.Lock()
|
||||
for s.counter < 1 {
|
||||
s.cond.Wait()
|
||||
}
|
||||
s.counter -= 1
|
||||
s.lock.Unlock()
|
||||
}
|
||||
|
||||
func (s *Semaphore) AcquireTimeout(timeout time.Duration) bool {
|
||||
done := make(chan bool, 1)
|
||||
// Gate used to communicate between the threads and decide what the result
|
||||
// is. If the main thread decides, we have timed out, otherwise we succeed.
|
||||
decided := new(int32)
|
||||
go func() {
|
||||
s.Acquire()
|
||||
if atomic.SwapInt32(decided, 1) == 0 {
|
||||
done <- true
|
||||
} else {
|
||||
// If we already decided the result, and this thread did not win
|
||||
s.Release()
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
return true
|
||||
case <-time.NewTimer(timeout).C:
|
||||
if atomic.SwapInt32(decided, 1) == 1 {
|
||||
// The other thread already decided the result
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user