mirror of
https://github.com/docker/awesome-compose.git
synced 2025-04-26 10:43:35 +02:00
add go mysql redis sample
Signed-off-by: vishal979 <shantapowertech2@gmail.com>
This commit is contained in:
parent
638c159abd
commit
207f73ab81
384 changed files with 233601 additions and 0 deletions
81
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/consistenthash/consistenthash.go
generated
vendored
Normal file
81
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/consistenthash/consistenthash.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package consistenthash provides an implementation of a ring hash.
|
||||
package consistenthash
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Hash func(data []byte) uint32
|
||||
|
||||
type Map struct {
|
||||
hash Hash
|
||||
replicas int
|
||||
keys []int // Sorted
|
||||
hashMap map[int]string
|
||||
}
|
||||
|
||||
func New(replicas int, fn Hash) *Map {
|
||||
m := &Map{
|
||||
replicas: replicas,
|
||||
hash: fn,
|
||||
hashMap: make(map[int]string),
|
||||
}
|
||||
if m.hash == nil {
|
||||
m.hash = crc32.ChecksumIEEE
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Returns true if there are no items available.
|
||||
func (m *Map) IsEmpty() bool {
|
||||
return len(m.keys) == 0
|
||||
}
|
||||
|
||||
// Adds some keys to the hash.
|
||||
func (m *Map) Add(keys ...string) {
|
||||
for _, key := range keys {
|
||||
for i := 0; i < m.replicas; i++ {
|
||||
hash := int(m.hash([]byte(strconv.Itoa(i) + key)))
|
||||
m.keys = append(m.keys, hash)
|
||||
m.hashMap[hash] = key
|
||||
}
|
||||
}
|
||||
sort.Ints(m.keys)
|
||||
}
|
||||
|
||||
// Gets the closest item in the hash to the provided key.
|
||||
func (m *Map) Get(key string) string {
|
||||
if m.IsEmpty() {
|
||||
return ""
|
||||
}
|
||||
|
||||
hash := int(m.hash([]byte(key)))
|
||||
|
||||
// Binary search for appropriate replica.
|
||||
idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })
|
||||
|
||||
// Means we have cycled back to the first replica.
|
||||
if idx == len(m.keys) {
|
||||
idx = 0
|
||||
}
|
||||
|
||||
return m.hashMap[m.keys[idx]]
|
||||
}
|
75
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/errors.go
generated
vendored
Normal file
75
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const Nil = RedisError("redis: nil")
|
||||
|
||||
type RedisError string
|
||||
|
||||
func (e RedisError) Error() string { return string(e) }
|
||||
|
||||
func IsRetryableError(err error) bool {
|
||||
return IsNetworkError(err)
|
||||
}
|
||||
|
||||
func IsInternalError(err error) bool {
|
||||
_, ok := err.(RedisError)
|
||||
return ok
|
||||
}
|
||||
|
||||
func IsNetworkError(err error) bool {
|
||||
if err == io.EOF {
|
||||
return true
|
||||
}
|
||||
_, ok := err.(net.Error)
|
||||
return ok
|
||||
}
|
||||
|
||||
func IsBadConn(err error, allowTimeout bool) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if IsInternalError(err) {
|
||||
return false
|
||||
}
|
||||
if allowTimeout {
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsMovedError(err error) (moved bool, ask bool, addr string) {
|
||||
if !IsInternalError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
s := err.Error()
|
||||
if strings.HasPrefix(s, "MOVED ") {
|
||||
moved = true
|
||||
} else if strings.HasPrefix(s, "ASK ") {
|
||||
ask = true
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
ind := strings.LastIndex(s, " ")
|
||||
if ind == -1 {
|
||||
return false, false, ""
|
||||
}
|
||||
addr = s[ind+1:]
|
||||
return
|
||||
}
|
||||
|
||||
func IsLoadingError(err error) bool {
|
||||
return strings.HasPrefix(err.Error(), "LOADING")
|
||||
}
|
||||
|
||||
func IsExecAbortError(err error) bool {
|
||||
return strings.HasPrefix(err.Error(), "EXECABORT")
|
||||
}
|
73
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/hashtag/hashtag.go
generated
vendored
Normal file
73
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/hashtag/hashtag.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
package hashtag
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const SlotNumber = 16384
|
||||
|
||||
// CRC16 implementation according to CCITT standards.
|
||||
// Copyright 2001-2010 Georges Menie (www.menie.org)
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// http://redis.io/topics/cluster-spec#appendix-a-crc16-reference-implementation-in-ansi-c
|
||||
var crc16tab = [256]uint16{
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
||||
}
|
||||
|
||||
func Key(key string) string {
|
||||
if s := strings.IndexByte(key, '{'); s > -1 {
|
||||
if e := strings.IndexByte(key[s+1:], '}'); e > 0 {
|
||||
return key[s+1 : s+e+1]
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// hashSlot returns a consistent slot number between 0 and 16383
|
||||
// for any given string key.
|
||||
func Slot(key string) int {
|
||||
key = Key(key)
|
||||
if key == "" {
|
||||
return rand.Intn(SlotNumber)
|
||||
}
|
||||
return int(crc16sum(key)) % SlotNumber
|
||||
}
|
||||
|
||||
func crc16sum(key string) (crc uint16) {
|
||||
for i := 0; i < len(key); i++ {
|
||||
crc = (crc << 8) ^ crc16tab[(byte(crc>>8)^key[i])&0x00ff]
|
||||
}
|
||||
return
|
||||
}
|
15
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/log.go
generated
vendored
Normal file
15
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/log.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
var Logger *log.Logger
|
||||
|
||||
func Logf(s string, args ...interface{}) {
|
||||
if Logger == nil {
|
||||
return
|
||||
}
|
||||
Logger.Output(2, fmt.Sprintf(s, args...))
|
||||
}
|
78
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/conn.go
generated
vendored
Normal file
78
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/conn.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gopkg.in/redis.v5/internal/proto"
|
||||
)
|
||||
|
||||
var noDeadline = time.Time{}
|
||||
|
||||
type Conn struct {
|
||||
netConn net.Conn
|
||||
|
||||
Rd *proto.Reader
|
||||
Wb *proto.WriteBuffer
|
||||
|
||||
Inited bool
|
||||
usedAt atomic.Value
|
||||
}
|
||||
|
||||
func NewConn(netConn net.Conn) *Conn {
|
||||
cn := &Conn{
|
||||
netConn: netConn,
|
||||
Wb: proto.NewWriteBuffer(),
|
||||
}
|
||||
cn.Rd = proto.NewReader(cn.netConn)
|
||||
cn.SetUsedAt(time.Now())
|
||||
return cn
|
||||
}
|
||||
|
||||
func (cn *Conn) UsedAt() time.Time {
|
||||
return cn.usedAt.Load().(time.Time)
|
||||
}
|
||||
|
||||
func (cn *Conn) SetUsedAt(tm time.Time) {
|
||||
cn.usedAt.Store(tm)
|
||||
}
|
||||
|
||||
func (cn *Conn) SetNetConn(netConn net.Conn) {
|
||||
cn.netConn = netConn
|
||||
cn.Rd.Reset(netConn)
|
||||
}
|
||||
|
||||
func (cn *Conn) IsStale(timeout time.Duration) bool {
|
||||
return timeout > 0 && time.Since(cn.UsedAt()) > timeout
|
||||
}
|
||||
|
||||
func (cn *Conn) SetReadTimeout(timeout time.Duration) error {
|
||||
now := time.Now()
|
||||
cn.SetUsedAt(now)
|
||||
if timeout > 0 {
|
||||
return cn.netConn.SetReadDeadline(now.Add(timeout))
|
||||
}
|
||||
return cn.netConn.SetReadDeadline(noDeadline)
|
||||
}
|
||||
|
||||
func (cn *Conn) SetWriteTimeout(timeout time.Duration) error {
|
||||
now := time.Now()
|
||||
cn.SetUsedAt(now)
|
||||
if timeout > 0 {
|
||||
return cn.netConn.SetWriteDeadline(now.Add(timeout))
|
||||
}
|
||||
return cn.netConn.SetWriteDeadline(noDeadline)
|
||||
}
|
||||
|
||||
func (cn *Conn) Write(b []byte) (int, error) {
|
||||
return cn.netConn.Write(b)
|
||||
}
|
||||
|
||||
func (cn *Conn) RemoteAddr() net.Addr {
|
||||
return cn.netConn.RemoteAddr()
|
||||
}
|
||||
|
||||
func (cn *Conn) Close() error {
|
||||
return cn.netConn.Close()
|
||||
}
|
354
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool.go
generated
vendored
Normal file
354
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool.go
generated
vendored
Normal file
|
@ -0,0 +1,354 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gopkg.in/redis.v5/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrClosed = errors.New("redis: client is closed")
|
||||
ErrPoolTimeout = errors.New("redis: connection pool timeout")
|
||||
errConnStale = errors.New("connection is stale")
|
||||
)
|
||||
|
||||
var timers = sync.Pool{
|
||||
New: func() interface{} {
|
||||
t := time.NewTimer(time.Hour)
|
||||
t.Stop()
|
||||
return t
|
||||
},
|
||||
}
|
||||
|
||||
// Stats contains pool state information and accumulated stats.
|
||||
type Stats struct {
|
||||
Requests uint32 // number of times a connection was requested by the pool
|
||||
Hits uint32 // number of times free connection was found in the pool
|
||||
Timeouts uint32 // number of times a wait timeout occurred
|
||||
|
||||
TotalConns uint32 // the number of total connections in the pool
|
||||
FreeConns uint32 // the number of free connections in the pool
|
||||
}
|
||||
|
||||
type Pooler interface {
|
||||
Get() (*Conn, bool, error)
|
||||
Put(*Conn) error
|
||||
Remove(*Conn, error) error
|
||||
Len() int
|
||||
FreeLen() int
|
||||
Stats() *Stats
|
||||
Close() error
|
||||
}
|
||||
|
||||
type dialer func() (net.Conn, error)
|
||||
|
||||
type ConnPool struct {
|
||||
dial dialer
|
||||
OnClose func(*Conn) error
|
||||
|
||||
poolTimeout time.Duration
|
||||
idleTimeout time.Duration
|
||||
|
||||
queue chan struct{}
|
||||
|
||||
connsMu sync.Mutex
|
||||
conns []*Conn
|
||||
|
||||
freeConnsMu sync.Mutex
|
||||
freeConns []*Conn
|
||||
|
||||
stats Stats
|
||||
|
||||
_closed int32 // atomic
|
||||
lastErr atomic.Value
|
||||
}
|
||||
|
||||
var _ Pooler = (*ConnPool)(nil)
|
||||
|
||||
func NewConnPool(dial dialer, poolSize int, poolTimeout, idleTimeout, idleCheckFrequency time.Duration) *ConnPool {
|
||||
p := &ConnPool{
|
||||
dial: dial,
|
||||
|
||||
poolTimeout: poolTimeout,
|
||||
idleTimeout: idleTimeout,
|
||||
|
||||
queue: make(chan struct{}, poolSize),
|
||||
conns: make([]*Conn, 0, poolSize),
|
||||
freeConns: make([]*Conn, 0, poolSize),
|
||||
}
|
||||
if idleTimeout > 0 && idleCheckFrequency > 0 {
|
||||
go p.reaper(idleCheckFrequency)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *ConnPool) NewConn() (*Conn, error) {
|
||||
netConn, err := p.dial()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewConn(netConn), nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) PopFree() *Conn {
|
||||
timer := timers.Get().(*time.Timer)
|
||||
timer.Reset(p.poolTimeout)
|
||||
|
||||
select {
|
||||
case p.queue <- struct{}{}:
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
timers.Put(timer)
|
||||
case <-timer.C:
|
||||
timers.Put(timer)
|
||||
atomic.AddUint32(&p.stats.Timeouts, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
p.freeConnsMu.Lock()
|
||||
cn := p.popFree()
|
||||
p.freeConnsMu.Unlock()
|
||||
|
||||
if cn == nil {
|
||||
<-p.queue
|
||||
}
|
||||
return cn
|
||||
}
|
||||
|
||||
func (p *ConnPool) popFree() *Conn {
|
||||
if len(p.freeConns) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
idx := len(p.freeConns) - 1
|
||||
cn := p.freeConns[idx]
|
||||
p.freeConns = p.freeConns[:idx]
|
||||
return cn
|
||||
}
|
||||
|
||||
// Get returns existed connection from the pool or creates a new one.
|
||||
func (p *ConnPool) Get() (*Conn, bool, error) {
|
||||
if p.closed() {
|
||||
return nil, false, ErrClosed
|
||||
}
|
||||
|
||||
atomic.AddUint32(&p.stats.Requests, 1)
|
||||
|
||||
timer := timers.Get().(*time.Timer)
|
||||
timer.Reset(p.poolTimeout)
|
||||
|
||||
select {
|
||||
case p.queue <- struct{}{}:
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
timers.Put(timer)
|
||||
case <-timer.C:
|
||||
timers.Put(timer)
|
||||
atomic.AddUint32(&p.stats.Timeouts, 1)
|
||||
return nil, false, ErrPoolTimeout
|
||||
}
|
||||
|
||||
for {
|
||||
p.freeConnsMu.Lock()
|
||||
cn := p.popFree()
|
||||
p.freeConnsMu.Unlock()
|
||||
|
||||
if cn == nil {
|
||||
break
|
||||
}
|
||||
|
||||
if cn.IsStale(p.idleTimeout) {
|
||||
p.remove(cn, errConnStale)
|
||||
continue
|
||||
}
|
||||
|
||||
atomic.AddUint32(&p.stats.Hits, 1)
|
||||
return cn, false, nil
|
||||
}
|
||||
|
||||
newcn, err := p.NewConn()
|
||||
if err != nil {
|
||||
<-p.queue
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
p.connsMu.Lock()
|
||||
p.conns = append(p.conns, newcn)
|
||||
p.connsMu.Unlock()
|
||||
|
||||
return newcn, true, nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) Put(cn *Conn) error {
|
||||
if data := cn.Rd.PeekBuffered(); data != nil {
|
||||
err := fmt.Errorf("connection has unread data: %q", data)
|
||||
internal.Logf(err.Error())
|
||||
return p.Remove(cn, err)
|
||||
}
|
||||
p.freeConnsMu.Lock()
|
||||
p.freeConns = append(p.freeConns, cn)
|
||||
p.freeConnsMu.Unlock()
|
||||
<-p.queue
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) Remove(cn *Conn, reason error) error {
|
||||
p.remove(cn, reason)
|
||||
<-p.queue
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) remove(cn *Conn, reason error) {
|
||||
_ = p.closeConn(cn, reason)
|
||||
|
||||
p.connsMu.Lock()
|
||||
for i, c := range p.conns {
|
||||
if c == cn {
|
||||
p.conns = append(p.conns[:i], p.conns[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
p.connsMu.Unlock()
|
||||
}
|
||||
|
||||
// Len returns total number of connections.
|
||||
func (p *ConnPool) Len() int {
|
||||
p.connsMu.Lock()
|
||||
l := len(p.conns)
|
||||
p.connsMu.Unlock()
|
||||
return l
|
||||
}
|
||||
|
||||
// FreeLen returns number of free connections.
|
||||
func (p *ConnPool) FreeLen() int {
|
||||
p.freeConnsMu.Lock()
|
||||
l := len(p.freeConns)
|
||||
p.freeConnsMu.Unlock()
|
||||
return l
|
||||
}
|
||||
|
||||
func (p *ConnPool) Stats() *Stats {
|
||||
return &Stats{
|
||||
Requests: atomic.LoadUint32(&p.stats.Requests),
|
||||
Hits: atomic.LoadUint32(&p.stats.Hits),
|
||||
Timeouts: atomic.LoadUint32(&p.stats.Timeouts),
|
||||
TotalConns: uint32(p.Len()),
|
||||
FreeConns: uint32(p.FreeLen()),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ConnPool) closed() bool {
|
||||
return atomic.LoadInt32(&p._closed) == 1
|
||||
}
|
||||
|
||||
func (p *ConnPool) Close() error {
|
||||
if !atomic.CompareAndSwapInt32(&p._closed, 0, 1) {
|
||||
return ErrClosed
|
||||
}
|
||||
|
||||
p.connsMu.Lock()
|
||||
var firstErr error
|
||||
for _, cn := range p.conns {
|
||||
if cn == nil {
|
||||
continue
|
||||
}
|
||||
if err := p.closeConn(cn, ErrClosed); err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
}
|
||||
p.conns = nil
|
||||
p.connsMu.Unlock()
|
||||
|
||||
p.freeConnsMu.Lock()
|
||||
p.freeConns = nil
|
||||
p.freeConnsMu.Unlock()
|
||||
|
||||
return firstErr
|
||||
}
|
||||
|
||||
func (p *ConnPool) closeConn(cn *Conn, reason error) error {
|
||||
if p.OnClose != nil {
|
||||
_ = p.OnClose(cn)
|
||||
}
|
||||
return cn.Close()
|
||||
}
|
||||
|
||||
func (p *ConnPool) reapStaleConn() bool {
|
||||
if len(p.freeConns) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
cn := p.freeConns[0]
|
||||
if !cn.IsStale(p.idleTimeout) {
|
||||
return false
|
||||
}
|
||||
|
||||
p.remove(cn, errConnStale)
|
||||
p.freeConns = append(p.freeConns[:0], p.freeConns[1:]...)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *ConnPool) ReapStaleConns() (int, error) {
|
||||
var n int
|
||||
for {
|
||||
p.queue <- struct{}{}
|
||||
p.freeConnsMu.Lock()
|
||||
|
||||
reaped := p.reapStaleConn()
|
||||
|
||||
p.freeConnsMu.Unlock()
|
||||
<-p.queue
|
||||
|
||||
if reaped {
|
||||
n++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) reaper(frequency time.Duration) {
|
||||
ticker := time.NewTicker(frequency)
|
||||
defer ticker.Stop()
|
||||
|
||||
for _ = range ticker.C {
|
||||
if p.closed() {
|
||||
break
|
||||
}
|
||||
n, err := p.ReapStaleConns()
|
||||
if err != nil {
|
||||
internal.Logf("ReapStaleConns failed: %s", err)
|
||||
continue
|
||||
}
|
||||
s := p.Stats()
|
||||
internal.Logf(
|
||||
"reaper: removed %d stale conns (TotalConns=%d FreeConns=%d Requests=%d Hits=%d Timeouts=%d)",
|
||||
n, s.TotalConns, s.FreeConns, s.Requests, s.Hits, s.Timeouts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var idleCheckFrequency atomic.Value
|
||||
|
||||
func SetIdleCheckFrequency(d time.Duration) {
|
||||
idleCheckFrequency.Store(d)
|
||||
}
|
||||
|
||||
func getIdleCheckFrequency() time.Duration {
|
||||
v := idleCheckFrequency.Load()
|
||||
if v == nil {
|
||||
return time.Minute
|
||||
}
|
||||
return v.(time.Duration)
|
||||
}
|
47
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool_single.go
generated
vendored
Normal file
47
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool_single.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
package pool
|
||||
|
||||
type SingleConnPool struct {
|
||||
cn *Conn
|
||||
}
|
||||
|
||||
var _ Pooler = (*SingleConnPool)(nil)
|
||||
|
||||
func NewSingleConnPool(cn *Conn) *SingleConnPool {
|
||||
return &SingleConnPool{
|
||||
cn: cn,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Get() (*Conn, bool, error) {
|
||||
return p.cn, false, nil
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Put(cn *Conn) error {
|
||||
if p.cn != cn {
|
||||
panic("p.cn != cn")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Remove(cn *Conn, _ error) error {
|
||||
if p.cn != cn {
|
||||
panic("p.cn != cn")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Len() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) FreeLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Stats() *Stats {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *SingleConnPool) Close() error {
|
||||
return nil
|
||||
}
|
119
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool_sticky.go
generated
vendored
Normal file
119
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/pool/pool_sticky.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type StickyConnPool struct {
|
||||
pool *ConnPool
|
||||
reusable bool
|
||||
|
||||
cn *Conn
|
||||
closed bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
var _ Pooler = (*StickyConnPool)(nil)
|
||||
|
||||
func NewStickyConnPool(pool *ConnPool, reusable bool) *StickyConnPool {
|
||||
return &StickyConnPool{
|
||||
pool: pool,
|
||||
reusable: reusable,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Get() (*Conn, bool, error) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.closed {
|
||||
return nil, false, ErrClosed
|
||||
}
|
||||
if p.cn != nil {
|
||||
return p.cn, false, nil
|
||||
}
|
||||
|
||||
cn, _, err := p.pool.Get()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
p.cn = cn
|
||||
return cn, true, nil
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) putUpstream() (err error) {
|
||||
err = p.pool.Put(p.cn)
|
||||
p.cn = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Put(cn *Conn) error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) removeUpstream(reason error) error {
|
||||
err := p.pool.Remove(p.cn, reason)
|
||||
p.cn = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Remove(cn *Conn, reason error) error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.closed {
|
||||
return nil
|
||||
}
|
||||
return p.removeUpstream(reason)
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Len() int {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.cn == nil {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) FreeLen() int {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.cn == nil {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Stats() *Stats {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *StickyConnPool) Close() error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
p.closed = true
|
||||
var err error
|
||||
if p.cn != nil {
|
||||
if p.reusable {
|
||||
err = p.putUpstream()
|
||||
} else {
|
||||
reason := errors.New("redis: unreusable sticky connection")
|
||||
err = p.removeUpstream(reason)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
334
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/reader.go
generated
vendored
Normal file
334
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/reader.go
generated
vendored
Normal file
|
@ -0,0 +1,334 @@
|
|||
package proto
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/redis.v5/internal"
|
||||
)
|
||||
|
||||
const bytesAllocLimit = 1024 * 1024 // 1mb
|
||||
|
||||
const (
|
||||
ErrorReply = '-'
|
||||
StatusReply = '+'
|
||||
IntReply = ':'
|
||||
StringReply = '$'
|
||||
ArrayReply = '*'
|
||||
)
|
||||
|
||||
type MultiBulkParse func(*Reader, int64) (interface{}, error)
|
||||
|
||||
type Reader struct {
|
||||
src *bufio.Reader
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func NewReader(rd io.Reader) *Reader {
|
||||
return &Reader{
|
||||
src: bufio.NewReader(rd),
|
||||
buf: make([]byte, 4096),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) Reset(rd io.Reader) {
|
||||
r.src.Reset(rd)
|
||||
}
|
||||
|
||||
func (p *Reader) PeekBuffered() []byte {
|
||||
if n := p.src.Buffered(); n != 0 {
|
||||
b, _ := p.src.Peek(n)
|
||||
return b
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Reader) ReadN(n int) ([]byte, error) {
|
||||
b, err := readN(p.src, p.buf, n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.buf = b
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (p *Reader) ReadLine() ([]byte, error) {
|
||||
line, isPrefix, err := p.src.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isPrefix {
|
||||
return nil, bufio.ErrBufferFull
|
||||
}
|
||||
if len(line) == 0 {
|
||||
return nil, internal.RedisError("redis: reply is empty")
|
||||
}
|
||||
if isNilReply(line) {
|
||||
return nil, internal.Nil
|
||||
}
|
||||
return line, nil
|
||||
}
|
||||
|
||||
func (p *Reader) ReadReply(m MultiBulkParse) (interface{}, error) {
|
||||
line, err := p.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch line[0] {
|
||||
case ErrorReply:
|
||||
return nil, ParseErrorReply(line)
|
||||
case StatusReply:
|
||||
return parseStatusValue(line), nil
|
||||
case IntReply:
|
||||
return parseInt(line[1:], 10, 64)
|
||||
case StringReply:
|
||||
return p.readTmpBytesValue(line)
|
||||
case ArrayReply:
|
||||
n, err := parseArrayLen(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m(p, n)
|
||||
}
|
||||
return nil, fmt.Errorf("redis: can't parse %.100q", line)
|
||||
}
|
||||
|
||||
func (p *Reader) ReadIntReply() (int64, error) {
|
||||
line, err := p.ReadLine()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch line[0] {
|
||||
case ErrorReply:
|
||||
return 0, ParseErrorReply(line)
|
||||
case IntReply:
|
||||
return parseInt(line[1:], 10, 64)
|
||||
default:
|
||||
return 0, fmt.Errorf("redis: can't parse int reply: %.100q", line)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Reader) ReadTmpBytesReply() ([]byte, error) {
|
||||
line, err := p.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch line[0] {
|
||||
case ErrorReply:
|
||||
return nil, ParseErrorReply(line)
|
||||
case StringReply:
|
||||
return p.readTmpBytesValue(line)
|
||||
case StatusReply:
|
||||
return parseStatusValue(line), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("redis: can't parse string reply: %.100q", line)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) ReadBytesReply() ([]byte, error) {
|
||||
b, err := r.ReadTmpBytesReply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cp := make([]byte, len(b))
|
||||
copy(cp, b)
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
func (p *Reader) ReadStringReply() (string, error) {
|
||||
b, err := p.ReadTmpBytesReply()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func (p *Reader) ReadFloatReply() (float64, error) {
|
||||
b, err := p.ReadTmpBytesReply()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return parseFloat(b, 64)
|
||||
}
|
||||
|
||||
func (p *Reader) ReadArrayReply(m MultiBulkParse) (interface{}, error) {
|
||||
line, err := p.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch line[0] {
|
||||
case ErrorReply:
|
||||
return nil, ParseErrorReply(line)
|
||||
case ArrayReply:
|
||||
n, err := parseArrayLen(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m(p, n)
|
||||
default:
|
||||
return nil, fmt.Errorf("redis: can't parse array reply: %.100q", line)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Reader) ReadArrayLen() (int64, error) {
|
||||
line, err := p.ReadLine()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch line[0] {
|
||||
case ErrorReply:
|
||||
return 0, ParseErrorReply(line)
|
||||
case ArrayReply:
|
||||
return parseArrayLen(line)
|
||||
default:
|
||||
return 0, fmt.Errorf("redis: can't parse array reply: %.100q", line)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Reader) ReadScanReply() ([]string, uint64, error) {
|
||||
n, err := p.ReadArrayLen()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if n != 2 {
|
||||
return nil, 0, fmt.Errorf("redis: got %d elements in scan reply, expected 2", n)
|
||||
}
|
||||
|
||||
cursor, err := p.ReadUint()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
n, err = p.ReadArrayLen()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
keys := make([]string, n)
|
||||
for i := int64(0); i < n; i++ {
|
||||
key, err := p.ReadStringReply()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
keys[i] = key
|
||||
}
|
||||
|
||||
return keys, cursor, err
|
||||
}
|
||||
|
||||
func (p *Reader) readTmpBytesValue(line []byte) ([]byte, error) {
|
||||
if isNilReply(line) {
|
||||
return nil, internal.Nil
|
||||
}
|
||||
|
||||
replyLen, err := strconv.Atoi(string(line[1:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err := p.ReadN(replyLen + 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:replyLen], nil
|
||||
}
|
||||
|
||||
func (r *Reader) ReadInt() (int64, error) {
|
||||
b, err := r.ReadTmpBytesReply()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return parseInt(b, 10, 64)
|
||||
}
|
||||
|
||||
func (r *Reader) ReadUint() (uint64, error) {
|
||||
b, err := r.ReadTmpBytesReply()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return parseUint(b, 10, 64)
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
func readN(r io.Reader, b []byte, n int) ([]byte, error) {
|
||||
if n == 0 && b == nil {
|
||||
return make([]byte, 0), nil
|
||||
}
|
||||
|
||||
if cap(b) >= n {
|
||||
b = b[:n]
|
||||
_, err := io.ReadFull(r, b)
|
||||
return b, err
|
||||
}
|
||||
b = b[:cap(b)]
|
||||
|
||||
pos := 0
|
||||
for pos < n {
|
||||
diff := n - len(b)
|
||||
if diff > bytesAllocLimit {
|
||||
diff = bytesAllocLimit
|
||||
}
|
||||
b = append(b, make([]byte, diff)...)
|
||||
|
||||
nn, err := io.ReadFull(r, b[pos:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pos += nn
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func formatInt(n int64) string {
|
||||
return strconv.FormatInt(n, 10)
|
||||
}
|
||||
|
||||
func formatUint(u uint64) string {
|
||||
return strconv.FormatUint(u, 10)
|
||||
}
|
||||
|
||||
func formatFloat(f float64) string {
|
||||
return strconv.FormatFloat(f, 'f', -1, 64)
|
||||
}
|
||||
|
||||
func isNilReply(b []byte) bool {
|
||||
return len(b) == 3 &&
|
||||
(b[0] == StringReply || b[0] == ArrayReply) &&
|
||||
b[1] == '-' && b[2] == '1'
|
||||
}
|
||||
|
||||
func ParseErrorReply(line []byte) error {
|
||||
return internal.RedisError(string(line[1:]))
|
||||
}
|
||||
|
||||
func parseStatusValue(line []byte) []byte {
|
||||
return line[1:]
|
||||
}
|
||||
|
||||
func parseArrayLen(line []byte) (int64, error) {
|
||||
if isNilReply(line) {
|
||||
return 0, internal.Nil
|
||||
}
|
||||
return parseInt(line[1:], 10, 64)
|
||||
}
|
||||
|
||||
func atoi(b []byte) (int, error) {
|
||||
return strconv.Atoi(internal.BytesToString(b))
|
||||
}
|
||||
|
||||
func parseInt(b []byte, base int, bitSize int) (int64, error) {
|
||||
return strconv.ParseInt(internal.BytesToString(b), base, bitSize)
|
||||
}
|
||||
|
||||
func parseUint(b []byte, base int, bitSize int) (uint64, error) {
|
||||
return strconv.ParseUint(internal.BytesToString(b), base, bitSize)
|
||||
}
|
||||
|
||||
func parseFloat(b []byte, bitSize int) (float64, error) {
|
||||
return strconv.ParseFloat(internal.BytesToString(b), bitSize)
|
||||
}
|
131
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/scan.go
generated
vendored
Normal file
131
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/scan.go
generated
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
package proto
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"gopkg.in/redis.v5/internal"
|
||||
)
|
||||
|
||||
func Scan(b []byte, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
return internal.RedisError("redis: Scan(nil)")
|
||||
case *string:
|
||||
*v = internal.BytesToString(b)
|
||||
return nil
|
||||
case *[]byte:
|
||||
*v = b
|
||||
return nil
|
||||
case *int:
|
||||
var err error
|
||||
*v, err = atoi(b)
|
||||
return err
|
||||
case *int8:
|
||||
n, err := parseInt(b, 10, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = int8(n)
|
||||
return nil
|
||||
case *int16:
|
||||
n, err := parseInt(b, 10, 16)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = int16(n)
|
||||
return nil
|
||||
case *int32:
|
||||
n, err := parseInt(b, 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = int32(n)
|
||||
return nil
|
||||
case *int64:
|
||||
n, err := parseInt(b, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = n
|
||||
return nil
|
||||
case *uint:
|
||||
n, err := parseUint(b, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = uint(n)
|
||||
return nil
|
||||
case *uint8:
|
||||
n, err := parseUint(b, 10, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = uint8(n)
|
||||
return nil
|
||||
case *uint16:
|
||||
n, err := parseUint(b, 10, 16)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = uint16(n)
|
||||
return nil
|
||||
case *uint32:
|
||||
n, err := parseUint(b, 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = uint32(n)
|
||||
return nil
|
||||
case *uint64:
|
||||
n, err := parseUint(b, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = n
|
||||
return nil
|
||||
case *float32:
|
||||
n, err := parseFloat(b, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = float32(n)
|
||||
return err
|
||||
case *float64:
|
||||
var err error
|
||||
*v, err = parseFloat(b, 64)
|
||||
return err
|
||||
case *bool:
|
||||
*v = len(b) == 1 && b[0] == '1'
|
||||
return nil
|
||||
case encoding.BinaryUnmarshaler:
|
||||
return v.UnmarshalBinary(b)
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"redis: can't unmarshal %T (consider implementing BinaryUnmarshaler)", v)
|
||||
}
|
||||
}
|
||||
|
||||
func ScanSlice(data []string, slice interface{}) error {
|
||||
v := reflect.ValueOf(slice)
|
||||
if !v.IsValid() {
|
||||
return fmt.Errorf("redis: ScanSlice(nil)")
|
||||
}
|
||||
if v.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("redis: ScanSlice(non-pointer %T)", slice)
|
||||
}
|
||||
v = v.Elem()
|
||||
if v.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("redis: ScanSlice(non-slice %T)", slice)
|
||||
}
|
||||
|
||||
for i, s := range data {
|
||||
elem := internal.SliceNextElem(v)
|
||||
if err := Scan([]byte(s), elem.Addr().Interface()); err != nil {
|
||||
return fmt.Errorf("redis: ScanSlice(index=%d value=%q) failed: %s", i, s, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
105
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/write_buffer.go
generated
vendored
Normal file
105
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/proto/write_buffer.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package proto
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const bufferSize = 4096
|
||||
|
||||
type WriteBuffer struct {
|
||||
b []byte
|
||||
}
|
||||
|
||||
func NewWriteBuffer() *WriteBuffer {
|
||||
return &WriteBuffer{
|
||||
b: make([]byte, 0, 4096),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WriteBuffer) Len() int { return len(w.b) }
|
||||
func (w *WriteBuffer) Bytes() []byte { return w.b }
|
||||
func (w *WriteBuffer) Reset() { w.b = w.b[:0] }
|
||||
|
||||
func (w *WriteBuffer) Append(args []interface{}) error {
|
||||
w.b = append(w.b, ArrayReply)
|
||||
w.b = strconv.AppendUint(w.b, uint64(len(args)), 10)
|
||||
w.b = append(w.b, '\r', '\n')
|
||||
|
||||
for _, arg := range args {
|
||||
if err := w.append(arg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WriteBuffer) append(val interface{}) error {
|
||||
switch v := val.(type) {
|
||||
case nil:
|
||||
w.AppendString("")
|
||||
case string:
|
||||
w.AppendString(v)
|
||||
case []byte:
|
||||
w.AppendBytes(v)
|
||||
case int:
|
||||
w.AppendString(formatInt(int64(v)))
|
||||
case int8:
|
||||
w.AppendString(formatInt(int64(v)))
|
||||
case int16:
|
||||
w.AppendString(formatInt(int64(v)))
|
||||
case int32:
|
||||
w.AppendString(formatInt(int64(v)))
|
||||
case int64:
|
||||
w.AppendString(formatInt(v))
|
||||
case uint:
|
||||
w.AppendString(formatUint(uint64(v)))
|
||||
case uint8:
|
||||
w.AppendString(formatUint(uint64(v)))
|
||||
case uint16:
|
||||
w.AppendString(formatUint(uint64(v)))
|
||||
case uint32:
|
||||
w.AppendString(formatUint(uint64(v)))
|
||||
case uint64:
|
||||
w.AppendString(formatUint(v))
|
||||
case float32:
|
||||
w.AppendString(formatFloat(float64(v)))
|
||||
case float64:
|
||||
w.AppendString(formatFloat(v))
|
||||
case bool:
|
||||
if v {
|
||||
w.AppendString("1")
|
||||
} else {
|
||||
w.AppendString("0")
|
||||
}
|
||||
default:
|
||||
if bm, ok := val.(encoding.BinaryMarshaler); ok {
|
||||
bb, err := bm.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.AppendBytes(bb)
|
||||
} else {
|
||||
return fmt.Errorf(
|
||||
"redis: can't marshal %T (consider implementing encoding.BinaryMarshaler)", val)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WriteBuffer) AppendString(s string) {
|
||||
w.b = append(w.b, StringReply)
|
||||
w.b = strconv.AppendUint(w.b, uint64(len(s)), 10)
|
||||
w.b = append(w.b, '\r', '\n')
|
||||
w.b = append(w.b, s...)
|
||||
w.b = append(w.b, '\r', '\n')
|
||||
}
|
||||
|
||||
func (w *WriteBuffer) AppendBytes(p []byte) {
|
||||
w.b = append(w.b, StringReply)
|
||||
w.b = strconv.AppendUint(w.b, uint64(len(p)), 10)
|
||||
w.b = append(w.b, '\r', '\n')
|
||||
w.b = append(w.b, p...)
|
||||
w.b = append(w.b, '\r', '\n')
|
||||
}
|
7
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/safe.go
generated
vendored
Normal file
7
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/safe.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
// +build appengine
|
||||
|
||||
package internal
|
||||
|
||||
func BytesToString(b []byte) string {
|
||||
return string(b)
|
||||
}
|
14
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/unsafe.go
generated
vendored
Normal file
14
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// +build !appengine
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func BytesToString(b []byte) string {
|
||||
bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
strHeader := reflect.StringHeader{bytesHeader.Data, bytesHeader.Len}
|
||||
return *(*string)(unsafe.Pointer(&strHeader))
|
||||
}
|
47
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/util.go
generated
vendored
Normal file
47
go-mysql-redis/vendor/gopkg.in/redis.v5/internal/util.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
package internal
|
||||
|
||||
import "reflect"
|
||||
|
||||
func ToLower(s string) string {
|
||||
if isLower(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
b := make([]byte, len(s))
|
||||
for i := range b {
|
||||
c := s[i]
|
||||
if c >= 'A' && c <= 'Z' {
|
||||
c += 'a' - 'A'
|
||||
}
|
||||
b[i] = c
|
||||
}
|
||||
return BytesToString(b)
|
||||
}
|
||||
|
||||
func isLower(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c >= 'A' && c <= 'Z' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SliceNextElem(v reflect.Value) reflect.Value {
|
||||
if v.Len() < v.Cap() {
|
||||
v.Set(v.Slice(0, v.Len()+1))
|
||||
return v.Index(v.Len() - 1)
|
||||
}
|
||||
|
||||
elemType := v.Type().Elem()
|
||||
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
elem := reflect.New(elemType.Elem())
|
||||
v.Set(reflect.Append(v, elem))
|
||||
return elem.Elem()
|
||||
}
|
||||
|
||||
v.Set(reflect.Append(v, reflect.Zero(elemType)))
|
||||
return v.Index(v.Len() - 1)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue