1
0
mirror of https://github.com/astaxie/beego.git synced 2025-07-01 08:40:19 +00:00

update mod

This commit is contained in:
astaxie
2018-11-09 12:37:28 +08:00
parent 9fdc1eaf3a
commit 5ea04bdfd3
548 changed files with 339257 additions and 46 deletions

20
vendor/github.com/siddontang/go/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
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 Normal file
View File

@ -0,0 +1,27 @@
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.

View File

@ -0,0 +1,17 @@
// 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)
}

View File

@ -0,0 +1,43 @@
// 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
}

View File

@ -0,0 +1,51 @@
// 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
}

View File

@ -0,0 +1,36 @@
// 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 Normal file
View File

@ -0,0 +1,27 @@
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 Normal file
View File

@ -0,0 +1,39 @@
// 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)
}

View File

@ -0,0 +1,69 @@
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 Normal file
View File

@ -0,0 +1,21 @@
// 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

221
vendor/github.com/siddontang/go/log/filehandler.go generated vendored Normal file
View File

@ -0,0 +1,221 @@
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
curBytes int
backupCount int
}
func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
dir := path.Dir(fileName)
os.MkdirAll(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
}
f, err := h.fd.Stat()
if err != nil {
return nil, err
}
h.curBytes = int(f.Size())
return h, nil
}
func (h *RotatingFileHandler) Write(p []byte) (n int, err error) {
h.doRollover()
n, err = h.fd.Write(p)
h.curBytes += n
return
}
func (h *RotatingFileHandler) Close() error {
if h.fd != nil {
return h.fd.Close()
}
return nil
}
func (h *RotatingFileHandler) doRollover() {
if h.curBytes < h.maxBytes {
return
}
f, err := h.fd.Stat()
if err != nil {
return
}
if h.maxBytes <= 0 {
return
} else if f.Size() < int64(h.maxBytes) {
h.curBytes = int(f.Size())
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)
h.curBytes = 0
f, err := h.fd.Stat()
if err != nil {
return
}
h.curBytes = int(f.Size())
}
}
//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 Normal file
View File

@ -0,0 +1,48 @@
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() {
}

343
vendor/github.com/siddontang/go/log/log.go generated vendored Normal file
View File

@ -0,0 +1,343 @@
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
bufMutex sync.Mutex
bufs [][]byte
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.closed.Set(0)
l.bufs = make([][]byte, 0, 16)
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) 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)
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, format string, v ...interface{}) {
if l.closed.Get() == 1 {
// closed
return
}
if l.level.Get() > level {
// higher level can be logged
return
}
var s string
if format == "" {
s = fmt.Sprint(v...)
} else {
s = fmt.Sprintf(format, v...)
}
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
l.hMutex.Lock()
l.handler.Write(buf)
l.hMutex.Unlock()
l.putBuf(buf)
}
//log with Trace level
func (l *Logger) Trace(v ...interface{}) {
l.Output(2, LevelTrace, "", v...)
}
//log with Debug level
func (l *Logger) Debug(v ...interface{}) {
l.Output(2, LevelDebug, "", v...)
}
//log with info level
func (l *Logger) Info(v ...interface{}) {
l.Output(2, LevelInfo, "", v...)
}
//log with warn level
func (l *Logger) Warn(v ...interface{}) {
l.Output(2, LevelWarn, "", v...)
}
//log with error level
func (l *Logger) Error(v ...interface{}) {
l.Output(2, LevelError, "", v...)
}
//log with fatal level
func (l *Logger) Fatal(v ...interface{}) {
l.Output(2, LevelFatal, "", v...)
}
//log with Trace level
func (l *Logger) Tracef(format string, v ...interface{}) {
l.Output(2, LevelTrace, format, v...)
}
//log with Debug level
func (l *Logger) Debugf(format string, v ...interface{}) {
l.Output(2, LevelDebug, format, v...)
}
//log with info level
func (l *Logger) Infof(format string, v ...interface{}) {
l.Output(2, LevelInfo, format, v...)
}
//log with warn level
func (l *Logger) Warnf(format string, v ...interface{}) {
l.Output(2, LevelWarn, format, v...)
}
//log with error level
func (l *Logger) Errorf(format string, v ...interface{}) {
l.Output(2, LevelError, format, v...)
}
//log with fatal level
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.Output(2, LevelFatal, 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, "", v...)
}
func Debug(v ...interface{}) {
std.Output(2, LevelDebug, "", v...)
}
func Info(v ...interface{}) {
std.Output(2, LevelInfo, "", v...)
}
func Warn(v ...interface{}) {
std.Output(2, LevelWarn, "", v...)
}
func Error(v ...interface{}) {
std.Output(2, LevelError, "", v...)
}
func Fatal(v ...interface{}) {
std.Output(2, LevelFatal, "", v...)
}
func Tracef(format string, v ...interface{}) {
std.Output(2, LevelTrace, format, v...)
}
func Debugf(format string, v ...interface{}) {
std.Output(2, LevelDebug, format, v...)
}
func Infof(format string, v ...interface{}) {
std.Output(2, LevelInfo, format, v...)
}
func Warnf(format string, v ...interface{}) {
std.Output(2, LevelWarn, format, v...)
}
func Errorf(format string, v ...interface{}) {
std.Output(2, LevelError, format, v...)
}
func Fatalf(format string, v ...interface{}) {
std.Output(2, LevelFatal, format, v...)
}

65
vendor/github.com/siddontang/go/log/sockethandler.go generated vendored Normal file
View File

@ -0,0 +1,65 @@
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 Normal file
View File

@ -0,0 +1,67 @@
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 Normal file
View File

@ -0,0 +1,161 @@
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 Normal file
View File

@ -0,0 +1,157 @@
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 Normal file
View File

@ -0,0 +1,27 @@
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 Normal file
View File

@ -0,0 +1,124 @@
// 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 Normal file
View File

@ -0,0 +1,174 @@
// 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 Normal file
View File

@ -0,0 +1,38 @@
// 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 Normal file
View File

@ -0,0 +1,146 @@
// 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 Normal file
View File

@ -0,0 +1,65 @@
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
}
}