diff --git a/go.mod b/go.mod index 8f3eea3..c564fbe 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,9 @@ go 1.18 require ( github.com/google/uuid v1.3.0 - github.com/lwahlmeier/lcwlog v0.0.1 + github.com/lwahlmeier/GoScheduler v1.0.1 + github.com/lwahlmeier/lcwlog v0.1.0 + github.com/lwahlmeier/unboundChannel v1.0.0 github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.1.1 github.com/stretchr/testify v1.8.0 @@ -14,14 +16,12 @@ require ( ) require ( - github.com/cornelk/hashmap v1.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dchest/siphash v1.1.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/lwahlmeier/pyfmt v0.0.1 // indirect + github.com/lwahlmeier/pyfmt v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -30,7 +30,6 @@ require ( github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/tevino/abool v1.2.0 // indirect golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect golang.org/x/text v0.3.7 // indirect diff --git a/go.sum b/go.sum index a92245a..30400db 100644 --- a/go.sum +++ b/go.sum @@ -46,14 +46,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cornelk/hashmap v1.0.1 h1:RXGcy29hEdLLV8T6aK4s+BAd4tq4+3Hq50N2GoG0uIg= -github.com/cornelk/hashmap v1.0.1/go.mod h1:8wbysTUDnwJGrPZ1Iwsou3m+An6sldFrJItjRhfegCw= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/siphash v1.1.0 h1:1Rs9eTUlZLPBEvV+2sTaM8O0NWn0ppbgqS7p11aWawI= -github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -106,7 +102,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -145,10 +140,14 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/lwahlmeier/lcwlog v0.0.1 h1:SxB+9hsfY8EC1/Y5PrKiFY9aPX1XP2Cvdc6CxhiDrhw= -github.com/lwahlmeier/lcwlog v0.0.1/go.mod h1:gkvtifa+KrERlYm1RobxuHT8sAlK4E4Q4fRcHHDB2DE= -github.com/lwahlmeier/pyfmt v0.0.1 h1:dhSNbX+/oacDsAAMoY32PVLNyt3qFb9KyHthxNsIvPE= -github.com/lwahlmeier/pyfmt v0.0.1/go.mod h1:IczzcvzCJCBjvOtZ3jFtb420GnoTzfgzA5tzgS47Sww= +github.com/lwahlmeier/GoScheduler v1.0.1 h1:n/ITVaSnXIEO761o5JSVG188/51lt+1xoocmqaheWxQ= +github.com/lwahlmeier/GoScheduler v1.0.1/go.mod h1:dypP1694paqSgaD69kytbnNRqRcsx2ogmokbcfgXyac= +github.com/lwahlmeier/lcwlog v0.1.0 h1:rAmgDV8QMy/sUrH70jWxnfdMvzvg9+WHF4LHa135Gy4= +github.com/lwahlmeier/lcwlog v0.1.0/go.mod h1:1OeOKw6wTKuiYn9+MDw5nNx7s6cKyb66/drs+wJD0kI= +github.com/lwahlmeier/pyfmt v0.2.0 h1:MdVYQQb19ZJbpBROuLRtLwj+94Au/EYIZUb6lT1zYN8= +github.com/lwahlmeier/pyfmt v0.2.0/go.mod h1:FzApCDajWuGo3Ww79197mPDNwwdv+ungAHZKRUz5vIg= +github.com/lwahlmeier/unboundChannel v1.0.0 h1:7EN9RTh0W4HZoNActAZAJ/fGQYSYl0n2Eo1t0K0KNQ4= +github.com/lwahlmeier/unboundChannel v1.0.0/go.mod h1:H73PyOLKqEC2LJcfhu7aEVWrxCmlJNu9x+Cqv5dL+9E= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -185,8 +184,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= -github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -497,7 +494,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/fspubsub/FSSubscription.go b/internal/fspubsub/FSSubscription.go index 8bb7532..bf7f483 100644 --- a/internal/fspubsub/FSSubscription.go +++ b/internal/fspubsub/FSSubscription.go @@ -1,6 +1,7 @@ package fspubsub import ( + "context" "errors" "fmt" "io/ioutil" @@ -9,11 +10,13 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "time" "githb.com/lwahlmeier/go-pubsub-emulator/internal/base" - "githb.com/lwahlmeier/go-pubsub-emulator/internal/utils" "github.com/google/uuid" + "github.com/lwahlmeier/GoScheduler" + unboundchannel "github.com/lwahlmeier/unboundChannel" "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -31,8 +34,9 @@ type FSSubscription struct { ackLock sync.Mutex streamClients map[string]*StreamingSubcription clientLock sync.Mutex - msgsChannel *utils.DynamicUUIDChannel - running bool + msgsChannel *unboundchannel.UnboundChannel[uuid.UUID] + running atomic.Bool + cf context.CancelFunc } func CreateSubscription(basePath string, topic *FSTopic, sub *pubsub.Subscription) (*FSSubscription, error) { @@ -58,9 +62,10 @@ func CreateSubscription(basePath string, topic *FSTopic, sub *pubsub.Subscriptio subPath: subPath, pubsubSubscription: sub, streamClients: make(map[string]*StreamingSubcription), - msgsChannel: utils.NewDynamicUUIDChannel(), - running: true, + msgsChannel: unboundchannel.NewUnboundChannel[uuid.UUID](), + running: atomic.Bool{}, } + fsSub.running.Store(true) sfp := fsSub.GetSubFilePath() data, err := proto.Marshal(sub) @@ -72,7 +77,9 @@ func CreateSubscription(basePath string, topic *FSTopic, sub *pubsub.Subscriptio return nil, err } logger.Info("Created Sub:{} for Topic:{} in Project:{}", subName, topic.name, topic.project.name) - go fsSub.watchAcks() + ctx, cf := context.WithCancel(context.Background()) + fsSub.cf = cf + GoScheduler.GetDefaultScheduler().ScheduleWithContext(ack_check_time, true, fsSub.nackMessages, ctx) return fsSub, nil } @@ -83,9 +90,10 @@ func LoadSubscription(subName string, topic *FSTopic) (*FSSubscription, error) { topic: topic, subPath: subPath, streamClients: make(map[string]*StreamingSubcription), - msgsChannel: utils.NewDynamicUUIDChannel(), - running: true, + msgsChannel: unboundchannel.NewUnboundChannel[uuid.UUID](), + running: atomic.Bool{}, } + fsSub.running.Store(true) psSub := &pubsub.Subscription{} fp, err := os.Open(fsSub.GetSubFilePath()) if err != nil { @@ -116,19 +124,12 @@ func LoadSubscription(subName string, topic *FSTopic) (*FSSubscription, error) { fsSub.msgsChannel.Add() <- mid } logger.Info("Loaded Sub:{} for Topic:{} in Project:{}", subName, topic.name, topic.project.name) - go fsSub.watchAcks() + ctx, cf := context.WithCancel(context.Background()) + fsSub.cf = cf + GoScheduler.GetDefaultScheduler().ScheduleWithContext(ack_check_time, true, fsSub.nackMessages, ctx) return fsSub, nil } -func (fss *FSSubscription) watchAcks() { - ackTimer := time.NewTimer(ack_check_time) - for fss.running { - <-ackTimer.C - fss.nackMessages() - ackTimer.Reset(ack_check_time) - } -} - func (fss *FSSubscription) GetTopic() base.BaseTopic { return fss.topic } @@ -146,6 +147,9 @@ func (fss *FSSubscription) GetSubscriptionPubSub() *pubsub.Subscription { } func (fss *FSSubscription) Publish(msg *pubsub.PubsubMessage) { + if !fss.running.Load() { + return + } data, _ := proto.Marshal(msg) tmpPath := path.Join(fss.subPath, fmt.Sprintf("%s.tmp-msg.proto", msg.MessageId)) msgPath := path.Join(fss.subPath, fmt.Sprintf("%s.msg.proto", msg.MessageId)) @@ -157,6 +161,9 @@ func (fss *FSSubscription) Publish(msg *pubsub.PubsubMessage) { } func (fss *FSSubscription) UpdateAcks(ackIds []string, deadline int32) { + if !fss.running.Load() { + return + } doTime := time.Second * time.Duration(deadline) if doTime < time.Second { doTime = time.Duration(0) @@ -179,6 +186,9 @@ func (fss *FSSubscription) UpdateAcks(ackIds []string, deadline int32) { } func (fss *FSSubscription) UpdateAck(ackId string, addTime time.Duration) { + if !fss.running.Load() { + return + } doTime := addTime if addTime < time.Second { doTime = time.Duration(0) @@ -194,10 +204,13 @@ func (fss *FSSubscription) UpdateAck(ackId string, addTime time.Duration) { return } os.Chtimes(msgPath, ackTill, ackTill) - } func (fss *FSSubscription) nackMessages() { + fmt.Println("NACK") + if !fss.running.Load() { + return + } fss.ackLock.Lock() defer fss.ackLock.Unlock() nacks := make([]uuid.UUID, 0) @@ -317,16 +330,18 @@ func (fss *FSSubscription) GetMessages(max int32, maxWait time.Duration) []*pubs } func (fss *FSSubscription) Delete() { - fss.running = false - fss.clientLock.Lock() - defer fss.clientLock.Unlock() - for _, ss := range fss.streamClients { - ss.running = false - ss.streamingServer.Context().Done() - ss.acker.Stop() + if fss.running.CompareAndSwap(true, false) { + fss.clientLock.Lock() + defer fss.clientLock.Unlock() + fss.cf() + for _, ss := range fss.streamClients { + ss.running = false + ss.streamingServer.Context().Done() + ss.acker.Stop() + } + fss.msgsChannel.Stop() + os.RemoveAll(fss.subPath) } - fss.msgsChannel.Stop() - os.RemoveAll(fss.subPath) } func (fss *FSSubscription) CreateStreamingSubscription(firstRecvMsg *pubsub.StreamingPullRequest, streamingServer pubsub.Subscriber_StreamingPullServer) base.BaseStreamingSubcription { @@ -345,7 +360,7 @@ func (fss *FSSubscription) CreateStreamingSubscription(firstRecvMsg *pubsub.Stre deadline: time.Second * time.Duration(firstRecvMsg.StreamAckDeadlineSeconds), running: true, pendingMsgs: make(map[uuid.UUID]bool), - acker: utils.NewDynamicUUIDChannel(), + acker: unboundchannel.NewUnboundChannel[uuid.UUID](), recvChan: make(chan *pubsub.StreamingPullRequest), } fss.clientLock.Lock() @@ -372,7 +387,7 @@ type StreamingSubcription struct { clientId string deadline time.Duration recvChan chan *pubsub.StreamingPullRequest - acker *utils.DynamicUUIDChannel + acker *unboundchannel.UnboundChannel[uuid.UUID] running bool } diff --git a/internal/fspubsub/FSSubscription_test.go b/internal/fspubsub/FSSubscription_test.go index a0b314f..88bbb4c 100644 --- a/internal/fspubsub/FSSubscription_test.go +++ b/internal/fspubsub/FSSubscription_test.go @@ -183,17 +183,20 @@ func TestBasicExpireAck(t *testing.T) { go ss.Run() msgUUID := uuid.NewString() data := []byte("TEST") + fmt.Println("Publish") sub.GetTopic().PublishMessage(&pubsub.PubsubMessage{MessageId: msgUUID, Data: data}) - rmsg := <-tsps.recvChannel + assert.Equal(t, 1, len(rmsg.ReceivedMessages)) assert.Equal(t, data, rmsg.ReceivedMessages[0].Message.Data) tsps.sendChannel <- &pubsub.StreamingPullRequest{ ModifyDeadlineSeconds: []int32{0}, ModifyDeadlineAckIds: []string{msgUUID}, } + fmt.Println("Publish2") time.Sleep(ack_check_time * 2) rmsg = <-tsps.recvChannel + fmt.Println("Publish3") assert.Equal(t, 1, len(rmsg.ReceivedMessages)) assert.Equal(t, data, rmsg.ReceivedMessages[0].Message.Data) tsps.sendChannel <- &pubsub.StreamingPullRequest{ diff --git a/internal/mempubsub/MemSubscription.go b/internal/mempubsub/MemSubscription.go index 2acf34b..aa9b91c 100644 --- a/internal/mempubsub/MemSubscription.go +++ b/internal/mempubsub/MemSubscription.go @@ -1,14 +1,17 @@ package mempubsub import ( + "context" "math" "runtime" "sync" + "sync/atomic" "time" "githb.com/lwahlmeier/go-pubsub-emulator/internal/base" - "githb.com/lwahlmeier/go-pubsub-emulator/internal/utils" "github.com/google/uuid" + "github.com/lwahlmeier/GoScheduler" + unboundchannel "github.com/lwahlmeier/unboundChannel" "google.golang.org/genproto/googleapis/pubsub/v1" ) @@ -40,10 +43,11 @@ type MemSubscription struct { sub *pubsub.Subscription acks map[uuid.UUID]*MsgTime ackLock sync.Mutex - msgChannel *utils.DynamicMsgChannel - running bool + msgChannel *unboundchannel.UnboundChannel[*pubsub.ReceivedMessage] + running atomic.Bool streamClients map[string]*StreamingSubcription clientLock sync.Mutex + cf context.CancelFunc } func NewMemSub(name string, topic *MemTopic, sub *pubsub.Subscription) *MemSubscription { @@ -51,12 +55,15 @@ func NewMemSub(name string, topic *MemTopic, sub *pubsub.Subscription) *MemSubsc name: name, topic: topic, sub: sub, - msgChannel: utils.NewDynamicMsgChannel(), + msgChannel: unboundchannel.NewUnboundChannel[*pubsub.ReceivedMessage](), acks: make(map[uuid.UUID]*MsgTime), streamClients: make(map[string]*StreamingSubcription), - running: true, + running: atomic.Bool{}, } - go ms.watcher() + ms.running.Store(true) + ctx, cf := context.WithCancel(context.Background()) + ms.cf = cf + GoScheduler.GetDefaultScheduler().ScheduleWithContext(ack_check_time, true, ms.checkNack, ctx) logger.Info("Created Sub:{} for Topic:{} and Project:{}", name, topic.name, topic.project.name) return ms } @@ -71,6 +78,9 @@ func (ms *MemSubscription) GetSubscriptionPubSub() *pubsub.Subscription { return ms.sub } func (ms *MemSubscription) UpdateAcks(acks []string, secs int32) { + if !ms.running.Load() { + return + } ms.ackLock.Lock() defer ms.ackLock.Unlock() addTime := time.Second * time.Duration(secs) @@ -82,6 +92,9 @@ func (ms *MemSubscription) UpdateAcks(acks []string, secs int32) { } } func (ms *MemSubscription) UpdateAck(ack string, addTime time.Duration) { + if !ms.running.Load() { + return + } ms.ackLock.Lock() defer ms.ackLock.Unlock() uack := uuid.MustParse(ack) @@ -91,6 +104,9 @@ func (ms *MemSubscription) UpdateAck(ack string, addTime time.Duration) { } func (ms *MemSubscription) AckMessages(acks []string) { + if !ms.running.Load() { + return + } ms.ackLock.Lock() defer ms.ackLock.Unlock() for _, ack := range acks { @@ -148,7 +164,7 @@ func (ms *MemSubscription) CreateStreamingSubscription(firstRecvMsg *pubsub.Stre maxBytes: firstRecvMsg.MaxOutstandingBytes, deadline: time.Second * time.Duration(firstRecvMsg.StreamAckDeadlineSeconds), running: true, - acker: utils.NewDynamicUUIDChannel(), + acker: unboundchannel.NewUnboundChannel[uuid.UUID](), pendingMsgs: make(map[uuid.UUID]bool), recvChan: make(chan *pubsub.StreamingPullRequest), } @@ -170,23 +186,16 @@ func (ms *MemSubscription) DeleteStreamingSubscription(ss *StreamingSubcription) } func (ms *MemSubscription) stop() { - ms.running = false - ms.clientLock.Lock() - defer ms.clientLock.Unlock() - for _, ss := range ms.streamClients { - ss.running = false - ss.streamingServer.Context().Done() - ss.acker.Stop() - } - ms.msgChannel.Stop() -} - -func (ms *MemSubscription) watcher() { - timer := time.NewTimer(ack_check_time) - for ms.running { - <-timer.C - ms.checkNack() - timer.Reset(ack_check_time) + if ms.running.CompareAndSwap(true, false) { + ms.cf() + ms.clientLock.Lock() + defer ms.clientLock.Unlock() + for _, ss := range ms.streamClients { + ss.running = false + ss.streamingServer.Context().Done() + ss.acker.Stop() + } + ms.msgChannel.Stop() } } @@ -235,7 +244,7 @@ type StreamingSubcription struct { maxMsgs int64 maxBytes int64 pendingMsgs map[uuid.UUID]bool - acker *utils.DynamicUUIDChannel + acker *unboundchannel.UnboundChannel[uuid.UUID] currentBytes int64 clientId string deadline time.Duration diff --git a/internal/utils/unbound.go b/internal/utils/unbound.go deleted file mode 100644 index daf337d..0000000 --- a/internal/utils/unbound.go +++ /dev/null @@ -1,126 +0,0 @@ -package utils - -import ( - "github.com/google/uuid" - "google.golang.org/genproto/googleapis/pubsub/v1" -) - -type DynamicUUIDChannel struct { - data []uuid.UUID - inChannel chan uuid.UUID - outChannel chan uuid.UUID - countChannel chan int - running bool -} - -func NewDynamicUUIDChannel() *DynamicUUIDChannel { - duc := &DynamicUUIDChannel{ - data: make([]uuid.UUID, 0, 10), - inChannel: make(chan uuid.UUID, 10), - outChannel: make(chan uuid.UUID, 10), - countChannel: make(chan int), - running: true, - } - go duc.run() - return duc -} - -func (duc *DynamicUUIDChannel) Add() chan<- uuid.UUID { - return duc.inChannel -} - -func (duc *DynamicUUIDChannel) Get() <-chan uuid.UUID { - return duc.outChannel -} - -func (duc *DynamicUUIDChannel) Count() <-chan int { - return duc.countChannel -} - -func (duc *DynamicUUIDChannel) Stop() { - duc.running = false - select { - case <-duc.Count(): - default: - } -} - -func (duc *DynamicUUIDChannel) run() { - for duc.running { - if len(duc.data) > 0 { - select { - case newMsg := <-duc.inChannel: - duc.data = append(duc.data, newMsg) - case duc.outChannel <- duc.data[0]: - duc.data = duc.data[1:] - case duc.countChannel <- len(duc.data) + len(duc.outChannel): - } - } else { - select { - case newStr := <-duc.inChannel: - duc.data = append(duc.data, newStr) - case duc.countChannel <- len(duc.data) + len(duc.outChannel): - } - } - } -} - -type DynamicMsgChannel struct { - data []*pubsub.ReceivedMessage - inChannel chan *pubsub.ReceivedMessage - outChannel chan *pubsub.ReceivedMessage - countChannel chan int - running bool -} - -func NewDynamicMsgChannel() *DynamicMsgChannel { - dsc := &DynamicMsgChannel{ - data: make([]*pubsub.ReceivedMessage, 0, 10), - inChannel: make(chan *pubsub.ReceivedMessage, 10), - outChannel: make(chan *pubsub.ReceivedMessage, 10), - countChannel: make(chan int), - running: true, - } - go dsc.run() - return dsc -} - -func (dmc *DynamicMsgChannel) Add() chan<- *pubsub.ReceivedMessage { - return dmc.inChannel -} - -func (dmc *DynamicMsgChannel) Get() <-chan *pubsub.ReceivedMessage { - return dmc.outChannel -} - -func (dmc *DynamicMsgChannel) Count() <-chan int { - return dmc.countChannel -} - -func (dmc *DynamicMsgChannel) Stop() { - dmc.running = false - select { - case <-dmc.Count(): - default: - } -} - -func (dmc *DynamicMsgChannel) run() { - for dmc.running { - if len(dmc.data) > 0 { - select { - case newMsg := <-dmc.inChannel: - dmc.data = append(dmc.data, newMsg) - case dmc.outChannel <- dmc.data[0]: - dmc.data = dmc.data[1:] - case dmc.countChannel <- len(dmc.data) + len(dmc.outChannel): - } - } else { - select { - case newStr := <-dmc.inChannel: - dmc.data = append(dmc.data, newStr) - case dmc.countChannel <- len(dmc.data) + len(dmc.outChannel): - } - } - } -} diff --git a/internal/utils/unbound_test.go b/internal/utils/unbound_test.go deleted file mode 100644 index fa2bff7..0000000 --- a/internal/utils/unbound_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package utils - -import ( - "fmt" - "math" - "math/rand" - "runtime" - "sync" - "testing" - "time" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "google.golang.org/genproto/googleapis/pubsub/v1" -) - -func TestDynamicUUIDChannel(t *testing.T) { - count := int(math.Max(400, float64(rand.Intn(1000)))) - duc := NewDynamicUUIDChannel() - for i := 0; i < count; i++ { - duc.Add() <- uuid.New() - } - et := time.Now().Add(time.Millisecond * 5) - for time.Until(et) > 0 && count != <-duc.Count() { - runtime.Gosched() - fmt.Println(<-duc.Count()) - fmt.Println(time.Until(et)) - } - assert.Equal(t, count, <-duc.Count()) - waiter := sync.WaitGroup{} - waiter.Add(count) - for i := 0; i < 50; i++ { - go func() { - for { - <-duc.Get() - <-duc.Count() - waiter.Done() - } - }() - } - waiter.Wait() - // <-duc.Count() - assert.Equal(t, 0, <-duc.Count()) - count = int(math.Max(400, float64(rand.Intn(1000)))) - waiter.Add(count) - for i := 0; i < count; i++ { - duc.Add() <- uuid.New() - } - waiter.Wait() - // <-duc.Count() - assert.Equal(t, 0, <-duc.Count()) -} - -func TestDynamicMsgChannel(t *testing.T) { - count := int(math.Max(400, float64(rand.Intn(1000)))) - dmc := NewDynamicMsgChannel() - for i := 0; i < count; i++ { - dmc.Add() <- &pubsub.ReceivedMessage{} - } - et := time.Now().Add(time.Millisecond * 5) - for time.Until(et) > 0 && count != <-dmc.Count() { - runtime.Gosched() - } - assert.Equal(t, count, <-dmc.Count()) - waiter := sync.WaitGroup{} - waiter.Add(count) - for i := 0; i < 50; i++ { - go func() { - for { - <-dmc.Get() - <-dmc.Count() - waiter.Done() - } - }() - } - waiter.Wait() - assert.Equal(t, 0, <-dmc.Count()) - count = int(math.Max(400, float64(rand.Intn(1000)))) - waiter.Add(count) - for i := 0; i < count; i++ { - dmc.Add() <- &pubsub.ReceivedMessage{} - } - waiter.Wait() - assert.Equal(t, 0, <-dmc.Count()) -} diff --git a/vendor/github.com/cornelk/hashmap/.codecov.yml b/vendor/github.com/cornelk/hashmap/.codecov.yml deleted file mode 100644 index dd29ac7..0000000 --- a/vendor/github.com/cornelk/hashmap/.codecov.yml +++ /dev/null @@ -1,7 +0,0 @@ -comment: - layout: header, changes, diff -coverage: - ignore: - - .*.pb.go - status: - patch: false diff --git a/vendor/github.com/cornelk/hashmap/.gitignore b/vendor/github.com/cornelk/hashmap/.gitignore deleted file mode 100644 index 9d36df3..0000000 --- a/vendor/github.com/cornelk/hashmap/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -*.iml -.idea -*.exe diff --git a/vendor/github.com/cornelk/hashmap/.travis.yml b/vendor/github.com/cornelk/hashmap/.travis.yml deleted file mode 100644 index 3fff622..0000000 --- a/vendor/github.com/cornelk/hashmap/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go - -go: - - 1.9.x - - 1.10.x - - 1.11.x - -script: - - go test -race -coverprofile=coverage.txt -covermode=atomic - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/cornelk/hashmap/Gopkg.lock b/vendor/github.com/cornelk/hashmap/Gopkg.lock deleted file mode 100644 index 02bc8b6..0000000 --- a/vendor/github.com/cornelk/hashmap/Gopkg.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/dchest/siphash" - packages = ["."] - revision = "4ebf1de738443ea7f45f02dc394c4df1942a126d" - version = "v1.1.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "f10a62969509b9bc3d1b059eb4888bd35c4b038b7152e682c1c1071be7dff1ba" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/cornelk/hashmap/Gopkg.toml b/vendor/github.com/cornelk/hashmap/Gopkg.toml deleted file mode 100644 index fe544d1..0000000 --- a/vendor/github.com/cornelk/hashmap/Gopkg.toml +++ /dev/null @@ -1,34 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/dchest/siphash" - version = "1.1.0" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/cornelk/hashmap/LICENSE b/vendor/github.com/cornelk/hashmap/LICENSE deleted file mode 100644 index e034cdf..0000000 --- a/vendor/github.com/cornelk/hashmap/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright cornelk - - 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. diff --git a/vendor/github.com/cornelk/hashmap/README.md b/vendor/github.com/cornelk/hashmap/README.md deleted file mode 100644 index 4e7be2f..0000000 --- a/vendor/github.com/cornelk/hashmap/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# hashmap [![Build Status](https://travis-ci.org/cornelk/hashmap.svg?branch=master)](https://travis-ci.org/cornelk/hashmap) [![GoDoc](https://godoc.org/github.com/cornelk/hashmap?status.svg)](https://godoc.org/github.com/cornelk/hashmap) [![Go Report Card](https://goreportcard.com/badge/cornelk/hashmap)](https://goreportcard.com/report/github.com/cornelk/hashmap) [![codecov](https://codecov.io/gh/cornelk/hashmap/branch/master/graph/badge.svg)](https://codecov.io/gh/cornelk/hashmap) - -## Overview - -A Golang lock-free thread-safe HashMap optimized for fastest read access. - -## Usage - -Set a value for a key in the map: - -``` -m := &HashMap{} -m.Set("amount", 123) -``` - -Read a value for a key from the map: -``` -amount, ok := m.Get("amount") -``` - -Use the map to count URL requests: -``` -var i int64 -actual, _ := m.GetOrInsert("api/123", &i) -counter := (actual).(*int64) -atomic.AddInt64(counter, 1) // increase counter -... -count := atomic.LoadInt64(counter) // read counter -``` - -## Benchmarks - -Reading from the hash map in a thread-safe way is nearly as fast as reading from a standard Golang map -in an unsafe way and twice as fast as Go's `sync.Map`: - -``` -BenchmarkReadHashMapUint-8 200000 6830 ns/op -BenchmarkReadGoMapUintUnsafe-8 300000 4280 ns/op -BenchmarkReadGoMapUintMutex-8 30000 51294 ns/op -BenchmarkReadGoSyncMapUint-8 200000 10351 ns/op -``` - -If your keys for the map are already hashes, no extra hashing needs to be done by the map: - -``` -BenchmarkReadHashMapHashedKey-8 1000000 1692 ns/op -``` - -Reading from the map while writes are happening: -``` -BenchmarkReadHashMapWithWritesUint-8 200000 8395 ns/op -BenchmarkReadGoMapWithWritesUintMutex-8 10000 143793 ns/op -BenchmarkReadGoSyncMapWithWritesUint-8 100000 12221 ns/op -``` - -Write performance without any concurrent reads: - -``` -BenchmarkWriteHashMapUint-8 10000 210383 ns/op -BenchmarkWriteGoMapMutexUint-8 30000 53331 ns/op -BenchmarkWriteGoSyncMapUint-8 10000 176903 ns/op -``` - -The benchmarks were run with Golang 1.10.1 on MacOS. - -### Benefits over Golangs builtin map - -* Faster - -* thread-safe access without need of a(n extra) mutex - -* [Compare-and-swap](https://en.wikipedia.org/wiki/Compare-and-swap) access for values - -* Access functions for keys that are hashes and do not need to be hashed again - -### Benefits over [Golangs sync.Map](https://golang.org/pkg/sync/#Map) - -* Faster - -* Access functions for keys that are hashes and do not need to be hashed again - -## Technical details - -* Technical design decisions have been made based on benchmarks that are stored in an external repository: - [go-benchmark](https://github.com/cornelk/go-benchmark) - -* The library uses a sorted doubly linked list and a slice as an index into that list. - -* The Get() function contains helper functions that have been inlined manually until the Golang compiler will inline them automatically. - -* It optimizes the slice access by circumventing the Golang size check when reading from the slice. - Once a slice is allocated, the size of it does not change. - The library limits the index into the slice, therefor the Golang size check is obsolete. - When the slice reaches a defined fill rate, a bigger slice is allocated and all keys are recalculated and transferred into the new slice. diff --git a/vendor/github.com/cornelk/hashmap/hashmap.go b/vendor/github.com/cornelk/hashmap/hashmap.go deleted file mode 100644 index 8033ec6..0000000 --- a/vendor/github.com/cornelk/hashmap/hashmap.go +++ /dev/null @@ -1,435 +0,0 @@ -package hashmap - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "sync/atomic" - "unsafe" -) - -// DefaultSize is the default size for a zero allocated map -const DefaultSize = 8 - -// MaxFillRate is the maximum fill rate for the slice before a resize will happen. -const MaxFillRate = 50 - -type ( - hashMapData struct { - keyshifts uintptr // Pointer size - log2 of array size, to be used as index in the data array - count uintptr // count of filled elements in the slice - data unsafe.Pointer // pointer to slice data array - index []*ListElement // storage for the slice for the garbage collector to not clean it up - } - - // HashMap implements a read optimized hash map. - HashMap struct { - datamap unsafe.Pointer // pointer to a map instance that gets replaced if the map resizes - linkedlist unsafe.Pointer // key sorted linked list of elements - resizing uintptr // flag that marks a resizing operation in progress - } - - // KeyValue represents a key/value that is returned by the iterator. - KeyValue struct { - Key interface{} - Value interface{} - } -) - -// New returns a new HashMap instance with a specific initialization size. -func New(size uintptr) *HashMap { - m := &HashMap{} - m.allocate(size) - return m -} - -// Len returns the number of elements within the map. -func (m *HashMap) Len() int { - list := m.list() - return list.Len() -} - -func (m *HashMap) mapData() *hashMapData { - return (*hashMapData)(atomic.LoadPointer(&m.datamap)) -} - -func (m *HashMap) list() *List { - return (*List)(atomic.LoadPointer(&m.linkedlist)) -} - -func (m *HashMap) allocate(newSize uintptr) { - list := NewList() - // atomic swap in case of another allocation happening concurrently - if atomic.CompareAndSwapPointer(&m.linkedlist, nil, unsafe.Pointer(list)) { - if atomic.CompareAndSwapUintptr(&m.resizing, uintptr(0), uintptr(1)) { - m.grow(newSize, false) - } - } -} - -// Fillrate returns the fill rate of the map as an percentage integer. -func (m *HashMap) Fillrate() uintptr { - data := m.mapData() - count := atomic.LoadUintptr(&data.count) - l := uintptr(len(data.index)) - return (count * 100) / l -} - -func (m *HashMap) resizeNeeded(data *hashMapData, count uintptr) bool { - l := uintptr(len(data.index)) - if l == 0 { - return false - } - fillRate := (count * 100) / l - return fillRate > MaxFillRate -} - -func (m *HashMap) indexElement(hashedKey uintptr) (data *hashMapData, item *ListElement) { - data = m.mapData() - if data == nil { - return nil, nil - } - index := hashedKey >> data.keyshifts - ptr := (*unsafe.Pointer)(unsafe.Pointer(uintptr(data.data) + index*intSizeBytes)) - item = (*ListElement)(atomic.LoadPointer(ptr)) - return data, item -} - -/* The Golang 1.10.1 compiler dons not inline this function well -func (m *HashMap) searchItem(item *ListElement, key interface{}, keyHash uintptr) (value interface{}, ok bool) { - for item != nil { - if item.keyHash == keyHash && item.key == key { - return item.Value(), true - } - - if item.keyHash > keyHash { - return nil, false - } - - item = item.Next() - } - return nil, false -} -*/ - -// Del deletes the key from the map. -func (m *HashMap) Del(key interface{}) { - list := m.list() - if list == nil { - return - } - - h := getKeyHash(key) - - var element *ListElement -ElementLoop: - for _, element = m.indexElement(h); element != nil; element = element.Next() { - if element.keyHash == h { - switch key.(type) { - case []byte: - if bytes.Compare(element.key.([]byte), key.([]byte)) == 0 { - break ElementLoop - } - default: - if element.key == key { - break ElementLoop - } - } - } - - if element.keyHash > h { - return - } - } - if element == nil { - return - } - - m.deleteElement(element) - list.Delete(element) -} - -// DelHashedKey deletes the hashed key from the map. -func (m *HashMap) DelHashedKey(hashedKey uintptr) { - list := m.list() - if list == nil { - return - } - - // inline HashMap.searchItem() - var element *ListElement -ElementLoop: - for _, element = m.indexElement(hashedKey); element != nil; element = element.Next() { - if element.keyHash == hashedKey { - - break ElementLoop - - } - - if element.keyHash > hashedKey { - return - } - } - - if element == nil { - return - } - m.deleteElement(element) - list.Delete(element) -} - -// deleteElement deletes an element from index -func (m *HashMap) deleteElement(element *ListElement) { - for { - data := m.mapData() - index := element.keyHash >> data.keyshifts - ptr := (*unsafe.Pointer)(unsafe.Pointer(uintptr(data.data) + index*intSizeBytes)) - - next := element.Next() - if next != nil && element.keyHash>>data.keyshifts != index { - next = nil // do not set index to next item if it's not the same slice index - } - atomic.CompareAndSwapPointer(ptr, unsafe.Pointer(element), unsafe.Pointer(next)) - - currentdata := m.mapData() - if data == currentdata { // check that no resize happened - break - } - } -} - -// Insert sets the value under the specified key to the map if it does not exist yet. -// If a resizing operation is happening concurrently while calling Set, the item might show up in the map only after the resize operation is finished. -// Returns true if the item was inserted or false if it existed. -func (m *HashMap) Insert(key interface{}, value interface{}) bool { - h := getKeyHash(key) - element := &ListElement{ - key: key, - keyHash: h, - value: unsafe.Pointer(&value), - } - return m.insertListElement(element, false) -} - -// Set sets the value under the specified key to the map. An existing item for this key will be overwritten. -// If a resizing operation is happening concurrently while calling Set, the item might show up in the map only after the resize operation is finished. -func (m *HashMap) Set(key interface{}, value interface{}) { - h := getKeyHash(key) - element := &ListElement{ - key: key, - keyHash: h, - value: unsafe.Pointer(&value), - } - m.insertListElement(element, true) -} - -// SetHashedKey sets the value under the specified hash key to the map. An existing item for this key will be overwritten. -// You can use this function if your keys are already hashes and you want to avoid another hashing of the key. -// Do not use non hashes as keys for this function, the performance would decrease! -// If a resizing operation is happening concurrently while calling Set, the item might show up in the map only after the resize operation is finished. -func (m *HashMap) SetHashedKey(hashedKey uintptr, value interface{}) { - element := &ListElement{ - key: hashedKey, - keyHash: hashedKey, - value: unsafe.Pointer(&value), - } - m.insertListElement(element, true) -} - -func (m *HashMap) insertListElement(element *ListElement, update bool) bool { - for { - data, existing := m.indexElement(element.keyHash) - if data == nil { - m.allocate(DefaultSize) - continue // read mapdata and slice item again - } - list := m.list() - - if update { - if !list.AddOrUpdate(element, existing) { - continue // a concurrent add did interfere, try again - } - } else { - existed, inserted := list.Add(element, existing) - if existed { - return false - } - if !inserted { - continue - } - } - - count := data.addItemToIndex(element) - if m.resizeNeeded(data, count) { - if atomic.CompareAndSwapUintptr(&m.resizing, uintptr(0), uintptr(1)) { - go m.grow(0, true) - } - } - return true - } -} - -// CasHashedKey performs a compare and swap operation sets the value under the specified hash key to the map. An existing item for this key will be overwritten. -func (m *HashMap) CasHashedKey(hashedKey uintptr, from, to interface{}) bool { - data, existing := m.indexElement(hashedKey) - if data == nil { - return false - } - list := m.list() - if list == nil { - return false - } - - element := &ListElement{ - key: hashedKey, - keyHash: hashedKey, - value: unsafe.Pointer(&to), - } - return list.Cas(element, from, existing) -} - -// Cas performs a compare and swap operation sets the value under the specified hash key to the map. An existing item for this key will be overwritten. -func (m *HashMap) Cas(key, from, to interface{}) bool { - h := getKeyHash(key) - return m.CasHashedKey(h, from, to) -} - -// adds an item to the index if needed and returns the new item counter if it changed, otherwise 0 -func (mapData *hashMapData) addItemToIndex(item *ListElement) uintptr { - index := item.keyHash >> mapData.keyshifts - ptr := (*unsafe.Pointer)(unsafe.Pointer(uintptr(mapData.data) + index*intSizeBytes)) - - for { // loop until the smallest key hash is in the index - element := (*ListElement)(atomic.LoadPointer(ptr)) // get the current item in the index - if element == nil { // no item yet at this index - if atomic.CompareAndSwapPointer(ptr, nil, unsafe.Pointer(item)) { - return atomic.AddUintptr(&mapData.count, 1) - } - continue // a new item was inserted concurrently, retry - } - - if item.keyHash < element.keyHash { - // the new item is the smallest for this index? - if !atomic.CompareAndSwapPointer(ptr, unsafe.Pointer(element), unsafe.Pointer(item)) { - continue // a new item was inserted concurrently, retry - } - } - return 0 - } -} - -// Grow resizes the hashmap to a new size, gets rounded up to next power of 2. -// To double the size of the hashmap use newSize 0. -// This function returns immediately, the resize operation is done in a goroutine. -// No resizing is done in case of another resize operation already being in progress. -func (m *HashMap) Grow(newSize uintptr) { - if atomic.CompareAndSwapUintptr(&m.resizing, uintptr(0), uintptr(1)) { - go m.grow(newSize, true) - } -} - -func (m *HashMap) grow(newSize uintptr, loop bool) { - defer atomic.CompareAndSwapUintptr(&m.resizing, uintptr(1), uintptr(0)) - - for { - data := m.mapData() - if newSize == 0 { - newSize = uintptr(len(data.index)) << 1 - } else { - newSize = roundUpPower2(newSize) - } - - index := make([]*ListElement, newSize) - header := (*reflect.SliceHeader)(unsafe.Pointer(&index)) - - newdata := &hashMapData{ - keyshifts: strconv.IntSize - log2(newSize), - data: unsafe.Pointer(header.Data), // use address of slice data storage - index: index, - } - - m.fillIndexItems(newdata) // initialize new index slice with longer keys - - atomic.StorePointer(&m.datamap, unsafe.Pointer(newdata)) - - m.fillIndexItems(newdata) // make sure that the new index is up to date with the current state of the linked list - - if !loop { - break - } - - // check if a new resize needs to be done already - count := uintptr(m.Len()) - if !m.resizeNeeded(newdata, count) { - break - } - newSize = 0 // 0 means double the current size - } -} - -func (m *HashMap) fillIndexItems(mapData *hashMapData) { - list := m.list() - if list == nil { - return - } - first := list.First() - item := first - lastIndex := uintptr(0) - - for item != nil { - index := item.keyHash >> mapData.keyshifts - if item == first || index != lastIndex { // store item with smallest hash key for every index - mapData.addItemToIndex(item) - lastIndex = index - } - item = item.Next() - } -} - -// String returns the map as a string, only hashed keys are printed. -func (m *HashMap) String() string { - list := m.list() - if list == nil { - return "[]" - } - - buffer := bytes.NewBufferString("") - buffer.WriteRune('[') - - first := list.First() - item := first - - for item != nil { - if item != first { - buffer.WriteRune(',') - } - fmt.Fprint(buffer, item.keyHash) - item = item.Next() - } - buffer.WriteRune(']') - return buffer.String() -} - -// Iter returns an iterator which could be used in a for range loop. -// The order of the items is sorted by hash keys. -func (m *HashMap) Iter() <-chan KeyValue { - ch := make(chan KeyValue) // do not use a size here since items can get added during iteration - - go func() { - list := m.list() - if list == nil { - close(ch) - return - } - item := list.First() - for item != nil { - value := item.Value() - ch <- KeyValue{item.key, value} - item = item.Next() - } - close(ch) - }() - - return ch -} diff --git a/vendor/github.com/cornelk/hashmap/hashmap_get.go b/vendor/github.com/cornelk/hashmap/hashmap_get.go deleted file mode 100644 index 3c7d8ff..0000000 --- a/vendor/github.com/cornelk/hashmap/hashmap_get.go +++ /dev/null @@ -1,178 +0,0 @@ -package hashmap - -import ( - "bytes" - "reflect" - "unsafe" - - "github.com/dchest/siphash" -) - -// Get retrieves an element from the map under given hash key. -// Using interface{} adds a performance penalty. -// Please consider using GetUintKey or GetStringKey instead. -func (m *HashMap) Get(key interface{}) (value interface{}, ok bool) { - h := getKeyHash(key) - data, element := m.indexElement(h) - if data == nil { - return nil, false - } - - // inline HashMap.searchItem() - for element != nil { - if element.keyHash == h { - switch key.(type) { - case []byte: - if bytes.Compare(element.key.([]byte), key.([]byte)) == 0 { - return element.Value(), true - } - default: - if element.key == key { - return element.Value(), true - } - } - } - - if element.keyHash > h { - return nil, false - } - - element = element.Next() - } - return nil, false -} - -// GetUintKey retrieves an element from the map under given integer key. -func (m *HashMap) GetUintKey(key uintptr) (value interface{}, ok bool) { - // inline getUintptrHash() - bh := reflect.SliceHeader{ - Data: uintptr(unsafe.Pointer(&key)), - Len: intSizeBytes, - Cap: intSizeBytes, - } - buf := *(*[]byte)(unsafe.Pointer(&bh)) - h := uintptr(siphash.Hash(sipHashKey1, sipHashKey2, buf)) - - data, element := m.indexElement(h) - if data == nil { - return nil, false - } - - // inline HashMap.searchItem() - for element != nil { - if element.keyHash == h && element.key == key { - return element.Value(), true - } - - if element.keyHash > h { - return nil, false - } - - element = element.Next() - } - return nil, false -} - -// GetStringKey retrieves an element from the map under given string key. -func (m *HashMap) GetStringKey(key string) (value interface{}, ok bool) { - // inline getStringHash() - sh := (*reflect.StringHeader)(unsafe.Pointer(&key)) - bh := reflect.SliceHeader{ - Data: sh.Data, - Len: sh.Len, - Cap: sh.Len, - } - buf := *(*[]byte)(unsafe.Pointer(&bh)) - h := uintptr(siphash.Hash(sipHashKey1, sipHashKey2, buf)) - - data, element := m.indexElement(h) - if data == nil { - return nil, false - } - - // inline HashMap.searchItem() - for element != nil { - if element.keyHash == h && element.key == key { - return element.Value(), true - } - - if element.keyHash > h { - return nil, false - } - - element = element.Next() - } - return nil, false -} - -// GetHashedKey retrieves an element from the map under given hashed key. -func (m *HashMap) GetHashedKey(hashedKey uintptr) (value interface{}, ok bool) { - data, element := m.indexElement(hashedKey) - if data == nil { - return nil, false - } - - // inline HashMap.searchItem() - for element != nil { - if element.keyHash == hashedKey { - return element.Value(), true - } - - if element.keyHash > hashedKey { - return nil, false - } - - element = element.Next() - } - return nil, false -} - -// GetOrInsert returns the existing value for the key if present. -// Otherwise, it stores and returns the given value. -// The loaded result is true if the value was loaded, false if stored. -func (m *HashMap) GetOrInsert(key interface{}, value interface{}) (actual interface{}, loaded bool) { - h := getKeyHash(key) - var newelement *ListElement - - for { - data, element := m.indexElement(h) - if data == nil { - m.allocate(DefaultSize) - continue - } - - for element != nil { - if element.keyHash == h { - switch key.(type) { - case []byte: - if bytes.Compare(element.key.([]byte), key.([]byte)) == 0 { - return element.Value(), true - } - default: - if element.key == key { - actual = element.Value() - return actual, true - } - } - } - - if element.keyHash > h { - break - } - - element = element.Next() - } - - if newelement == nil { // allocate only once - newelement = &ListElement{ - key: key, - keyHash: h, - value: unsafe.Pointer(&value), - } - } - - if m.insertListElement(newelement, false) { - return value, false - } - } -} diff --git a/vendor/github.com/cornelk/hashmap/list.go b/vendor/github.com/cornelk/hashmap/list.go deleted file mode 100644 index e51b80f..0000000 --- a/vendor/github.com/cornelk/hashmap/list.go +++ /dev/null @@ -1,181 +0,0 @@ -package hashmap - -import ( - "sync/atomic" - "unsafe" -) - -// List is a sorted doubly linked list. -type List struct { - count uintptr - head *ListElement -} - -// NewList returns an initialized list. -func NewList() *List { - return &List{head: &ListElement{}} -} - -// Len returns the number of elements within the list. -func (l *List) Len() int { - if l == nil { // not initialized yet? - return 0 - } - - return int(atomic.LoadUintptr(&l.count)) -} - -// First returns the head item of the list. -func (l *List) Head() *ListElement { - if l == nil { // not initialized yet? - return nil - } - - return l.head -} - -// First returns the first item of the list. -func (l *List) First() *ListElement { - if l == nil { // not initialized yet? - return nil - } - - return l.head.Next() -} - -// Add adds an item to the list and returns false if an item for the hash existed. -// searchStart = nil will start to search at the head item -func (l *List) Add(element *ListElement, searchStart *ListElement) (existed bool, inserted bool) { - left, found, right := l.search(searchStart, element) - if found != nil { // existing item found - return true, false - } - - return false, l.insertAt(element, left, right) -} - -// AddOrUpdate adds or updates an item to the list. -func (l *List) AddOrUpdate(element *ListElement, searchStart *ListElement) bool { - left, found, right := l.search(searchStart, element) - if found != nil { // existing item found - found.setValue(element.value) // update the value - return true - } - - return l.insertAt(element, left, right) -} - -// Cas compares and swaps the value of an item in the list. -func (l *List) Cas(element *ListElement, oldValue interface{}, searchStart *ListElement) bool { - _, found, _ := l.search(searchStart, element) - if found == nil { // no existing item found - return false - } - - if found.casValue(oldValue, element.value) { - atomic.AddUintptr(&l.count, 1) - return true - } - return false -} - -func (l *List) search(searchStart *ListElement, item *ListElement) (left *ListElement, found *ListElement, right *ListElement) { - if searchStart != nil && item.keyHash < searchStart.keyHash { // key would remain left from item? { - searchStart = nil // start search at head - } - - if searchStart == nil { // start search at head? - left = l.head - found = left.Next() - if found == nil { // no items beside head? - return nil, nil, nil - } - } else { - found = searchStart - } - - for { - if item.keyHash == found.keyHash { // key already exists - return nil, found, nil - } - - if item.keyHash < found.keyHash { // new item needs to be inserted before the found value - if l.head == left { - return nil, nil, found - } - return left, nil, found - } - - // go to next element in sorted linked list - left = found - found = left.Next() - if found == nil { // no more items on the right - return left, nil, nil - } - } -} - -func (l *List) insertAt(element *ListElement, left *ListElement, right *ListElement) bool { - if left == nil { - //element->previous = head - element.previousElement = unsafe.Pointer(l.head) - //element->next = right - element.nextElement = unsafe.Pointer(right) - - // insert at head, head-->next = element - if !atomic.CompareAndSwapPointer(&l.head.nextElement, unsafe.Pointer(right), unsafe.Pointer(element)) { - return false // item was modified concurrently - } - - //right->previous = element - if right != nil { - if !atomic.CompareAndSwapPointer(&right.previousElement, unsafe.Pointer(l.head), unsafe.Pointer(element)) { - return false // item was modified concurrently - } - } - } else { - element.previousElement = unsafe.Pointer(left) - element.nextElement = unsafe.Pointer(right) - - if !atomic.CompareAndSwapPointer(&left.nextElement, unsafe.Pointer(right), unsafe.Pointer(element)) { - return false // item was modified concurrently - } - - if right != nil { - if !atomic.CompareAndSwapPointer(&right.previousElement, unsafe.Pointer(left), unsafe.Pointer(element)) { - return false // item was modified concurrently - } - } - } - - atomic.AddUintptr(&l.count, 1) - return true -} - -// Delete deletes an element from the list. -func (l *List) Delete(element *ListElement) { - if !atomic.CompareAndSwapUintptr(&element.deleted, uintptr(0), uintptr(1)) { - return // concurrent delete of the item in progress - } - - for { - left := element.Previous() - right := element.Next() - - if left == nil { // element is first item in list? - if !atomic.CompareAndSwapPointer(&l.head.nextElement, unsafe.Pointer(element), unsafe.Pointer(right)) { - continue // now head item was inserted concurrently - } - } else { - if !atomic.CompareAndSwapPointer(&left.nextElement, unsafe.Pointer(element), unsafe.Pointer(right)) { - continue // item was modified concurrently - } - } - if right != nil { - atomic.CompareAndSwapPointer(&right.previousElement, unsafe.Pointer(element), unsafe.Pointer(left)) - } - break - } - - atomic.AddUintptr(&l.count, ^uintptr(0)) // decrease counter -} diff --git a/vendor/github.com/cornelk/hashmap/listelement.go b/vendor/github.com/cornelk/hashmap/listelement.go deleted file mode 100644 index b84e0e7..0000000 --- a/vendor/github.com/cornelk/hashmap/listelement.go +++ /dev/null @@ -1,47 +0,0 @@ -package hashmap - -import ( - "sync/atomic" - "unsafe" -) - -// ListElement is an element of a list. -type ListElement struct { - keyHash uintptr - previousElement unsafe.Pointer // is nil for the first item in list - nextElement unsafe.Pointer // is nil for the last item in list - key interface{} - value unsafe.Pointer - deleted uintptr // marks the item as deleting or deleted -} - -// Value returns the value of the list item. -func (e *ListElement) Value() (value interface{}) { - return *(*interface{})(atomic.LoadPointer(&e.value)) -} - -// Next returns the item on the right. -func (e *ListElement) Next() *ListElement { - return (*ListElement)(atomic.LoadPointer(&e.nextElement)) -} - -// Previous returns the item on the left. -func (e *ListElement) Previous() *ListElement { - return (*ListElement)(atomic.LoadPointer(&e.previousElement)) -} - -// setValue sets the value of the item. -// The value needs to be wrapped in unsafe.Pointer already. -func (e *ListElement) setValue(value unsafe.Pointer) { - atomic.StorePointer(&e.value, value) -} - -// casValue compares and swaps the values of the item. -// The to value needs to be wrapped in unsafe.Pointer already. -func (e *ListElement) casValue(from interface{}, to unsafe.Pointer) bool { - old := atomic.LoadPointer(&e.value) - if *(*interface{})(old) != from { - return false - } - return atomic.CompareAndSwapPointer(&e.value, old, to) -} diff --git a/vendor/github.com/cornelk/hashmap/util.go b/vendor/github.com/cornelk/hashmap/util.go deleted file mode 100644 index 8982dfc..0000000 --- a/vendor/github.com/cornelk/hashmap/util.go +++ /dev/null @@ -1,95 +0,0 @@ -package hashmap - -import ( - "fmt" - "reflect" - "strconv" - "unsafe" - - "github.com/dchest/siphash" -) - -const ( - // intSizeBytes is the size in byte of an int or uint value. - intSizeBytes = strconv.IntSize >> 3 - - // generated by splitting the md5 sum of "hashmap" - sipHashKey1 = 0xdda7806a4847ec61 - sipHashKey2 = 0xb5940c2623a5aabd -) - -// roundUpPower2 rounds a number to the next power of 2. -func roundUpPower2(i uintptr) uintptr { - i-- - i |= i >> 1 - i |= i >> 2 - i |= i >> 4 - i |= i >> 8 - i |= i >> 16 - i |= i >> 32 - i++ - return i -} - -// log2 computes the binary logarithm of x, rounded up to the next integer. -func log2(i uintptr) uintptr { - var n, p uintptr - for p = 1; p < i; p += p { - n++ - } - return n -} - -// getKeyHash returns a hash for the key. Only string and number types are supported. -func getKeyHash(key interface{}) uintptr { - switch x := key.(type) { - case string: - return getStringHash(x) - case []byte: - return uintptr(siphash.Hash(sipHashKey1, sipHashKey2, x)) - case int: - return getUintptrHash(uintptr(x)) - case int8: - return getUintptrHash(uintptr(x)) - case int16: - return getUintptrHash(uintptr(x)) - case int32: - return getUintptrHash(uintptr(x)) - case int64: - return getUintptrHash(uintptr(x)) - case uint: - return getUintptrHash(uintptr(x)) - case uint8: - return getUintptrHash(uintptr(x)) - case uint16: - return getUintptrHash(uintptr(x)) - case uint32: - return getUintptrHash(uintptr(x)) - case uint64: - return getUintptrHash(uintptr(x)) - case uintptr: - return getUintptrHash(x) - } - panic(fmt.Errorf("unsupported key type %T", key)) -} - -func getStringHash(s string) uintptr { - sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) - bh := reflect.SliceHeader{ - Data: sh.Data, - Len: sh.Len, - Cap: sh.Len, - } - buf := *(*[]byte)(unsafe.Pointer(&bh)) - return uintptr(siphash.Hash(sipHashKey1, sipHashKey2, buf)) -} - -func getUintptrHash(num uintptr) uintptr { - bh := reflect.SliceHeader{ - Data: uintptr(unsafe.Pointer(&num)), - Len: intSizeBytes, - Cap: intSizeBytes, - } - buf := *(*[]byte)(unsafe.Pointer(&bh)) - return uintptr(siphash.Hash(sipHashKey1, sipHashKey2, buf)) -} diff --git a/vendor/github.com/dchest/siphash/.travis.yml b/vendor/github.com/dchest/siphash/.travis.yml deleted file mode 100644 index f15b751..0000000 --- a/vendor/github.com/dchest/siphash/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go - -go: - - 1.4 - - 1.5 - - 1.7 - - tip diff --git a/vendor/github.com/dchest/siphash/README.md b/vendor/github.com/dchest/siphash/README.md deleted file mode 100644 index a3645e1..0000000 --- a/vendor/github.com/dchest/siphash/README.md +++ /dev/null @@ -1,69 +0,0 @@ -SipHash (Go) -============ - -[![Build Status](https://travis-ci.org/dchest/siphash.svg)](https://travis-ci.org/dchest/siphash) - -Go implementation of SipHash-2-4, a fast short-input PRF created by -Jean-Philippe Aumasson and Daniel J. Bernstein (http://131002.net/siphash/). - - -## Installation - - $ go get github.com/dchest/siphash - -## Usage - - import "github.com/dchest/siphash" - -There are two ways to use this package. -The slower one is to use the standard hash.Hash64 interface: - - h := siphash.New(key) - h.Write([]byte("Hello")) - sum := h.Sum(nil) // returns 8-byte []byte - -or - - sum64 := h.Sum64() // returns uint64 - -The faster one is to use Hash() function, which takes two uint64 parts of -16-byte key and a byte slice, and returns uint64 hash: - - sum64 := siphash.Hash(key0, key1, []byte("Hello")) - -The keys and output are little-endian. - - -## Functions - -### func Hash(k0, k1 uint64, p []byte) uint64 - -Hash returns the 64-bit SipHash-2-4 of the given byte slice with two -64-bit parts of 128-bit key: k0 and k1. - -### func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) - -Hash128 returns the 128-bit SipHash-2-4 of the given byte slice with two -64-bit parts of 128-bit key: k0 and k1. - -Note that 128-bit SipHash is considered experimental by SipHash authors at this time. - -### func New(key []byte) hash.Hash64 - -New returns a new hash.Hash64 computing SipHash-2-4 with 16-byte key. - -### func New128(key []byte) hash.Hash - -New128 returns a new hash.Hash computing SipHash-2-4 with 16-byte key and 16-byte output. - -Note that 16-byte output is considered experimental by SipHash authors at this time. - - -## Public domain dedication - -Written by Dmitry Chestnykh and Damian Gryski. - -To the extent possible under law, the authors have dedicated all copyright -and related and neighboring rights to this software to the public domain -worldwide. This software is distributed without any warranty. -http://creativecommons.org/publicdomain/zero/1.0/ diff --git a/vendor/github.com/dchest/siphash/blocks.go b/vendor/github.com/dchest/siphash/blocks.go deleted file mode 100644 index 817b215..0000000 --- a/vendor/github.com/dchest/siphash/blocks.go +++ /dev/null @@ -1,148 +0,0 @@ -// +build !arm,!amd64 appengine gccgo - -package siphash - -func once(d *digest) { - blocks(d, d.x[:]) -} - -func finalize(d *digest) uint64 { - d0 := *d - once(&d0) - - v0, v1, v2, v3 := d0.v0, d0.v1, d0.v2, d0.v3 - v2 ^= 0xff - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - return v0 ^ v1 ^ v2 ^ v3 -} - -func blocks(d *digest, p []uint8) { - v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 - - for len(p) >= BlockSize { - m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | - uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 - - v3 ^= m - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= m - - p = p[BlockSize:] - } - - d.v0, d.v1, d.v2, d.v3 = v0, v1, v2, v3 -} diff --git a/vendor/github.com/dchest/siphash/blocks_amd64.s b/vendor/github.com/dchest/siphash/blocks_amd64.s deleted file mode 100644 index 2d4816f..0000000 --- a/vendor/github.com/dchest/siphash/blocks_amd64.s +++ /dev/null @@ -1,86 +0,0 @@ -// +build amd64,!appengine,!gccgo - -#define ROUND(v0, v1, v2, v3) \ - ADDQ v1, v0; \ - RORQ $51, v1; \ - ADDQ v3, v2; \ - XORQ v0, v1; \ - RORQ $48, v3; \ - RORQ $32, v0; \ - XORQ v2, v3; \ - ADDQ v1, v2; \ - ADDQ v3, v0; \ - RORQ $43, v3; \ - RORQ $47, v1; \ - XORQ v0, v3; \ - XORQ v2, v1; \ - RORQ $32, v2 - -// blocks(d *digest, data []uint8) -TEXT ·blocks(SB),4,$0-32 - MOVQ d+0(FP), BX - MOVQ 0(BX), R9 // R9 = v0 - MOVQ 8(BX), R10 // R10 = v1 - MOVQ 16(BX), R11 // R11 = v2 - MOVQ 24(BX), R12 // R12 = v3 - MOVQ p_base+8(FP), DI // DI = *uint64 - MOVQ p_len+16(FP), SI // SI = nblocks - XORL DX, DX // DX = index (0) - SHRQ $3, SI // SI /= 8 -body: - CMPQ DX, SI - JGE end - MOVQ 0(DI)(DX*8), CX // CX = m - XORQ CX, R12 - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - XORQ CX, R9 - ADDQ $1, DX - JMP body -end: - MOVQ R9, 0(BX) - MOVQ R10, 8(BX) - MOVQ R11, 16(BX) - MOVQ R12, 24(BX) - RET - -// once(d *digest) -TEXT ·once(SB),4,$0-8 - MOVQ d+0(FP), BX - MOVQ 0(BX), R9 // R9 = v0 - MOVQ 8(BX), R10 // R10 = v1 - MOVQ 16(BX), R11 // R11 = v2 - MOVQ 24(BX), R12 // R12 = v3 - MOVQ 48(BX), CX // CX = d.x[:] - XORQ CX, R12 - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - XORQ CX, R9 - MOVQ R9, 0(BX) - MOVQ R10, 8(BX) - MOVQ R11, 16(BX) - MOVQ R12, 24(BX) - RET - -// finalize(d *digest) uint64 -TEXT ·finalize(SB),4,$0-16 - MOVQ d+0(FP), BX - MOVQ 0(BX), R9 // R9 = v0 - MOVQ 8(BX), R10 // R10 = v1 - MOVQ 16(BX), R11 // R11 = v2 - MOVQ 24(BX), R12 // R12 = v3 - MOVQ 48(BX), CX // CX = d.x[:] - XORQ CX, R12 - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - XORQ CX, R9 - NOTB R11 - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - ROUND(R9, R10, R11, R12) - XORQ R12, R11 - XORQ R10, R9 - XORQ R11, R9 - MOVQ R9, ret+8(FP) - RET diff --git a/vendor/github.com/dchest/siphash/blocks_arm.s b/vendor/github.com/dchest/siphash/blocks_arm.s deleted file mode 100644 index 42dcd23..0000000 --- a/vendor/github.com/dchest/siphash/blocks_arm.s +++ /dev/null @@ -1,144 +0,0 @@ -#include "textflag.h" -#define R10 g -#define ROUND()\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<13,R0,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R1,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R4,R4;\ - ADC R7,R5,R5;\ - EOR R6<<16,R4,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R5,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<21,R1,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R0,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R4,R4;\ - ADC R11,R5,R5;\ - EOR R8<<17,R4,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R5,R3;\ - EOR R11<<17,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<13,R1,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R0,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R5,R5;\ - ADC R7,R4,R4;\ - EOR R6<<16,R5,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R4,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<21,R0,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R1,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R5,R5;\ - ADC R11,R4,R4;\ - EOR R8<<17,R5,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R4,R3;\ - EOR R11<<17,R3,R3;\ - -// once(d *digest) -TEXT ·once(SB),NOSPLIT,$4-4 - MOVW d+0(FP),R8 - MOVM.IA (R8),[R0,R1,R2,R3,R4,R5,R6,R7] - MOVW 48(R8),R12 - MOVW 52(R8),R14 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - MOVW d+0(FP),R8 - MOVM.IA [R0,R1,R2,R3,R4,R5,R6,R7],(R8) - RET - -// finalize(d *digest) uint64 -TEXT ·finalize(SB),NOSPLIT,$4-12 - MOVW d+0(FP),R8 - MOVM.IA (R8),[R0,R1,R2,R3,R4,R5,R6,R7] - MOVW 48(R8),R12 - MOVW 52(R8),R14 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - EOR $255,R4 - ROUND() - ROUND() - EOR R2,R0,R0 - EOR R3,R1,R1 - EOR R6,R4,R4 - EOR R7,R5,R5 - EOR R4,R0,R0 - EOR R5,R1,R1 - MOVW R0,ret_lo+4(FP) - MOVW R1,ret_hi+8(FP) - RET - -// blocks(d *digest, data []uint8) -TEXT ·blocks(SB),NOSPLIT,$8-16 - MOVW R10,sav-8(SP) - MOVW d+0(FP),R8 - MOVM.IA (R8),[R0,R1,R2,R3,R4,R5,R6,R7] - MOVW p+4(FP),R10 - MOVW p_len+8(FP),R11 - ADD R10,R11,R11 - MOVW R11,endp-4(SP) - AND.S $3,R10,R8 - BNE blocksunaligned -blocksloop: - MOVM.IA.W (R10),[R12,R14] - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - MOVW endp-4(SP),R11 - CMP R11,R10 - BLO blocksloop - MOVW d+0(FP),R8 - MOVM.IA [R0,R1,R2,R3,R4,R5,R6,R7],(R8) - MOVW sav-8(SP),R10 - RET -blocksunaligned: - MOVB (R10),R12 - MOVB 1(R10),R11 - ORR R11<<8,R12,R12 - MOVB 2(R10),R11 - ORR R11<<16,R12,R12 - MOVB 3(R10),R11 - ORR R11<<24,R12,R12 - MOVB 4(R10),R14 - MOVB 5(R10),R11 - ORR R11<<8,R14,R14 - MOVB 6(R10),R11 - ORR R11<<16,R14,R14 - MOVB 7(R10),R11 - ORR R11<<24,R14,R14 - ADD $8,R10,R10 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - MOVW endp-4(SP),R11 - CMP R11,R10 - BLO blocksunaligned - MOVW d+0(FP),R8 - MOVM.IA [R0,R1,R2,R3,R4,R5,R6,R7],(R8) - MOVW sav-8(SP),R10 - RET diff --git a/vendor/github.com/dchest/siphash/hash.go b/vendor/github.com/dchest/siphash/hash.go deleted file mode 100644 index 0de28d0..0000000 --- a/vendor/github.com/dchest/siphash/hash.go +++ /dev/null @@ -1,216 +0,0 @@ -// +build !arm,!amd64 appengine gccgo - -// Written in 2012 by Dmitry Chestnykh. -// -// To the extent possible under law, the author have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -package siphash - -// Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit -// parts of 128-bit key: k0 and k1. -func Hash(k0, k1 uint64, p []byte) uint64 { - // Initialization. - v0 := k0 ^ 0x736f6d6570736575 - v1 := k1 ^ 0x646f72616e646f6d - v2 := k0 ^ 0x6c7967656e657261 - v3 := k1 ^ 0x7465646279746573 - t := uint64(len(p)) << 56 - - // Compression. - for len(p) >= BlockSize { - m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | - uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 - v3 ^= m - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= m - p = p[BlockSize:] - } - - // Compress last block. - switch len(p) { - case 7: - t |= uint64(p[6]) << 48 - fallthrough - case 6: - t |= uint64(p[5]) << 40 - fallthrough - case 5: - t |= uint64(p[4]) << 32 - fallthrough - case 4: - t |= uint64(p[3]) << 24 - fallthrough - case 3: - t |= uint64(p[2]) << 16 - fallthrough - case 2: - t |= uint64(p[1]) << 8 - fallthrough - case 1: - t |= uint64(p[0]) - } - - v3 ^= t - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= t - - // Finalization. - v2 ^= 0xff - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - return v0 ^ v1 ^ v2 ^ v3 -} diff --git a/vendor/github.com/dchest/siphash/hash128.go b/vendor/github.com/dchest/siphash/hash128.go deleted file mode 100644 index 634ce57..0000000 --- a/vendor/github.com/dchest/siphash/hash128.go +++ /dev/null @@ -1,302 +0,0 @@ -// +build !arm,!amd64 appengine gccgo -// Written in 2012 by Dmitry Chestnykh. -// Modifications 2014 for 128-bit hash function by Damian Gryski. -// -// To the extent possible under law, the authors have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -package siphash - -// Hash returns the 128-bit SipHash-2-4 of the given byte slice with two 64-bit -// parts of 128-bit key: k0 and k1. -// -// Note that 128-bit SipHash is considered experimental by SipHash authors at this time. -func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) { - // Initialization. - v0 := k0 ^ 0x736f6d6570736575 - v1 := k1 ^ 0x646f72616e646f6d - v2 := k0 ^ 0x6c7967656e657261 - v3 := k1 ^ 0x7465646279746573 - t := uint64(len(p)) << 56 - - v1 ^= 0xee - - // Compression. - for len(p) >= BlockSize { - m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | - uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 - v3 ^= m - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= m - p = p[BlockSize:] - } - - // Compress last block. - switch len(p) { - case 7: - t |= uint64(p[6]) << 48 - fallthrough - case 6: - t |= uint64(p[5]) << 40 - fallthrough - case 5: - t |= uint64(p[4]) << 32 - fallthrough - case 4: - t |= uint64(p[3]) << 24 - fallthrough - case 3: - t |= uint64(p[2]) << 16 - fallthrough - case 2: - t |= uint64(p[1]) << 8 - fallthrough - case 1: - t |= uint64(p[0]) - } - - v3 ^= t - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= t - - // Finalization. - v2 ^= 0xee - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - r0 := v0 ^ v1 ^ v2 ^ v3 - - v1 ^= 0xdd - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - r1 := v0 ^ v1 ^ v2 ^ v3 - - return r0, r1 -} diff --git a/vendor/github.com/dchest/siphash/hash128_amd64.s b/vendor/github.com/dchest/siphash/hash128_amd64.s deleted file mode 100644 index 86605cc..0000000 --- a/vendor/github.com/dchest/siphash/hash128_amd64.s +++ /dev/null @@ -1,292 +0,0 @@ -// +build amd64,!appengine,!gccgo - -// This is a translation of the gcc output of FloodyBerry's pure-C public -// domain siphash implementation at https://github.com/floodyberry/siphash - -// This assembly code has been modified from the 64-bit output to the experiment 128-bit output. - -// SI = v0 -// AX = v1 -// CX = v2 -// DX = v3 - -// func Hash128(k0, k1 uint64, b []byte) (r0 uint64, r1 uint64) -TEXT ·Hash128(SB),4,$0-56 - MOVQ k0+0(FP),CX - MOVQ $0x736F6D6570736575,R9 - MOVQ k1+8(FP),DI - MOVQ $0x6C7967656E657261,BX - MOVQ $0x646F72616E646F6D,AX - MOVQ b_len+24(FP),DX - XORQ $0xEE,AX - MOVQ DX,R11 - MOVQ DX,R10 - XORQ CX,R9 - XORQ CX,BX - MOVQ $0x7465646279746573,CX - XORQ DI,AX - XORQ DI,CX - SHLQ $0x38,R11 - XORQ DI,DI - MOVQ b_base+16(FP),SI - ANDQ $0xFFFFFFFFFFFFFFF8,R10 - JE afterLoop - XCHGQ AX,AX -loopBody: - MOVQ 0(SI)(DI*1),R8 - ADDQ AX,R9 - RORQ $0x33,AX - XORQ R9,AX - RORQ $0x20,R9 - ADDQ $0x8,DI - XORQ R8,CX - ADDQ CX,BX - RORQ $0x30,CX - XORQ BX,CX - ADDQ AX,BX - RORQ $0x2F,AX - ADDQ CX,R9 - RORQ $0x2B,CX - XORQ BX,AX - XORQ R9,CX - RORQ $0x20,BX - ADDQ AX,R9 - ADDQ CX,BX - RORQ $0x33,AX - RORQ $0x30,CX - XORQ R9,AX - XORQ BX,CX - RORQ $0x20,R9 - ADDQ AX,BX - ADDQ CX,R9 - RORQ $0x2F,AX - RORQ $0x2B,CX - XORQ BX,AX - RORQ $0x20,BX - XORQ R9,CX - XORQ R8,R9 - CMPQ R10,DI - JA loopBody -afterLoop: - SUBQ R10,DX - - CMPQ DX,$0x7 - JA afterSwitch - - // no support for jump tables - - CMPQ DX,$0x7 - JE sw7 - - CMPQ DX,$0x6 - JE sw6 - - CMPQ DX,$0x5 - JE sw5 - - CMPQ DX,$0x4 - JE sw4 - - CMPQ DX,$0x3 - JE sw3 - - CMPQ DX,$0x2 - JE sw2 - - CMPQ DX,$0x1 - JE sw1 - - JMP afterSwitch - -sw7: MOVBQZX 6(SI)(DI*1),DX - SHLQ $0x30,DX - ORQ DX,R11 -sw6: MOVBQZX 0x5(SI)(DI*1),DX - SHLQ $0x28,DX - ORQ DX,R11 -sw5: MOVBQZX 0x4(SI)(DI*1),DX - SHLQ $0x20,DX - ORQ DX,R11 -sw4: MOVBQZX 0x3(SI)(DI*1),DX - SHLQ $0x18,DX - ORQ DX,R11 -sw3: MOVBQZX 0x2(SI)(DI*1),DX - SHLQ $0x10,DX - ORQ DX,R11 -sw2: MOVBQZX 0x1(SI)(DI*1),DX - SHLQ $0x8,DX - ORQ DX,R11 -sw1: MOVBQZX 0(SI)(DI*1),DX - ORQ DX,R11 -afterSwitch: - LEAQ (AX)(R9*1),SI - XORQ R11,CX - RORQ $0x33,AX - ADDQ CX,BX - MOVQ CX,DX - XORQ SI,AX - RORQ $0x30,DX - RORQ $0x20,SI - LEAQ 0(BX)(AX*1),CX - XORQ BX,DX - RORQ $0x2F,AX - ADDQ DX,SI - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - XORQ SI,AX - RORQ $0x30,DX - RORQ $0x20,SI - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - ADDQ DX,SI - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ SI,DX - XORQ R11,SI - XORB $0xEE,CL - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - RORQ $0x30,DX - XORQ SI,AX - XORQ CX,DX - RORQ $0x20,SI - ADDQ AX,CX - ADDQ DX,SI - RORQ $0x2F,AX - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ SI,AX - RORQ $0x20,SI - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - ADDQ DX,SI - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ CX,DX - XORQ SI,AX - RORQ $0x20,SI - ADDQ DX,SI - ADDQ AX,CX - RORQ $0x2F,AX - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ SI,DX - - // gcc optimized the tail end of this function differently. However, - // we need to preserve out registers to carry out the second stage of - // the finalization. This is a duplicate of an earlier finalization - // round. - - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - RORQ $0x30,DX - XORQ SI,AX - XORQ CX,DX - RORQ $0x20,SI - ADDQ AX,CX - ADDQ DX,SI - RORQ $0x2F,AX - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - - // Stuff the result into BX instead of AX as gcc had done - - MOVQ SI,BX - XORQ AX,BX - XORQ DX,BX - XORQ CX,BX - MOVQ BX,ret+40(FP) - - // Start the second finalization round - - XORB $0xDD,AL - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - RORQ $0x30,DX - XORQ SI,AX - XORQ CX,DX - RORQ $0x20,SI - ADDQ AX,CX - ADDQ DX,SI - RORQ $0x2F,AX - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ SI,AX - RORQ $0x20,SI - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - ADDQ DX,SI - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ CX,DX - XORQ SI,AX - RORQ $0x20,SI - ADDQ DX,SI - ADDQ AX,CX - RORQ $0x2F,AX - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ SI,DX - - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - RORQ $0x30,DX - XORQ SI,AX - XORQ CX,DX - RORQ $0x20,SI - ADDQ AX,CX - ADDQ DX,SI - RORQ $0x2F,AX - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - - MOVQ SI,BX - XORQ AX,BX - XORQ DX,BX - XORQ CX,BX - MOVQ BX,ret1+48(FP) - - RET diff --git a/vendor/github.com/dchest/siphash/hash128_arm.s b/vendor/github.com/dchest/siphash/hash128_arm.s deleted file mode 100644 index eca3529..0000000 --- a/vendor/github.com/dchest/siphash/hash128_arm.s +++ /dev/null @@ -1,169 +0,0 @@ -#include "textflag.h" -#define R10 g -#define ROUND()\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<13,R0,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R1,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R4,R4;\ - ADC R7,R5,R5;\ - EOR R6<<16,R4,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R5,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<21,R1,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R0,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R4,R4;\ - ADC R11,R5,R5;\ - EOR R8<<17,R4,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R5,R3;\ - EOR R11<<17,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<13,R1,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R0,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R5,R5;\ - ADC R7,R4,R4;\ - EOR R6<<16,R5,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R4,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<21,R0,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R1,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R5,R5;\ - ADC R11,R4,R4;\ - EOR R8<<17,R5,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R4,R3;\ - EOR R11<<17,R3,R3;\ - -// Hash128(k0, k1 uint64, b []byte) (uint64, uint64) -TEXT ·Hash128(SB),NOSPLIT,$8-44 - MOVW R10,sav-8(SP) - MOVW k0_lo+0(FP),R12 - MOVW k0_hi+4(FP),R14 - MOVW $0x70736575,R0 - MOVW $0x736f6d65,R1 - MOVW $0x6e657261,R4 - MOVW $0x6c796765,R5 - EOR R12,R0,R0 - EOR R14,R1,R1 - EOR R12,R4,R4 - EOR R14,R5,R5 - MOVW k1_lo+8(FP),R12 - MOVW k1_hi+12(FP),R14 - MOVW $0x6e646f83,R2 - MOVW $0x646f7261,R3 - MOVW $0x79746573,R6 - MOVW $0x74656462,R7 - EOR R12,R2,R2 - EOR R14,R3,R3 - EOR R12,R6,R6 - EOR R14,R7,R7 - MOVW b+16(FP),R10 - MOVW b_len+20(FP),R11 - ADD R10,R11,R11 - MOVW R11,endb-4(SP) -hashloop128: - MOVW endb-4(SP),R11 - SUB R10,R11,R11 - SUB.S $8,R11 - BLO hashend128 - MOVM.IA.W (R10),[R12,R14] - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - B hashloop128 -hashloop128unaligned: - MOVW endb-4(SP),R11 - SUB R10,R11,R11 - SUB.S $8,R11 - BLO hashend128 - MOVB (R10),R12 - MOVB 1(R10),R11 - ORR R11<<8,R12,R12 - MOVB 2(R10),R11 - ORR R11<<16,R12,R12 - MOVB 3(R10),R11 - ORR R11<<24,R12,R12 - MOVB 4(R10),R14 - MOVB 5(R10),R11 - ORR R11<<8,R14,R14 - MOVB 6(R10),R11 - ORR R11<<16,R14,R14 - MOVB 7(R10),R11 - ORR R11<<24,R14,R14 - ADD $8,R10,R10 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - B hashloop128unaligned -hashend128: - MOVW $0x0,R12 - MOVW $0x0,R14 - RSB $0,R11,R11 - AND.S $7,R11 - BEQ hashlast128 - MOVW (R10),R12 - SLL $3,R11 - AND $63,R11 - SUB.S $32,R11,R11 - BEQ hashlast128 - BLO hashhi128 - MOVW R12<>R11,R12 - B hashlast128 -hashhi128: - ADD $32,R11 - MOVW 4(R10),R14 - MOVW R14<>R11,R14 -hashlast128: - MOVW b_len+20(FP),R11 - ORR R11<<24,R14,R14 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - EOR $238,R4 - ROUND() - ROUND() - EOR R0,R2,R12 - EOR R1,R3,R14 - EOR R4,R12,R12 - EOR R5,R14,R14 - EOR R6,R12,R12 - EOR R7,R14,R14 - MOVW R12,ret_lo+28(FP) - MOVW R14,ret_hi+32(FP) - EOR $221,R2 - ROUND() - ROUND() - EOR R0,R2,R12 - EOR R1,R3,R14 - EOR R4,R12,R12 - EOR R5,R14,R14 - EOR R6,R12,R12 - EOR R7,R14,R14 - MOVW R12,unnamed_lo+36(FP) - MOVW R14,unnamed_hi+40(FP) - MOVW sav-8(SP),R10 - RET diff --git a/vendor/github.com/dchest/siphash/hash_amd64.s b/vendor/github.com/dchest/siphash/hash_amd64.s deleted file mode 100644 index 0ca1631..0000000 --- a/vendor/github.com/dchest/siphash/hash_amd64.s +++ /dev/null @@ -1,201 +0,0 @@ -// +build amd64,!appengine,!gccgo - -// This is a translation of the gcc output of FloodyBerry's pure-C public -// domain siphash implementation at https://github.com/floodyberry/siphash -// func Hash(k0, k1 uint64, b []byte) uint64 -TEXT ·Hash(SB),4,$0-48 - MOVQ k0+0(FP),CX - MOVQ $0x736F6D6570736575,R9 - MOVQ k1+8(FP),DI - MOVQ $0x6C7967656E657261,BX - MOVQ $0x646F72616E646F6D,AX - MOVQ b_len+24(FP),DX - MOVQ DX,R11 - MOVQ DX,R10 - XORQ CX,R9 - XORQ CX,BX - MOVQ $0x7465646279746573,CX - XORQ DI,AX - XORQ DI,CX - SHLQ $0x38,R11 - XORQ DI,DI - MOVQ b_base+16(FP),SI - ANDQ $0xFFFFFFFFFFFFFFF8,R10 - JE afterLoop - XCHGQ AX,AX -loopBody: - MOVQ 0(SI)(DI*1),R8 - ADDQ AX,R9 - RORQ $0x33,AX - XORQ R9,AX - RORQ $0x20,R9 - ADDQ $0x8,DI - XORQ R8,CX - ADDQ CX,BX - RORQ $0x30,CX - XORQ BX,CX - ADDQ AX,BX - RORQ $0x2F,AX - ADDQ CX,R9 - RORQ $0x2B,CX - XORQ BX,AX - XORQ R9,CX - RORQ $0x20,BX - ADDQ AX,R9 - ADDQ CX,BX - RORQ $0x33,AX - RORQ $0x30,CX - XORQ R9,AX - XORQ BX,CX - RORQ $0x20,R9 - ADDQ AX,BX - ADDQ CX,R9 - RORQ $0x2F,AX - RORQ $0x2B,CX - XORQ BX,AX - RORQ $0x20,BX - XORQ R9,CX - XORQ R8,R9 - CMPQ R10,DI - JA loopBody -afterLoop: - SUBQ R10,DX - - CMPQ DX,$0x7 - JA afterSwitch - - // no support for jump tables - - CMPQ DX,$0x7 - JE sw7 - - CMPQ DX,$0x6 - JE sw6 - - CMPQ DX,$0x5 - JE sw5 - - CMPQ DX,$0x4 - JE sw4 - - CMPQ DX,$0x3 - JE sw3 - - CMPQ DX,$0x2 - JE sw2 - - CMPQ DX,$0x1 - JE sw1 - - JMP afterSwitch - -sw7: MOVBQZX 6(SI)(DI*1),DX - SHLQ $0x30,DX - ORQ DX,R11 -sw6: MOVBQZX 0x5(SI)(DI*1),DX - SHLQ $0x28,DX - ORQ DX,R11 -sw5: MOVBQZX 0x4(SI)(DI*1),DX - SHLQ $0x20,DX - ORQ DX,R11 -sw4: MOVBQZX 0x3(SI)(DI*1),DX - SHLQ $0x18,DX - ORQ DX,R11 -sw3: MOVBQZX 0x2(SI)(DI*1),DX - SHLQ $0x10,DX - ORQ DX,R11 -sw2: MOVBQZX 0x1(SI)(DI*1),DX - SHLQ $0x8,DX - ORQ DX,R11 -sw1: MOVBQZX 0(SI)(DI*1),DX - ORQ DX,R11 -afterSwitch: - LEAQ (AX)(R9*1),SI - XORQ R11,CX - RORQ $0x33,AX - ADDQ CX,BX - MOVQ CX,DX - XORQ SI,AX - RORQ $0x30,DX - RORQ $0x20,SI - LEAQ 0(BX)(AX*1),CX - XORQ BX,DX - RORQ $0x2F,AX - ADDQ DX,SI - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - XORQ SI,AX - RORQ $0x30,DX - RORQ $0x20,SI - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - ADDQ DX,SI - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ SI,DX - XORQ R11,SI - XORB $0xFF,CL - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - RORQ $0x30,DX - XORQ SI,AX - XORQ CX,DX - RORQ $0x20,SI - ADDQ AX,CX - ADDQ DX,SI - RORQ $0x2F,AX - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ SI,AX - RORQ $0x20,SI - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - ADDQ DX,SI - RORQ $0x2B,DX - XORQ CX,AX - XORQ SI,DX - RORQ $0x20,CX - ADDQ AX,SI - ADDQ DX,CX - RORQ $0x33,AX - RORQ $0x30,DX - XORQ CX,DX - XORQ SI,AX - RORQ $0x20,SI - ADDQ DX,SI - ADDQ AX,CX - RORQ $0x2F,AX - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ SI,DX - ADDQ AX,SI - RORQ $0x33,AX - ADDQ DX,CX - XORQ SI,AX - RORQ $0x30,DX - XORQ CX,DX - ADDQ AX,CX - RORQ $0x2F,AX - XORQ CX,AX - RORQ $0x2B,DX - RORQ $0x20,CX - XORQ DX,AX - XORQ CX,AX - MOVQ AX,ret+40(FP) - RET diff --git a/vendor/github.com/dchest/siphash/hash_arm.s b/vendor/github.com/dchest/siphash/hash_arm.s deleted file mode 100644 index ddad8f8..0000000 --- a/vendor/github.com/dchest/siphash/hash_arm.s +++ /dev/null @@ -1,160 +0,0 @@ -#include "textflag.h" -#define R10 g -#define ROUND()\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<13,R0,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R1,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R4,R4;\ - ADC R7,R5,R5;\ - EOR R6<<16,R4,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R5,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<21,R1,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R0,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R4,R4;\ - ADC R11,R5,R5;\ - EOR R8<<17,R4,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R5,R3;\ - EOR R11<<17,R3,R3;\ - ADD.S R2,R1,R1;\ - ADC R3,R0,R0;\ - EOR R2<<13,R1,R8;\ - EOR R3>>19,R8,R8;\ - EOR R2>>19,R0,R11;\ - EOR R3<<13,R11,R11;\ - ADD.S R6,R5,R5;\ - ADC R7,R4,R4;\ - EOR R6<<16,R5,R2;\ - EOR R7>>16,R2,R2;\ - EOR R6>>16,R4,R3;\ - EOR R7<<16,R3,R3;\ - ADD.S R2,R0,R0;\ - ADC R3,R1,R1;\ - EOR R2<<21,R0,R6;\ - EOR R3>>11,R6,R6;\ - EOR R2>>11,R1,R7;\ - EOR R3<<21,R7,R7;\ - ADD.S R8,R5,R5;\ - ADC R11,R4,R4;\ - EOR R8<<17,R5,R2;\ - EOR R11>>15,R2,R2;\ - EOR R8>>15,R4,R3;\ - EOR R11<<17,R3,R3;\ - -// Hash(k0, k1 uint64, b []byte) uint64 -TEXT ·Hash(SB),NOSPLIT,$8-36 - MOVW R10,sav-8(SP) - MOVW k0_lo+0(FP),R12 - MOVW k0_hi+4(FP),R14 - MOVW $0x70736575,R0 - MOVW $0x736f6d65,R1 - MOVW $0x6e657261,R4 - MOVW $0x6c796765,R5 - EOR R12,R0,R0 - EOR R14,R1,R1 - EOR R12,R4,R4 - EOR R14,R5,R5 - MOVW k1_lo+8(FP),R12 - MOVW k1_hi+12(FP),R14 - MOVW $0x6e646f6d,R2 - MOVW $0x646f7261,R3 - MOVW $0x79746573,R6 - MOVW $0x74656462,R7 - EOR R12,R2,R2 - EOR R14,R3,R3 - EOR R12,R6,R6 - EOR R14,R7,R7 - MOVW b+16(FP),R10 - MOVW b_len+20(FP),R11 - ADD R10,R11,R11 - MOVW R11,endb-4(SP) - AND.S $3,R10,R8 - BNE hashloopunaligned -hashloop: - MOVW endb-4(SP),R11 - SUB R10,R11,R11 - SUB.S $8,R11 - BLO hashend - MOVM.IA.W (R10),[R12,R14] - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - B hashloop -hashloopunaligned: - MOVW endb-4(SP),R11 - SUB R10,R11,R11 - SUB.S $8,R11 - BLO hashend - MOVB (R10),R12 - MOVB 1(R10),R11 - ORR R11<<8,R12,R12 - MOVB 2(R10),R11 - ORR R11<<16,R12,R12 - MOVB 3(R10),R11 - ORR R11<<24,R12,R12 - MOVB 4(R10),R14 - MOVB 5(R10),R11 - ORR R11<<8,R14,R14 - MOVB 6(R10),R11 - ORR R11<<16,R14,R14 - MOVB 7(R10),R11 - ORR R11<<24,R14,R14 - ADD $8,R10,R10 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - B hashloopunaligned -hashend: - MOVW $0x0,R12 - MOVW $0x0,R14 - RSB $0,R11,R11 - AND.S $7,R11 - BEQ hashlast - MOVW (R10),R12 - SLL $3,R11 - AND $63,R11 - SUB.S $32,R11,R11 - BEQ hashlast - BLO hashhi - MOVW R12<>R11,R12 - B hashlast -hashhi: - ADD $32,R11 - MOVW 4(R10),R14 - MOVW R14<>R11,R14 -hashlast: - MOVW b_len+20(FP),R11 - ORR R11<<24,R14,R14 - EOR R12,R6,R6 - EOR R14,R7,R7 - ROUND() - EOR R12,R0,R0 - EOR R14,R1,R1 - EOR $255,R4 - ROUND() - ROUND() - EOR R2,R0,R0 - EOR R3,R1,R1 - EOR R6,R4,R4 - EOR R7,R5,R5 - EOR R4,R0,R0 - EOR R5,R1,R1 - MOVW sav-8(SP),R10 - MOVW R0,ret_lo+28(FP) - MOVW R1,ret_hi+32(FP) - RET diff --git a/vendor/github.com/dchest/siphash/hash_asm.go b/vendor/github.com/dchest/siphash/hash_asm.go deleted file mode 100644 index 13f540c..0000000 --- a/vendor/github.com/dchest/siphash/hash_asm.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build arm amd64,!appengine,!gccgo - -// Written in 2012 by Dmitry Chestnykh. -// -// To the extent possible under law, the author have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -// This file contains a function definition for use with assembly implementations of Hash() - -package siphash - -//go:noescape - -// Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit -// parts of 128-bit key: k0 and k1. -func Hash(k0, k1 uint64, b []byte) uint64 - -//go:noescape - -// Hash128 returns the 128-bit SipHash-2-4 of the given byte slice with two -// 64-bit parts of 128-bit key: k0 and k1. -func Hash128(k0, k1 uint64, b []byte) (uint64, uint64) - -//go:noescape -func blocks(d *digest, p []uint8) - -//go:noescape -func finalize(d *digest) uint64 - -//go:noescape -func once(d *digest) diff --git a/vendor/github.com/dchest/siphash/siphash.go b/vendor/github.com/dchest/siphash/siphash.go deleted file mode 100644 index 4a3cb49..0000000 --- a/vendor/github.com/dchest/siphash/siphash.go +++ /dev/null @@ -1,318 +0,0 @@ -// Written in 2012-2014 by Dmitry Chestnykh. -// -// To the extent possible under law, the author have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -// Package siphash implements SipHash-2-4, a fast short-input PRF -// created by Jean-Philippe Aumasson and Daniel J. Bernstein. -package siphash - -import "hash" - -const ( - // BlockSize is the block size of hash algorithm in bytes. - BlockSize = 8 - - // Size is the size of hash output in bytes. - Size = 8 - - // Size128 is the size of 128-bit hash output in bytes. - Size128 = 16 -) - -type digest struct { - v0, v1, v2, v3 uint64 // state - k0, k1 uint64 // two parts of key - x [8]byte // buffer for unprocessed bytes - nx int // number of bytes in buffer x - size int // output size in bytes (8 or 16) - t uint8 // message bytes counter (mod 256) -} - -// newDigest returns a new digest with the given output size in bytes (must be 8 or 16). -func newDigest(size int, key []byte) *digest { - if size != Size && size != Size128 { - panic("size must be 8 or 16") - } - d := new(digest) - d.k0 = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | - uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 - d.k1 = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | - uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 - d.size = size - d.Reset() - return d -} - -// New returns a new hash.Hash64 computing SipHash-2-4 with 16-byte key and 8-byte output. -func New(key []byte) hash.Hash64 { - return newDigest(Size, key) -} - -// New128 returns a new hash.Hash computing SipHash-2-4 with 16-byte key and 16-byte output. -// -// Note that 16-byte output is considered experimental by SipHash authors at this time. -func New128(key []byte) hash.Hash { - return newDigest(Size128, key) -} - -func (d *digest) Reset() { - d.v0 = d.k0 ^ 0x736f6d6570736575 - d.v1 = d.k1 ^ 0x646f72616e646f6d - d.v2 = d.k0 ^ 0x6c7967656e657261 - d.v3 = d.k1 ^ 0x7465646279746573 - d.t = 0 - d.nx = 0 - if d.size == Size128 { - d.v1 ^= 0xee - } -} - -func (d *digest) Size() int { return d.size } - -func (d *digest) BlockSize() int { return BlockSize } - -func (d *digest) Write(p []byte) (nn int, err error) { - nn = len(p) - d.t += uint8(nn) - if d.nx > 0 { - n := len(p) - if n > BlockSize-d.nx { - n = BlockSize - d.nx - } - d.nx += copy(d.x[d.nx:], p) - if d.nx == BlockSize { - once(d) - d.nx = 0 - } - p = p[n:] - } - if len(p) >= BlockSize { - n := len(p) &^ (BlockSize - 1) - blocks(d, p[:n]) - p = p[n:] - } - if len(p) > 0 { - d.nx = copy(d.x[:], p) - } - return -} - -func (d *digest) Sum64() uint64 { - for i := d.nx; i < BlockSize-1; i++ { - d.x[i] = 0 - } - d.x[7] = d.t - return finalize(d) -} - -func (d0 *digest) sum128() (r0, r1 uint64) { - // Make a copy of d0 so that caller can keep writing and summing. - d := *d0 - - for i := d.nx; i < BlockSize-1; i++ { - d.x[i] = 0 - } - d.x[7] = d.t - blocks(&d, d.x[:]) - - v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 - v2 ^= 0xee - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - r0 = v0 ^ v1 ^ v2 ^ v3 - - v1 ^= 0xdd - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - r1 = v0 ^ v1 ^ v2 ^ v3 - - return r0, r1 -} - -func (d *digest) Sum(in []byte) []byte { - if d.size == Size { - r := d.Sum64() - in = append(in, - byte(r), - byte(r>>8), - byte(r>>16), - byte(r>>24), - byte(r>>32), - byte(r>>40), - byte(r>>48), - byte(r>>56)) - } else { - r0, r1 := d.sum128() - in = append(in, - byte(r0), - byte(r0>>8), - byte(r0>>16), - byte(r0>>24), - byte(r0>>32), - byte(r0>>40), - byte(r0>>48), - byte(r0>>56), - byte(r1), - byte(r1>>8), - byte(r1>>16), - byte(r1>>24), - byte(r1>>32), - byte(r1>>40), - byte(r1>>48), - byte(r1>>56)) - } - return in -} diff --git a/vendor/github.com/lwahlmeier/GoScheduler/.gitignore b/vendor/github.com/lwahlmeier/GoScheduler/.gitignore new file mode 100644 index 0000000..2c78ecf --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/.gitignore @@ -0,0 +1 @@ +.cache/* diff --git a/vendor/github.com/lwahlmeier/GoScheduler/Makefile b/vendor/github.com/lwahlmeier/GoScheduler/Makefile new file mode 100644 index 0000000..c98e1d9 --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/Makefile @@ -0,0 +1,14 @@ +GO_VERSION ?= 1.19 +GO_FILES := $(shell find ./* -iname '*.go') +DOCKER_EXEC := docker run --rm -e HOME=/build/.cache -u $$(id -u $${USER}):$$(id -g $${USER}) -v $$PWD:/build -w /build +GO_RUN := $(DOCKER_EXEC) golang:$(GO_VERSION) +GO_LINT := $(DOCKER_EXEC) golangci/golangci-lint:v1.50.0 golangci-lint run + +test: + $(GO_RUN) go test -count=10 -cover ./... + +lint: + $(GO_LINT) + +clean: + rm -rf ./bin diff --git a/vendor/github.com/lwahlmeier/GoScheduler/dynamic_scheduler.go b/vendor/github.com/lwahlmeier/GoScheduler/dynamic_scheduler.go new file mode 100644 index 0000000..c40069e --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/dynamic_scheduler.go @@ -0,0 +1,154 @@ +package GoScheduler + +import ( + "context" + "sync" + "sync/atomic" + "time" +) + +var MAX_WAIT_TIME = time.Minute + +// DynamicSchduler is a scheduler that runs every job scheduled in +// its own go routine +type DynamicScheduler struct { + clearChan chan bool + jobs []*job + newJob chan *job + runJob chan *job + running atomic.Bool + waiter sync.WaitGroup +} + +func CreateDynamicScheduler() *DynamicScheduler { + sch := &DynamicScheduler{ + clearChan: make(chan bool, 10), + jobs: make([]*job, 0), + newJob: make(chan *job), + runJob: make(chan *job), + running: atomic.Bool{}, + waiter: sync.WaitGroup{}, + } + sch.running.Store(true) + go sch.run() + return sch +} + +func (sch *DynamicScheduler) doWork() { + sch.waiter.Add(1) + defer sch.waiter.Done() + for sch.running.Load() { + expireTimer := time.NewTimer(MAX_WAIT_TIME) + select { + case job := <-sch.runJob: + expireTimer.Stop() + select { + case <-job.ctx.Done(): + continue + default: + } + execJob(job, sch) + case <-expireTimer.C: + return + } + } +} + +func (sch *DynamicScheduler) run() { + sch.waiter.Add(1) + defer sch.waiter.Done() + baseDelay := time.After(waitTime) + nextDelay := baseDelay + needSort := false + for sch.running.Load() { + select { + case <-sch.clearChan: + sch.jobs = make([]*job, 0) + nextDelay = baseDelay + case <-nextDelay: + nextDelay = baseDelay + if len(sch.jobs) > 0 { + runJob := sch.jobs[0] + sch.jobs = sch.jobs[1:] + + select { + case sch.runJob <- runJob: + default: + go sch.doWork() + sch.runJob <- runJob + } + if len(sch.jobs) > 0 { + if needSort { + sortJobs(sch.jobs) + needSort = false + } + nextDelay = sch.jobs[0].timer + } + } else { + baseDelay = time.After(waitTime) + nextDelay = baseDelay + } + + case newJob := <-sch.newJob: + if len(sch.jobs) == 0 { + sch.jobs = append(sch.jobs, newJob) + nextDelay = newJob.timer + } else if sch.jobs[0].nextCall.After(newJob.nextCall) { + sch.jobs = append([]*job{newJob}, sch.jobs...) + nextDelay = newJob.timer + } else { + sch.jobs = append(sch.jobs, newJob) + needSort = true + } + } + } +} + +func (sch *DynamicScheduler) Schedule(delay time.Duration, recurring bool, callable func()) { + sch.ScheduleWithContext(delay, recurring, callable, context.Background()) +} + +func (sch *DynamicScheduler) ScheduleWithContext(delay time.Duration, recurring bool, callable func(), ctx context.Context) { + if !sch.running.Load() { + return + } + context.TODO() + runTime := time.Now().Add(delay) + sch.newJob <- &job{ + callable: callable, + nextCall: runTime, + timer: time.After(time.Until(runTime)), + period: delay, + recurring: recurring, + ctx: ctx, + } +} + +func (sch *DynamicScheduler) Stop() { + if sch.running.CompareAndSwap(true, false) { + sch.Clear() + for { + select { + case sch.runJob <- &job{recurring: false, callable: func() {}, ctx: context.Background()}: + default: + return + } + } + } +} + +func (sch *DynamicScheduler) IsRunning() bool { + return sch.running.Load() +} + +func (sch *DynamicScheduler) Clear() { + select { + case sch.clearChan <- true: + default: + } +} + +func (sch *DynamicScheduler) WaitForStop() { + sch.Stop() + sch.waiter.Wait() +} diff --git a/vendor/github.com/lwahlmeier/GoScheduler/pool_scheduler.go b/vendor/github.com/lwahlmeier/GoScheduler/pool_scheduler.go new file mode 100644 index 0000000..a6936d4 --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/pool_scheduler.go @@ -0,0 +1,142 @@ +package GoScheduler + +import ( + "context" + "sync" + "sync/atomic" + "time" +) + +type PoolScheduler struct { + runJob chan *job + clearChan chan bool + jobs []*job + newJob chan *job + running atomic.Bool + workers int + waiter sync.WaitGroup +} + +func CreatePoolScheduler(workers int) *PoolScheduler { + ps := &PoolScheduler{ + clearChan: make(chan bool, 10), + newJob: make(chan *job), + runJob: make(chan *job, 1), + jobs: make([]*job, 0), + running: atomic.Bool{}, + workers: workers, + waiter: sync.WaitGroup{}, + } + ps.running.Store(true) + for i := 0; i < workers; i++ { + go ps.doWork() + } + go ps.run() + return ps +} + +func (ps *PoolScheduler) doWork() { + ps.waiter.Add(1) + defer ps.waiter.Done() + for ps.running.Load() { + job := <-ps.runJob + select { + case <-job.ctx.Done(): + continue + default: + } + execJob(job, ps) + } +} + +func (ps *PoolScheduler) run() { + ps.waiter.Add(1) + defer ps.waiter.Done() + baseDelay := time.After(waitTime) + nextDelay := baseDelay + needSort := false + for ps.running.Load() { + select { + case <-ps.clearChan: + ps.jobs = make([]*job, 0) + nextDelay = baseDelay + case <-nextDelay: + nextDelay = baseDelay + if len(ps.jobs) > 0 { + runJob := ps.jobs[0] + ps.jobs = ps.jobs[1:] + + ps.runJob <- runJob + if len(ps.jobs) > 0 { + if needSort { + sortJobs(ps.jobs) + needSort = false + } + nextDelay = ps.jobs[0].timer + } + } else { + baseDelay = time.After(waitTime) + nextDelay = baseDelay + } + case newJob := <-ps.newJob: + if len(ps.jobs) == 0 { + ps.jobs = append(ps.jobs, newJob) + nextDelay = newJob.timer + } else if ps.jobs[0].nextCall.After(newJob.nextCall) { + ps.jobs = append([]*job{newJob}, ps.jobs...) + nextDelay = newJob.timer + } else { + ps.jobs = append(ps.jobs, newJob) + needSort = true + } + } + } +} + +func (ps *PoolScheduler) Schedule(delay time.Duration, recurring bool, callable func()) { + ps.ScheduleWithContext(delay, recurring, callable, context.Background()) +} + +func (ps *PoolScheduler) ScheduleWithContext(delay time.Duration, recurring bool, callable func(), ctx context.Context) { + if !ps.running.Load() { + return + } + runTime := time.Now().Add(delay) + toRun := &job{ + callable: callable, + nextCall: runTime, + timer: time.After(time.Until(runTime)), + period: delay, + recurring: recurring, + ctx: ctx, + } + ps.newJob <- toRun +} + +func (ps *PoolScheduler) IsRunning() bool { + return ps.running.Load() +} + +func (ps *PoolScheduler) Stop() { + if ps.running.CompareAndSwap(true, false) { + ps.Clear() + for i := 0; i < ps.workers; i++ { + select { + case ps.runJob <- &job{recurring: false, callable: func() {}, ctx: context.Background()}: + default: + } + } + } +} + +func (ps *PoolScheduler) Clear() { + select { + case ps.clearChan <- true: + default: + } +} + +func (ps *PoolScheduler) WaitForStop() { + ps.Stop() + ps.waiter.Wait() +} diff --git a/vendor/github.com/lwahlmeier/GoScheduler/schedule.go b/vendor/github.com/lwahlmeier/GoScheduler/schedule.go new file mode 100644 index 0000000..d89401e --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/schedule.go @@ -0,0 +1,35 @@ +package GoScheduler + +import ( + "context" + "sync/atomic" + "time" +) + +var defaultScheduler atomic.Pointer[DynamicScheduler] +var waitTime time.Duration = time.Hour * 1000 + +// Basic Schduler interface +type Scheduler interface { + Clear() + Stop() + WaitForStop() + IsRunning() bool + Schedule(delay time.Duration, recurring bool, callable func()) + ScheduleWithContext(delay time.Duration, recurring bool, callable func(), ctx context.Context) +} + +// Returns the global default scheduler(creates it if it doesnt exist) +// This is a DynamicSchduler +func GetDefaultScheduler() Scheduler { + ds := defaultScheduler.Load() + if ds != nil && ds.IsRunning() { + return ds + } + nds := CreateDynamicScheduler() + if defaultScheduler.CompareAndSwap(ds, nds) { + return nds + } + nds.Stop() + return defaultScheduler.Load() +} diff --git a/vendor/github.com/lwahlmeier/GoScheduler/utils.go b/vendor/github.com/lwahlmeier/GoScheduler/utils.go new file mode 100644 index 0000000..ef2b432 --- /dev/null +++ b/vendor/github.com/lwahlmeier/GoScheduler/utils.go @@ -0,0 +1,52 @@ +package GoScheduler + +import ( + "context" + "sort" + "time" +) + +type job struct { + callable func() + nextCall time.Time + timer <-chan time.Time + period time.Duration + recurring bool + ctx context.Context +} + +func (j job) String() string { + return j.period.String() +} + +type jobSort []*job + +func (js jobSort) Len() int { + return len(js) +} + +func (js jobSort) Swap(i, j int) { + js[i], js[j] = js[j], js[i] +} + +func (js jobSort) Less(i, j int) bool { + return js[i].nextCall.Before(js[j].nextCall) +} + +func execJob(rj *job, sch Scheduler) { + rj.callable() + if rj.recurring { + sch.ScheduleWithContext(rj.period, true, rj.callable, rj.ctx) + } +} + +func sortJobs(jobs []*job) time.Duration { + cl := len(jobs) + if cl == 0 { + return waitTime + } + if cl > 1 { + sort.Sort(jobSort(jobs)) + } + return time.Until(jobs[0].nextCall) +} diff --git a/vendor/github.com/lwahlmeier/lcwlog/.gitignore b/vendor/github.com/lwahlmeier/lcwlog/.gitignore index 66fd13c..96cff57 100644 --- a/vendor/github.com/lwahlmeier/lcwlog/.gitignore +++ b/vendor/github.com/lwahlmeier/lcwlog/.gitignore @@ -13,3 +13,4 @@ # Dependency directories (remove the comment below to include it) # vendor/ +.cache/* diff --git a/vendor/github.com/lwahlmeier/lcwlog/Makefile b/vendor/github.com/lwahlmeier/lcwlog/Makefile new file mode 100644 index 0000000..2941fce --- /dev/null +++ b/vendor/github.com/lwahlmeier/lcwlog/Makefile @@ -0,0 +1,11 @@ +GO_VERSION ?= 1.19 +GO_FILES := $(shell find ./* -iname '*.go') +GO_RUN := docker run --rm -e GO111MODULE=on -e HOME=/build/.cache -u $$(id -u $${USER}):$$(id -g $${USER}) -v $$PWD:/build -w /build golang:$(GO_VERSION) +.PHONY: vendor test + +test: + $(GO_RUN) go test -count=1 -v -cover ./... + +vendor: + $(GO_RUN) go mod vendor + $(GO_RUN) go mod tidy diff --git a/vendor/github.com/lwahlmeier/lcwlog/lcwlog.go b/vendor/github.com/lwahlmeier/lcwlog/lcwlog.go index e036f68..4f4a7ad 100644 --- a/vendor/github.com/lwahlmeier/lcwlog/lcwlog.go +++ b/vendor/github.com/lwahlmeier/lcwlog/lcwlog.go @@ -6,11 +6,10 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" - "github.com/cornelk/hashmap" "github.com/lwahlmeier/pyfmt" - "github.com/tevino/abool" ) type Logger interface { @@ -75,16 +74,16 @@ type fullLCWLogger struct { currentLevel Level highestLevel Level dateFMT string - logfiles hashmap.HashMap + logfiles sync.Map logQueue chan *logMessage - forceFlush *abool.AtomicBool + forceFlush *atomic.Bool logLevel bool logTime bool } -var logger *fullLCWLogger +var logger atomic.Pointer[fullLCWLogger] -var prefixLogger map[string]LCWLogger +var prefixLogger = sync.Map{} const traceMsg = "[ TRACE ]" const debugMsg = "[ DEBUG ]" @@ -94,39 +93,44 @@ const infoMsg = "[ INFO ]" const verboseMsg = "[VERBOSE]" const dateFMT = "2006-01-02 15:04:05.999" -var LCWLoggerCreateLock sync.Mutex = sync.Mutex{} - func resetLogger() { - logger = nil - prefixLogger = nil + logger.Store(nil) + prefixLogger.Range(func(k, v any) bool { + prefixLogger.Delete(k) + return true + }) } func GetLoggerConfig() LCWLoggerConfig { GetLogger() - return logger + return logger.Load() } //GetLogger gets a logger for logging. -func GetLogger() LCWLogger { - if logger == nil { - LCWLoggerCreateLock.Lock() - defer LCWLoggerCreateLock.Unlock() - if logger == nil { - logger = &fullLCWLogger{ - currentLevel: InfoLevel, - highestLevel: InfoLevel, - dateFMT: dateFMT, - logQueue: make(chan *logMessage, 1000), - logfiles: hashmap.HashMap{}, - forceFlush: abool.NewBool(true), - logLevel: true, - logTime: true, - } - logger.AddLogFile("STDOUT", defaultLevel) - go logger.writeLogQueue() - } +func GetLogger() *fullLCWLogger { + ll := logger.Load() + if ll != nil { + return ll } - return logger + + ab := &atomic.Bool{} + ab.Store(true) + nll := &fullLCWLogger{ + currentLevel: InfoLevel, + highestLevel: InfoLevel, + dateFMT: dateFMT, + logQueue: make(chan *logMessage, 1000), + logfiles: sync.Map{}, + forceFlush: ab, + logLevel: true, + logTime: true, + } + nll.AddLogFile("STDOUT", defaultLevel) + if logger.CompareAndSwap(ll, nll) { + go nll.writeLogQueue() + return nll + } + return logger.Load() } //GetLoggerWithPrefix gets a logger for logging with a static prefix. @@ -135,20 +139,14 @@ func GetLoggerWithPrefix(prefix string) LCWLogger { if prefix == "" { return baseLogger } - if prefixLogger == nil { - LCWLoggerCreateLock.Lock() - if prefixLogger == nil { - prefixLogger = make(map[string]LCWLogger) - } - LCWLoggerCreateLock.Unlock() - } - LCWLoggerCreateLock.Lock() - defer LCWLoggerCreateLock.Unlock() - if sl, ok := prefixLogger[prefix]; ok { - return sl + cpl, exists := prefixLogger.Load(prefix) + if exists { + return cpl.(LCWLogger) } - prefixLogger[prefix] = &lcwPrefixLogger{LCWLogger: logger, prefix: prefix} - return prefixLogger[prefix] + npl := &lcwPrefixLogger{LCWLogger: baseLogger, prefix: prefix} + + cpl, _ = prefixLogger.LoadOrStore(prefix, npl) + return cpl.(LCWLogger) } //GetLogLevel gets the current highest set log level for lcwlog @@ -168,16 +166,17 @@ func (LCWLogger *fullLCWLogger) EnableTimeLogging(b bool) { //RemoveLogFile removes logging of a file (can be STDOUT/STDERR too) func (LCWLogger *fullLCWLogger) RemoveLogFile(file string) { - _, ok := LCWLogger.logfiles.Get(file) + _, ok := LCWLogger.logfiles.Load(file) if ok { highestLL := defaultLevel - LCWLogger.logfiles.Del(file) - for kv := range LCWLogger.logfiles.Iter() { - lgr := kv.Value.(*logFile) - if lgr.logLevel > highestLL { - highestLL = lgr.logLevel + LCWLogger.logfiles.Delete(file) + LCWLogger.logfiles.Range(func(key, v any) bool { + lf := v.(*logFile) + if lf.logLevel > highestLL { + highestLL = lf.logLevel } - } + return true + }) if highestLL > defaultLevel { LCWLogger.highestLevel = highestLL } @@ -206,7 +205,7 @@ func (LCWLogger *fullLCWLogger) AddLogFile(file string, logLevel Level) error { if logLevel > LCWLogger.highestLevel { LCWLogger.highestLevel = logLevel } - LCWLogger.logfiles.Set(file, &logFile{path: file, logLevel: logLevel, fp: fp}) + LCWLogger.logfiles.Store(file, &logFile{path: file, logLevel: logLevel, fp: fp}) return nil } @@ -214,12 +213,12 @@ func (LCWLogger *fullLCWLogger) writeLogQueue() { syncSoon := time.Duration(100 * time.Millisecond) syncLate := time.Duration(10000 * time.Millisecond) delay := time.NewTimer(syncSoon) - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { delay.Reset(syncLate) } defer delay.Stop() for { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { delay.Reset(syncLate) } else { delay.Reset(syncSoon) @@ -231,10 +230,11 @@ func (LCWLogger *fullLCWLogger) writeLogQueue() { lm.wg.Done() } case <-delay.C: - for kv := range LCWLogger.logfiles.Iter() { - lgr := kv.Value.(*logFile) - lgr.fp.Sync() - } + LCWLogger.logfiles.Range(func(key, v any) bool { + lf := v.(*logFile) + lf.fp.Sync() + return true + }) } } } @@ -270,15 +270,16 @@ func (LCWLogger *fullLCWLogger) formatLogMessage(lm *logMessage) string { } func (LCWLogger *fullLCWLogger) writeLogs(logLevel Level, sync bool, msg string) { - for kv := range LCWLogger.logfiles.Iter() { - lgr := kv.Value.(*logFile) + LCWLogger.logfiles.Range(func(k, v any) bool { + lgr := v.(*logFile) if lgr.logLevel >= logLevel || (lgr.logLevel == defaultLevel && LCWLogger.currentLevel >= logLevel) { lgr.fp.WriteString(msg) - if LCWLogger.forceFlush.IsSet() || sync { + if LCWLogger.forceFlush.Load() || sync { lgr.fp.Sync() } } - } + return true + }) } func (LCWLogger *fullLCWLogger) wrapMessage(ll Level, wg *sync.WaitGroup, args ...interface{}) *logMessage { @@ -309,7 +310,7 @@ func (LCWLogger *fullLCWLogger) Flush() { //ForceFlush enables/disables forcing sync on logfiles after every write func (LCWLogger *fullLCWLogger) ForceFlush(ff bool) { - LCWLogger.forceFlush.SetTo(ff) + LCWLogger.forceFlush.Store(ff) if ff { LCWLogger.Flush() } @@ -331,12 +332,13 @@ func (LCWLogger *fullLCWLogger) SetLogger(givenLogger Logger) { func (LCWLogger *fullLCWLogger) SetLevel(level Level) { LCWLogger.currentLevel = level hl := level - for kv := range LCWLogger.logfiles.Iter() { - lgr := kv.Value.(*logFile) + LCWLogger.logfiles.Range(func(k, v any) bool { + lgr := v.(*logFile) if lgr.logLevel > hl { hl = lgr.logLevel } - } + return true + }) LCWLogger.highestLevel = hl } @@ -344,7 +346,7 @@ func (LCWLogger *fullLCWLogger) SetLevel(level Level) { func (LCWLogger *fullLCWLogger) Debug(message ...interface{}) { if LCWLogger.highestLevel >= DebugLevel { if LCWLogger.setLogger == nil { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { wg := &sync.WaitGroup{} wg.Add(1) LCWLogger.logQueue <- LCWLogger.wrapMessage(DebugLevel, wg, message...) @@ -362,7 +364,7 @@ func (LCWLogger *fullLCWLogger) Debug(message ...interface{}) { func (LCWLogger *fullLCWLogger) Verbose(message ...interface{}) { if LCWLogger.highestLevel >= VerboseLevel { if LCWLogger.setLogger == nil { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { wg := &sync.WaitGroup{} wg.Add(1) LCWLogger.logQueue <- LCWLogger.wrapMessage(VerboseLevel, wg, message...) @@ -380,7 +382,7 @@ func (LCWLogger *fullLCWLogger) Verbose(message ...interface{}) { func (LCWLogger *fullLCWLogger) Warn(message ...interface{}) { if LCWLogger.highestLevel >= WarnLevel { if LCWLogger.setLogger == nil { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { wg := &sync.WaitGroup{} wg.Add(1) LCWLogger.logQueue <- LCWLogger.wrapMessage(WarnLevel, wg, message...) @@ -398,7 +400,7 @@ func (LCWLogger *fullLCWLogger) Warn(message ...interface{}) { func (LCWLogger *fullLCWLogger) Trace(message ...interface{}) { if LCWLogger.highestLevel >= TraceLevel { if LCWLogger.setLogger == nil { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { wg := &sync.WaitGroup{} wg.Add(1) LCWLogger.logQueue <- LCWLogger.wrapMessage(TraceLevel, wg, message...) @@ -417,7 +419,7 @@ func (LCWLogger *fullLCWLogger) Info(message ...interface{}) { if LCWLogger.highestLevel >= InfoLevel { if LCWLogger.setLogger == nil { - if LCWLogger.forceFlush.IsSet() { + if LCWLogger.forceFlush.Load() { wg := &sync.WaitGroup{} wg.Add(1) LCWLogger.logQueue <- LCWLogger.wrapMessage(InfoLevel, wg, message...) diff --git a/vendor/github.com/lwahlmeier/pyfmt/.gitignore b/vendor/github.com/lwahlmeier/pyfmt/.gitignore index 38dc470..77f7d50 100644 --- a/vendor/github.com/lwahlmeier/pyfmt/.gitignore +++ b/vendor/github.com/lwahlmeier/pyfmt/.gitignore @@ -21,3 +21,10 @@ _bridge.py test/build/** + +# Test data +test/.hypothesis/ +test/.venv/ +test/__pycache__/ +test/_bridge.py +test/build/ diff --git a/vendor/github.com/lwahlmeier/pyfmt/Makefile b/vendor/github.com/lwahlmeier/pyfmt/Makefile new file mode 100644 index 0000000..2941fce --- /dev/null +++ b/vendor/github.com/lwahlmeier/pyfmt/Makefile @@ -0,0 +1,11 @@ +GO_VERSION ?= 1.19 +GO_FILES := $(shell find ./* -iname '*.go') +GO_RUN := docker run --rm -e GO111MODULE=on -e HOME=/build/.cache -u $$(id -u $${USER}):$$(id -g $${USER}) -v $$PWD:/build -w /build golang:$(GO_VERSION) +.PHONY: vendor test + +test: + $(GO_RUN) go test -count=1 -v -cover ./... + +vendor: + $(GO_RUN) go mod vendor + $(GO_RUN) go mod tidy diff --git a/vendor/github.com/lwahlmeier/pyfmt/README.md b/vendor/github.com/lwahlmeier/pyfmt/README.md index db2bc2f..a21c03d 100644 --- a/vendor/github.com/lwahlmeier/pyfmt/README.md +++ b/vendor/github.com/lwahlmeier/pyfmt/README.md @@ -1,5 +1,5 @@ # pyfmt -[![Build Status](https://travis-ci.org/slongfield/pyfmt.svg?branch=master)](https://travis-ci.org/slongfield/pyfmt) +![Build Status](https://github.com/slongfield/pyfmt/actions/workflows/go.yml/badge.svg) pyfmt implements Python's advanced string formatting in Golang. @@ -16,7 +16,7 @@ literal '{' and '}' runes to be emitted in the output. Each format item consists of a 'field name', which indicates which value from the argument list to use, and a 'format specifier', which indicates how to format that item. -Requires Golang 1.5 or newer. +Requires Golang 1.5 or newer for formatting, 1.9 or newer to run the tests. # Functions @@ -36,7 +36,7 @@ names build off of simple names. The simplest look up treats the argument list as just a list. There are two possible ways to look up elements from this list. First, by {}, which gets the 'next' item and by {n}, which gets the nth -item. Accessing these two ways is independent, and +item. Accessing these two ways is independent but cannot be mixed, and ``` pyfmt.Must("{} {} {}", ...) diff --git a/vendor/github.com/lwahlmeier/pyfmt/pyfmt.go b/vendor/github.com/lwahlmeier/pyfmt/pyfmt.go index b12ecbf..d442b62 100644 --- a/vendor/github.com/lwahlmeier/pyfmt/pyfmt.go +++ b/vendor/github.com/lwahlmeier/pyfmt/pyfmt.go @@ -77,10 +77,12 @@ func (b *buffer) WriteAlignedString(s string, align int, width int64, fillChar r } } +// What type of numbering is being used to access fields. {} is automatic, {0} is manual. +type numbering int const ( - useMap = iota - useList - useStruct + unknown numbering = iota + automatic + manual ) // ff is used to store a formatter's state and is reused with sync.Pool to avoid allocations. @@ -90,6 +92,7 @@ type ff struct { // args is the list of arguments passed to Fmt. args []interface{} listPos int + numb numbering // render renders format parameters r render @@ -103,6 +106,7 @@ var ffFree = sync.Pool{ func newFormater() *ff { f := ffFree.Get().(*ff) f.listPos = 0 + f.numb = unknown f.r.init(&f.buf) return f } @@ -111,6 +115,7 @@ func (f *ff) free() { f.buf.contents = f.buf.contents[:0] f.args = f.args[:0] f.listPos = 0 + f.numb = unknown ffFree.Put(f) } @@ -194,6 +199,20 @@ func split(s string, sep rune) (string, string) { } func (f *ff) getArg(argName string) (interface{}, error) { + if f.numb == unknown { + if argName == "" { + f.numb = automatic + } else { + f.numb = manual + } + } else { + if argName == "" && f.numb == manual { + return nil, Error("cannot switch from manual field specification to automatic field numbering") + } + if argName != "" && f.numb == automatic { + return nil, Error("cannot switch from automatic field numbering to manual field specification") + } + } val, err := getElement(argName, f.listPos, f.args...) if argName == "" { f.listPos++ diff --git a/vendor/github.com/lwahlmeier/unboundChannel/.gitignore b/vendor/github.com/lwahlmeier/unboundChannel/.gitignore new file mode 100644 index 0000000..2c78ecf --- /dev/null +++ b/vendor/github.com/lwahlmeier/unboundChannel/.gitignore @@ -0,0 +1 @@ +.cache/* diff --git a/vendor/github.com/lwahlmeier/unboundChannel/Makefile b/vendor/github.com/lwahlmeier/unboundChannel/Makefile new file mode 100644 index 0000000..c98e1d9 --- /dev/null +++ b/vendor/github.com/lwahlmeier/unboundChannel/Makefile @@ -0,0 +1,14 @@ +GO_VERSION ?= 1.19 +GO_FILES := $(shell find ./* -iname '*.go') +DOCKER_EXEC := docker run --rm -e HOME=/build/.cache -u $$(id -u $${USER}):$$(id -g $${USER}) -v $$PWD:/build -w /build +GO_RUN := $(DOCKER_EXEC) golang:$(GO_VERSION) +GO_LINT := $(DOCKER_EXEC) golangci/golangci-lint:v1.50.0 golangci-lint run + +test: + $(GO_RUN) go test -count=10 -cover ./... + +lint: + $(GO_LINT) + +clean: + rm -rf ./bin diff --git a/vendor/github.com/lwahlmeier/unboundChannel/unboundChannel.go b/vendor/github.com/lwahlmeier/unboundChannel/unboundChannel.go new file mode 100644 index 0000000..aad1b12 --- /dev/null +++ b/vendor/github.com/lwahlmeier/unboundChannel/unboundChannel.go @@ -0,0 +1,75 @@ +package unboundchannel + +import ( + "sync/atomic" +) + +type UnboundChannel[T any] struct { + data []T + inChannel chan T + outChannel chan T + countChannel chan int + running atomic.Bool +} + +func NewUnboundChannel[T any]() *UnboundChannel[T] { + uc := &UnboundChannel[T]{ + data: make([]T, 0), + inChannel: make(chan T, 0), + outChannel: make(chan T, 0), + countChannel: make(chan int), + running: atomic.Bool{}, + } + uc.running.Store(true) + go uc.run() + return uc +} + +func (uc *UnboundChannel[T]) Add() chan<- T { + return uc.inChannel +} + +func (uc *UnboundChannel[T]) Get() <-chan T { + return uc.outChannel +} + +func (uc *UnboundChannel[T]) Count() <-chan int { + return uc.countChannel +} + +func (uc *UnboundChannel[T]) IsRunning() bool { + return uc.running.Load() +} + +func (uc *UnboundChannel[T]) Stop() { + if uc.running.CompareAndSwap(true, false) { + select { + case <-uc.Count(): + default: + } + close(uc.countChannel) + close(uc.outChannel) + close(uc.inChannel) + uc.data = nil + } +} + +func (uc *UnboundChannel[T]) run() { + for uc.running.Load() { + if len(uc.data) > 0 { + select { + case newMsg := <-uc.inChannel: + uc.data = append(uc.data, newMsg) + case uc.outChannel <- uc.data[0]: + uc.data = uc.data[1:] + case uc.countChannel <- len(uc.data) + len(uc.outChannel): + } + } else { + select { + case newStr := <-uc.inChannel: + uc.data = append(uc.data, newStr) + case uc.countChannel <- len(uc.data) + len(uc.outChannel): + } + } + } +} diff --git a/vendor/github.com/tevino/abool/.gitignore b/vendor/github.com/tevino/abool/.gitignore deleted file mode 100644 index daf913b..0000000 --- a/vendor/github.com/tevino/abool/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/tevino/abool/LICENSE b/vendor/github.com/tevino/abool/LICENSE deleted file mode 100644 index f20dac8..0000000 --- a/vendor/github.com/tevino/abool/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Tevin Zhang - -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. diff --git a/vendor/github.com/tevino/abool/README.md b/vendor/github.com/tevino/abool/README.md deleted file mode 100644 index c8e627d..0000000 --- a/vendor/github.com/tevino/abool/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# ABool :bulb: - -[![Go Report Card](https://goreportcard.com/badge/github.com/tevino/abool)](https://goreportcard.com/report/github.com/tevino/abool) -[![GoDoc](https://godoc.org/github.com/tevino/abool?status.svg)](https://godoc.org/github.com/tevino/abool) - -Atomic Boolean package for Go, optimized for performance yet simple to use. - -Designed for cleaner code. - -## Usage - -```go -import "github.com/tevino/abool" - -cond := abool.New() // default to false - -cond.Set() // Sets to true -cond.IsSet() // Returns true -cond.UnSet() // Sets to false -cond.IsNotSet() // Returns true -cond.SetTo(any) // Sets to whatever you want -cond.SetToIf(new, old) // Sets to `new` only if the Boolean matches the `old`, returns whether succeeded -cond.Toggle() // Inverts the boolean then returns the value before inverting - - -// embedding -type Foo struct { - cond *abool.AtomicBool // always use pointer to avoid copy -} -``` - -## Benchmark - -- Go 1.14.3 -- Linux 4.19.0 - -```bash -goos: linux -goarch: amd64 - -# Read -BenchmarkMutexRead-4 86662128 14.2 ns/op -BenchmarkAtomicValueRead-4 1000000000 0.755 ns/op -BenchmarkAtomicBoolRead-4 1000000000 0.720 ns/op # <--- This package - - -# Write -BenchmarkMutexWrite-4 76237544 13.6 ns/op -BenchmarkAtomicValueWrite-4 79471124 14.9 ns/op -BenchmarkAtomicBoolWrite-4 178218270 6.73 ns/op # <--- This package - -# CAS -BenchmarkMutexCAS-4 29416574 34.7 ns/op -BenchmarkAtomicBoolCAS-4 171900002 7.14 ns/op # <--- This package - -# Toggle -BenchmarkMutexToggle-4 35212117 34.5 ns/op -BenchmarkAtomicBoolToggle-4 169871972 7.02 ns/op # <--- This package -``` - -## Special thanks to contributors - -- [@barryz](https://github.com/barryz) - - Added the `Toggle` method diff --git a/vendor/github.com/tevino/abool/bool.go b/vendor/github.com/tevino/abool/bool.go deleted file mode 100644 index d4977a2..0000000 --- a/vendor/github.com/tevino/abool/bool.go +++ /dev/null @@ -1,71 +0,0 @@ -// Package abool provides atomic Boolean type for cleaner code and -// better performance. -package abool - -import "sync/atomic" - -// New creates an AtomicBool with default set to false. -func New() *AtomicBool { - return new(AtomicBool) -} - -// NewBool creates an AtomicBool with given default value. -func NewBool(ok bool) *AtomicBool { - ab := New() - if ok { - ab.Set() - } - return ab -} - -// AtomicBool is an atomic Boolean. -// Its methods are all atomic, thus safe to be called by multiple goroutines simultaneously. -// Note: When embedding into a struct one should always use *AtomicBool to avoid copy. -type AtomicBool int32 - -// Set sets the Boolean to true. -func (ab *AtomicBool) Set() { - atomic.StoreInt32((*int32)(ab), 1) -} - -// UnSet sets the Boolean to false. -func (ab *AtomicBool) UnSet() { - atomic.StoreInt32((*int32)(ab), 0) -} - -// IsSet returns whether the Boolean is true. -func (ab *AtomicBool) IsSet() bool { - return atomic.LoadInt32((*int32)(ab))&1 == 1 -} - -// IsNotSet returns whether the Boolean is false. -func (ab *AtomicBool) IsNotSet() bool { - return !ab.IsSet() -} - -// SetTo sets the boolean with given Boolean. -func (ab *AtomicBool) SetTo(yes bool) { - if yes { - atomic.StoreInt32((*int32)(ab), 1) - } else { - atomic.StoreInt32((*int32)(ab), 0) - } -} - -// Toggle inverts the Boolean then returns the value before inverting. -func (ab *AtomicBool) Toggle() bool { - return atomic.AddInt32((*int32)(ab), 1)&1 == 0 -} - -// SetToIf sets the Boolean to new only if the Boolean matches the old. -// Returns whether the set was done. -func (ab *AtomicBool) SetToIf(old, new bool) (set bool) { - var o, n int32 - if old { - o = 1 - } - if new { - n = 1 - } - return atomic.CompareAndSwapInt32((*int32)(ab), o, n) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9cbf7b6..b409ac7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,12 +1,10 @@ # github.com/cornelk/hashmap v1.0.1 ## explicit -github.com/cornelk/hashmap # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew # github.com/dchest/siphash v1.1.0 ## explicit -github.com/dchest/siphash # github.com/fsnotify/fsnotify v1.5.4 ## explicit; go 1.16 github.com/fsnotify/fsnotify @@ -36,12 +34,18 @@ github.com/hashicorp/hcl/json/token # github.com/inconshreveable/mousetrap v1.0.0 ## explicit github.com/inconshreveable/mousetrap -# github.com/lwahlmeier/lcwlog v0.0.1 -## explicit; go 1.16 +# github.com/lwahlmeier/GoScheduler v1.0.1 +## explicit; go 1.19 +github.com/lwahlmeier/GoScheduler +# github.com/lwahlmeier/lcwlog v0.1.0 +## explicit; go 1.19 github.com/lwahlmeier/lcwlog -# github.com/lwahlmeier/pyfmt v0.0.1 -## explicit; go 1.16 +# github.com/lwahlmeier/pyfmt v0.2.0 +## explicit; go 1.19 github.com/lwahlmeier/pyfmt +# github.com/lwahlmeier/unboundChannel v1.0.0 +## explicit; go 1.19 +github.com/lwahlmeier/unboundChannel # github.com/magiconair/properties v1.8.6 ## explicit; go 1.13 github.com/magiconair/properties @@ -78,7 +82,6 @@ github.com/spf13/viper github.com/stretchr/testify/assert # github.com/tevino/abool v1.2.0 ## explicit; go 1.14 -github.com/tevino/abool # golang.org/x/net v0.0.0-20220909164309-bea034e7d591 ## explicit; go 1.17 golang.org/x/net/http/httpguts