From a8e266465cbcd5e106433feec3e8710ac3bdf661 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 6 Jun 2018 19:18:38 -0400 Subject: [PATCH] Switch from nu7hatch/gouuid to satori/go.uuid. The former is unmaintained and does not follow the UUID spec. --- Gopkg.lock | 26 +- Gopkg.toml | 2 +- messages.go | 2 +- vendor/github.com/nu7hatch/gouuid/.gitignore | 11 - vendor/github.com/nu7hatch/gouuid/COPYING | 19 - vendor/github.com/nu7hatch/gouuid/README.md | 21 - .../nu7hatch/gouuid/example_test.go | 33 -- vendor/github.com/nu7hatch/gouuid/uuid.go | 173 -------- .../github.com/nu7hatch/gouuid/uuid_test.go | 135 ------- vendor/github.com/satori/go.uuid/.travis.yml | 23 ++ vendor/github.com/satori/go.uuid/LICENSE | 20 + vendor/github.com/satori/go.uuid/README.md | 74 ++++ vendor/github.com/satori/go.uuid/codec.go | 206 ++++++++++ .../github.com/satori/go.uuid/codec_test.go | 251 ++++++++++++ vendor/github.com/satori/go.uuid/generator.go | 265 +++++++++++++ .../satori/go.uuid/generator_test.go | 224 +++++++++++ vendor/github.com/satori/go.uuid/sql.go | 78 ++++ vendor/github.com/satori/go.uuid/sql_test.go | 136 +++++++ vendor/github.com/satori/go.uuid/uuid.go | 161 ++++++++ vendor/github.com/satori/go.uuid/uuid_test.go | 100 +++++ vendor/golang.org/x/sync/AUTHORS | 3 - vendor/golang.org/x/sync/CONTRIBUTING.md | 31 -- vendor/golang.org/x/sync/CONTRIBUTORS | 3 - vendor/golang.org/x/sync/LICENSE | 27 -- vendor/golang.org/x/sync/PATENTS | 22 -- vendor/golang.org/x/sync/README | 2 - vendor/golang.org/x/sync/codereview.cfg | 1 - vendor/golang.org/x/sync/errgroup/errgroup.go | 67 ---- .../errgroup/errgroup_example_md5all_test.go | 101 ----- .../x/sync/errgroup/errgroup_test.go | 176 --------- .../golang.org/x/sync/semaphore/semaphore.go | 131 ------ .../x/sync/semaphore/semaphore_bench_test.go | 130 ------ .../x/sync/semaphore/semaphore_test.go | 170 -------- .../x/sync/singleflight/singleflight.go | 111 ------ .../x/sync/singleflight/singleflight_test.go | 87 ---- vendor/golang.org/x/sync/syncmap/map.go | 372 ------------------ .../x/sync/syncmap/map_bench_test.go | 216 ---------- .../x/sync/syncmap/map_reference_test.go | 151 ------- vendor/golang.org/x/sync/syncmap/map_test.go | 172 -------- 39 files changed, 1555 insertions(+), 2378 deletions(-) delete mode 100644 vendor/github.com/nu7hatch/gouuid/.gitignore delete mode 100644 vendor/github.com/nu7hatch/gouuid/COPYING delete mode 100644 vendor/github.com/nu7hatch/gouuid/README.md delete mode 100644 vendor/github.com/nu7hatch/gouuid/example_test.go delete mode 100644 vendor/github.com/nu7hatch/gouuid/uuid.go delete mode 100644 vendor/github.com/nu7hatch/gouuid/uuid_test.go create mode 100644 vendor/github.com/satori/go.uuid/.travis.yml create mode 100644 vendor/github.com/satori/go.uuid/LICENSE create mode 100644 vendor/github.com/satori/go.uuid/README.md create mode 100644 vendor/github.com/satori/go.uuid/codec.go create mode 100644 vendor/github.com/satori/go.uuid/codec_test.go create mode 100644 vendor/github.com/satori/go.uuid/generator.go create mode 100644 vendor/github.com/satori/go.uuid/generator_test.go create mode 100644 vendor/github.com/satori/go.uuid/sql.go create mode 100644 vendor/github.com/satori/go.uuid/sql_test.go create mode 100644 vendor/github.com/satori/go.uuid/uuid.go create mode 100644 vendor/github.com/satori/go.uuid/uuid_test.go delete mode 100644 vendor/golang.org/x/sync/AUTHORS delete mode 100644 vendor/golang.org/x/sync/CONTRIBUTING.md delete mode 100644 vendor/golang.org/x/sync/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/sync/LICENSE delete mode 100644 vendor/golang.org/x/sync/PATENTS delete mode 100644 vendor/golang.org/x/sync/README delete mode 100644 vendor/golang.org/x/sync/codereview.cfg delete mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go delete mode 100644 vendor/golang.org/x/sync/errgroup/errgroup_example_md5all_test.go delete mode 100644 vendor/golang.org/x/sync/errgroup/errgroup_test.go delete mode 100644 vendor/golang.org/x/sync/semaphore/semaphore.go delete mode 100644 vendor/golang.org/x/sync/semaphore/semaphore_bench_test.go delete mode 100644 vendor/golang.org/x/sync/semaphore/semaphore_test.go delete mode 100644 vendor/golang.org/x/sync/singleflight/singleflight.go delete mode 100644 vendor/golang.org/x/sync/singleflight/singleflight_test.go delete mode 100644 vendor/golang.org/x/sync/syncmap/map.go delete mode 100644 vendor/golang.org/x/sync/syncmap/map_bench_test.go delete mode 100644 vendor/golang.org/x/sync/syncmap/map_reference_test.go delete mode 100644 vendor/golang.org/x/sync/syncmap/map_test.go diff --git a/Gopkg.lock b/Gopkg.lock index 995b961..11fafb3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -4,15 +4,19 @@ [[projects]] branch = "master" name = "github.com/cosmos72/gomacro" - packages = ["ast2","base","classic","fast","imports","parser","scanner","token","typeutil","xreflect"] + packages = [ + "ast2", + "base", + "fast", + "imports", + "parser", + "scanner", + "token", + "typeutil", + "xreflect" + ] revision = "b90dd5143957e920ac0ce87f9a3277bbc3ce1641" -[[projects]] - branch = "master" - name = "github.com/nu7hatch/gouuid" - packages = ["."] - revision = "179d4d0c4d8d407a32af483c2354df1d2c91e6c3" - [[projects]] branch = "master" name = "github.com/pebbe/zmq4" @@ -21,13 +25,13 @@ [[projects]] branch = "master" - name = "golang.org/x/sync" - packages = ["syncmap"] - revision = "f52d1811a62927559de87708c8913c1650ce4f26" + name = "github.com/satori/go.uuid" + packages = ["."] + revision = "36e9d2ebbde5e3f13ab2e25625fd453271d6522e" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "fa5d7d9ec51b9210ed3ca68de1105ddbbc070a941c737b3955518eaee951d10c" + inputs-digest = "53e3da38a3acce499a02845a078f89024d8ff6be247ace4f231a8e540cab4b99" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 81cb874..8fdb8e4 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,7 +27,7 @@ [[constraint]] branch = "master" - name = "github.com/nu7hatch/gouuid" + name = "github.com/satori/go.uuid" [[constraint]] branch = "master" diff --git a/messages.go b/messages.go index 3b6b2f6..c26907b 100644 --- a/messages.go +++ b/messages.go @@ -7,7 +7,7 @@ import ( "encoding/json" "time" - "github.com/nu7hatch/gouuid" + "github.com/satori/go.uuid" zmq "github.com/pebbe/zmq4" ) diff --git a/vendor/github.com/nu7hatch/gouuid/.gitignore b/vendor/github.com/nu7hatch/gouuid/.gitignore deleted file mode 100644 index f9d9cd8..0000000 --- a/vendor/github.com/nu7hatch/gouuid/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -_obj -_test -*.6 -*.out -_testmain.go -\#* -.\#* -*.log -_cgo* -*.o -*.a diff --git a/vendor/github.com/nu7hatch/gouuid/COPYING b/vendor/github.com/nu7hatch/gouuid/COPYING deleted file mode 100644 index d7849fd..0000000 --- a/vendor/github.com/nu7hatch/gouuid/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2011 by Krzysztof Kowalik - -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. \ No newline at end of file diff --git a/vendor/github.com/nu7hatch/gouuid/README.md b/vendor/github.com/nu7hatch/gouuid/README.md deleted file mode 100644 index e3d025d..0000000 --- a/vendor/github.com/nu7hatch/gouuid/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Pure Go UUID implementation - -This package provides immutable UUID structs and the functions -NewV3, NewV4, NewV5 and Parse() for generating versions 3, 4 -and 5 UUIDs as specified in [RFC 4122](http://www.ietf.org/rfc/rfc4122.txt). - -## Installation - -Use the `go` tool: - - $ go get github.com/nu7hatch/gouuid - -## Usage - -See [documentation and examples](http://godoc.org/github.com/nu7hatch/gouuid) -for more information. - -## Copyright - -Copyright (C) 2011 by Krzysztof Kowalik . See [COPYING](https://github.com/nu7hatch/gouuid/tree/master/COPYING) -file for details. diff --git a/vendor/github.com/nu7hatch/gouuid/example_test.go b/vendor/github.com/nu7hatch/gouuid/example_test.go deleted file mode 100644 index 9e86fdc..0000000 --- a/vendor/github.com/nu7hatch/gouuid/example_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package uuid_test - -import ( - "fmt" - "github.com/nu7hatch/gouuid" -) - -func ExampleNewV4() { - u4, err := uuid.NewV4() - if err != nil { - fmt.Println("error:", err) - return - } - fmt.Println(u4) -} - -func ExampleNewV5() { - u5, err := uuid.NewV5(uuid.NamespaceURL, []byte("nu7hat.ch")) - if err != nil { - fmt.Println("error:", err) - return - } - fmt.Println(u5) -} - -func ExampleParseHex() { - u, err := uuid.ParseHex("6ba7b810-9dad-11d1-80b4-00c04fd430c8") - if err != nil { - fmt.Println("error:", err) - return - } - fmt.Println(u) -} diff --git a/vendor/github.com/nu7hatch/gouuid/uuid.go b/vendor/github.com/nu7hatch/gouuid/uuid.go deleted file mode 100644 index ac9623b..0000000 --- a/vendor/github.com/nu7hatch/gouuid/uuid.go +++ /dev/null @@ -1,173 +0,0 @@ -// This package provides immutable UUID structs and the functions -// NewV3, NewV4, NewV5 and Parse() for generating versions 3, 4 -// and 5 UUIDs as specified in RFC 4122. -// -// Copyright (C) 2011 by Krzysztof Kowalik -package uuid - -import ( - "crypto/md5" - "crypto/rand" - "crypto/sha1" - "encoding/hex" - "errors" - "fmt" - "hash" - "regexp" -) - -// The UUID reserved variants. -const ( - ReservedNCS byte = 0x80 - ReservedRFC4122 byte = 0x40 - ReservedMicrosoft byte = 0x20 - ReservedFuture byte = 0x00 -) - -// The following standard UUIDs are for use with NewV3() or NewV5(). -var ( - NamespaceDNS, _ = ParseHex("6ba7b810-9dad-11d1-80b4-00c04fd430c8") - NamespaceURL, _ = ParseHex("6ba7b811-9dad-11d1-80b4-00c04fd430c8") - NamespaceOID, _ = ParseHex("6ba7b812-9dad-11d1-80b4-00c04fd430c8") - NamespaceX500, _ = ParseHex("6ba7b814-9dad-11d1-80b4-00c04fd430c8") -) - -// Pattern used to parse hex string representation of the UUID. -// FIXME: do something to consider both brackets at one time, -// current one allows to parse string with only one opening -// or closing bracket. -const hexPattern = "^(urn\\:uuid\\:)?\\{?([a-z0-9]{8})-([a-z0-9]{4})-" + - "([1-5][a-z0-9]{3})-([a-z0-9]{4})-([a-z0-9]{12})\\}?$" - -var re = regexp.MustCompile(hexPattern) - -// A UUID representation compliant with specification in -// RFC 4122 document. -type UUID [16]byte - -// ParseHex creates a UUID object from given hex string -// representation. Function accepts UUID string in following -// formats: -// -// uuid.ParseHex("6ba7b814-9dad-11d1-80b4-00c04fd430c8") -// uuid.ParseHex("{6ba7b814-9dad-11d1-80b4-00c04fd430c8}") -// uuid.ParseHex("urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8") -// -func ParseHex(s string) (u *UUID, err error) { - md := re.FindStringSubmatch(s) - if md == nil { - err = errors.New("Invalid UUID string") - return - } - hash := md[2] + md[3] + md[4] + md[5] + md[6] - b, err := hex.DecodeString(hash) - if err != nil { - return - } - u = new(UUID) - copy(u[:], b) - return -} - -// Parse creates a UUID object from given bytes slice. -func Parse(b []byte) (u *UUID, err error) { - if len(b) != 16 { - err = errors.New("Given slice is not valid UUID sequence") - return - } - u = new(UUID) - copy(u[:], b) - return -} - -// Generate a UUID based on the MD5 hash of a namespace identifier -// and a name. -func NewV3(ns *UUID, name []byte) (u *UUID, err error) { - if ns == nil { - err = errors.New("Invalid namespace UUID") - return - } - u = new(UUID) - // Set all bits to MD5 hash generated from namespace and name. - u.setBytesFromHash(md5.New(), ns[:], name) - u.setVariant(ReservedRFC4122) - u.setVersion(3) - return -} - -// Generate a random UUID. -func NewV4() (u *UUID, err error) { - u = new(UUID) - // Set all bits to randomly (or pseudo-randomly) chosen values. - _, err = rand.Read(u[:]) - if err != nil { - return - } - u.setVariant(ReservedRFC4122) - u.setVersion(4) - return -} - -// Generate a UUID based on the SHA-1 hash of a namespace identifier -// and a name. -func NewV5(ns *UUID, name []byte) (u *UUID, err error) { - u = new(UUID) - // Set all bits to truncated SHA1 hash generated from namespace - // and name. - u.setBytesFromHash(sha1.New(), ns[:], name) - u.setVariant(ReservedRFC4122) - u.setVersion(5) - return -} - -// Generate a MD5 hash of a namespace and a name, and copy it to the -// UUID slice. -func (u *UUID) setBytesFromHash(hash hash.Hash, ns, name []byte) { - hash.Write(ns[:]) - hash.Write(name) - copy(u[:], hash.Sum([]byte{})[:16]) -} - -// Set the two most significant bits (bits 6 and 7) of the -// clock_seq_hi_and_reserved to zero and one, respectively. -func (u *UUID) setVariant(v byte) { - switch v { - case ReservedNCS: - u[8] = (u[8] | ReservedNCS) & 0xBF - case ReservedRFC4122: - u[8] = (u[8] | ReservedRFC4122) & 0x7F - case ReservedMicrosoft: - u[8] = (u[8] | ReservedMicrosoft) & 0x3F - } -} - -// Variant returns the UUID Variant, which determines the internal -// layout of the UUID. This will be one of the constants: RESERVED_NCS, -// RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE. -func (u *UUID) Variant() byte { - if u[8]&ReservedNCS == ReservedNCS { - return ReservedNCS - } else if u[8]&ReservedRFC4122 == ReservedRFC4122 { - return ReservedRFC4122 - } else if u[8]&ReservedMicrosoft == ReservedMicrosoft { - return ReservedMicrosoft - } - return ReservedFuture -} - -// Set the four most significant bits (bits 12 through 15) of the -// time_hi_and_version field to the 4-bit version number. -func (u *UUID) setVersion(v byte) { - u[6] = (u[6] & 0xF) | (v << 4) -} - -// Version returns a version number of the algorithm used to -// generate the UUID sequence. -func (u *UUID) Version() uint { - return uint(u[6] >> 4) -} - -// Returns unparsed version of the generated UUID sequence. -func (u *UUID) String() string { - return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) -} diff --git a/vendor/github.com/nu7hatch/gouuid/uuid_test.go b/vendor/github.com/nu7hatch/gouuid/uuid_test.go deleted file mode 100644 index 70ed346..0000000 --- a/vendor/github.com/nu7hatch/gouuid/uuid_test.go +++ /dev/null @@ -1,135 +0,0 @@ -// This package provides immutable UUID structs and the functions -// NewV3, NewV4, NewV5 and Parse() for generating versions 3, 4 -// and 5 UUIDs as specified in RFC 4122. -// -// Copyright (C) 2011 by Krzysztof Kowalik -package uuid - -import ( - "regexp" - "testing" -) - -const format = "^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$" - -func TestParse(t *testing.T) { - _, err := Parse([]byte{1, 2, 3, 4, 5}) - if err == nil { - t.Errorf("Expected error due to invalid UUID sequence") - } - base, _ := NewV4() - u, err := Parse(base[:]) - if err != nil { - t.Errorf("Expected to parse UUID sequence without problems") - return - } - if u.String() != base.String() { - t.Errorf("Expected parsed UUID to be the same as base, %s != %s", u.String(), base.String()) - } -} - -func TestParseString(t *testing.T) { - _, err := ParseHex("foo") - if err == nil { - t.Errorf("Expected error due to invalid UUID string") - } - base, _ := NewV4() - u, err := ParseHex(base.String()) - if err != nil { - t.Errorf("Expected to parse UUID sequence without problems") - return - } - if u.String() != base.String() { - t.Errorf("Expected parsed UUID to be the same as base, %s != %s", u.String(), base.String()) - } -} - -func TestNewV3(t *testing.T) { - u, err := NewV3(NamespaceURL, []byte("golang.org")) - if err != nil { - t.Errorf("Expected to generate UUID without problems, error thrown: %d", err.Error()) - return - } - if u.Version() != 3 { - t.Errorf("Expected to generate UUIDv3, given %d", u.Version()) - } - if u.Variant() != ReservedRFC4122 { - t.Errorf("Expected to generate UUIDv3 RFC4122 variant, given %x", u.Variant()) - } - re := regexp.MustCompile(format) - if !re.MatchString(u.String()) { - t.Errorf("Expected string representation to be valid, given %s", u.String()) - } - u2, _ := NewV3(NamespaceURL, []byte("golang.org")) - if u2.String() != u.String() { - t.Errorf("Expected UUIDs generated of the same namespace and name to be the same") - } - u3, _ := NewV3(NamespaceDNS, []byte("golang.org")) - if u3.String() == u.String() { - t.Errorf("Expected UUIDs generated of different namespace and the same name to be different") - } - u4, _ := NewV3(NamespaceURL, []byte("code.google.com")) - if u4.String() == u.String() { - t.Errorf("Expected UUIDs generated of the same namespace and different names to be different") - } -} - -func TestNewV4(t *testing.T) { - u, err := NewV4() - if err != nil { - t.Errorf("Expected to generate UUID without problems, error thrown: %s", err.Error()) - return - } - if u.Version() != 4 { - t.Errorf("Expected to generate UUIDv4, given %d", u.Version()) - } - if u.Variant() != ReservedRFC4122 { - t.Errorf("Expected to generate UUIDv4 RFC4122 variant, given %x", u.Variant()) - } - re := regexp.MustCompile(format) - if !re.MatchString(u.String()) { - t.Errorf("Expected string representation to be valid, given %s", u.String()) - } -} - -func TestNewV5(t *testing.T) { - u, err := NewV5(NamespaceURL, []byte("golang.org")) - if err != nil { - t.Errorf("Expected to generate UUID without problems, error thrown: %d", err.Error()) - return - } - if u.Version() != 5 { - t.Errorf("Expected to generate UUIDv5, given %d", u.Version()) - } - if u.Variant() != ReservedRFC4122 { - t.Errorf("Expected to generate UUIDv5 RFC4122 variant, given %x", u.Variant()) - } - re := regexp.MustCompile(format) - if !re.MatchString(u.String()) { - t.Errorf("Expected string representation to be valid, given %s", u.String()) - } - u2, _ := NewV5(NamespaceURL, []byte("golang.org")) - if u2.String() != u.String() { - t.Errorf("Expected UUIDs generated of the same namespace and name to be the same") - } - u3, _ := NewV5(NamespaceDNS, []byte("golang.org")) - if u3.String() == u.String() { - t.Errorf("Expected UUIDs generated of different namespace and the same name to be different") - } - u4, _ := NewV5(NamespaceURL, []byte("code.google.com")) - if u4.String() == u.String() { - t.Errorf("Expected UUIDs generated of the same namespace and different names to be different") - } -} - -func BenchmarkParseHex(b *testing.B) { - s := "f3593cff-ee92-40df-4086-87825b523f13" - for i := 0; i < b.N; i++ { - _, err := ParseHex(s) - if err != nil { - b.Fatal(err) - } - } - b.StopTimer() - b.ReportAllocs() -} diff --git a/vendor/github.com/satori/go.uuid/.travis.yml b/vendor/github.com/satori/go.uuid/.travis.yml new file mode 100644 index 0000000..20dd53b --- /dev/null +++ b/vendor/github.com/satori/go.uuid/.travis.yml @@ -0,0 +1,23 @@ +language: go +sudo: false +go: + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - 1.7 + - 1.8 + - 1.9 + - tip +matrix: + allow_failures: + - go: tip + fast_finish: true +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -service=travis-ci +notifications: + email: false diff --git a/vendor/github.com/satori/go.uuid/LICENSE b/vendor/github.com/satori/go.uuid/LICENSE new file mode 100644 index 0000000..926d549 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2013-2018 by Maxim Bublis + +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/satori/go.uuid/README.md b/vendor/github.com/satori/go.uuid/README.md new file mode 100644 index 0000000..7702849 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/README.md @@ -0,0 +1,74 @@ +# UUID package for Go language + +[![Build Status](https://travis-ci.org/satori/go.uuid.svg?branch=master)](https://travis-ci.org/satori/go.uuid) +[![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid) +[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.svg)](http://godoc.org/github.com/satori/go.uuid) + +This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. + +With 100% test coverage and benchmarks out of box. + +Supported versions: +* Version 1, based on timestamp and MAC address (RFC 4122) +* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) +* Version 3, based on MD5 hashing (RFC 4122) +* Version 4, based on random numbers (RFC 4122) +* Version 5, based on SHA-1 hashing (RFC 4122) + +## Installation + +Use the `go` command: + + $ go get github.com/satori/go.uuid + +## Requirements + +UUID package requires Go >= 1.2. + +## Example + +```go +package main + +import ( + "fmt" + "github.com/satori/go.uuid" +) + +func main() { + // Creating UUID Version 4 + // panic on error + u1 := uuid.Must(uuid.NewV4()) + fmt.Printf("UUIDv4: %s\n", u1) + + // or error handling + u2, err := uuid.NewV4() + if err != nil { + fmt.Printf("Something went wrong: %s", err) + return + } + fmt.Printf("UUIDv4: %s\n", u2) + + // Parsing UUID from string input + u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + if err != nil { + fmt.Printf("Something went wrong: %s", err) + } + fmt.Printf("Successfully parsed: %s", u2) +} +``` + +## Documentation + +[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. + +## Links +* [RFC 4122](http://tools.ietf.org/html/rfc4122) +* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) + +## Copyright + +Copyright (C) 2013-2018 by Maxim Bublis . + +UUID package released under MIT License. +See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. diff --git a/vendor/github.com/satori/go.uuid/codec.go b/vendor/github.com/satori/go.uuid/codec.go new file mode 100644 index 0000000..656892c --- /dev/null +++ b/vendor/github.com/satori/go.uuid/codec.go @@ -0,0 +1,206 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "bytes" + "encoding/hex" + "fmt" +) + +// FromBytes returns UUID converted from raw byte slice input. +// It will return error if the slice isn't 16 bytes long. +func FromBytes(input []byte) (u UUID, err error) { + err = u.UnmarshalBinary(input) + return +} + +// FromBytesOrNil returns UUID converted from raw byte slice input. +// Same behavior as FromBytes, but returns a Nil UUID on error. +func FromBytesOrNil(input []byte) UUID { + uuid, err := FromBytes(input) + if err != nil { + return Nil + } + return uuid +} + +// FromString returns UUID parsed from string input. +// Input is expected in a form accepted by UnmarshalText. +func FromString(input string) (u UUID, err error) { + err = u.UnmarshalText([]byte(input)) + return +} + +// FromStringOrNil returns UUID parsed from string input. +// Same behavior as FromString, but returns a Nil UUID on error. +func FromStringOrNil(input string) UUID { + uuid, err := FromString(input) + if err != nil { + return Nil + } + return uuid +} + +// MarshalText implements the encoding.TextMarshaler interface. +// The encoding is the same as returned by String. +func (u UUID) MarshalText() (text []byte, err error) { + text = []byte(u.String()) + return +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Following formats are supported: +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +// "6ba7b8109dad11d180b400c04fd430c8" +// ABNF for supported UUID text representation follows: +// uuid := canonical | hashlike | braced | urn +// plain := canonical | hashlike +// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct +// hashlike := 12hexoct +// braced := '{' plain '}' +// urn := URN ':' UUID-NID ':' plain +// URN := 'urn' +// UUID-NID := 'uuid' +// 12hexoct := 6hexoct 6hexoct +// 6hexoct := 4hexoct 2hexoct +// 4hexoct := 2hexoct 2hexoct +// 2hexoct := hexoct hexoct +// hexoct := hexdig hexdig +// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | +// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +func (u *UUID) UnmarshalText(text []byte) (err error) { + switch len(text) { + case 32: + return u.decodeHashLike(text) + case 36: + return u.decodeCanonical(text) + case 38: + return u.decodeBraced(text) + case 41: + fallthrough + case 45: + return u.decodeURN(text) + default: + return fmt.Errorf("uuid: incorrect UUID length: %s", text) + } +} + +// decodeCanonical decodes UUID string in format +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8". +func (u *UUID) decodeCanonical(t []byte) (err error) { + if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { + return fmt.Errorf("uuid: incorrect UUID format %s", t) + } + + src := t[:] + dst := u[:] + + for i, byteGroup := range byteGroups { + if i > 0 { + src = src[1:] // skip dash + } + _, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup]) + if err != nil { + return + } + src = src[byteGroup:] + dst = dst[byteGroup/2:] + } + + return +} + +// decodeHashLike decodes UUID string in format +// "6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodeHashLike(t []byte) (err error) { + src := t[:] + dst := u[:] + + if _, err = hex.Decode(dst, src); err != nil { + return err + } + return +} + +// decodeBraced decodes UUID string in format +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format +// "{6ba7b8109dad11d180b400c04fd430c8}". +func (u *UUID) decodeBraced(t []byte) (err error) { + l := len(t) + + if t[0] != '{' || t[l-1] != '}' { + return fmt.Errorf("uuid: incorrect UUID format %s", t) + } + + return u.decodePlain(t[1 : l-1]) +} + +// decodeURN decodes UUID string in format +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format +// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodeURN(t []byte) (err error) { + total := len(t) + + urn_uuid_prefix := t[:9] + + if !bytes.Equal(urn_uuid_prefix, urnPrefix) { + return fmt.Errorf("uuid: incorrect UUID format: %s", t) + } + + return u.decodePlain(t[9:total]) +} + +// decodePlain decodes UUID string in canonical format +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format +// "6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodePlain(t []byte) (err error) { + switch len(t) { + case 32: + return u.decodeHashLike(t) + case 36: + return u.decodeCanonical(t) + default: + return fmt.Errorf("uuid: incorrrect UUID length: %s", t) + } +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (u UUID) MarshalBinary() (data []byte, err error) { + data = u.Bytes() + return +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +// It will return error if the slice isn't 16 bytes long. +func (u *UUID) UnmarshalBinary(data []byte) (err error) { + if len(data) != Size { + err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) + return + } + copy(u[:], data) + + return +} diff --git a/vendor/github.com/satori/go.uuid/codec_test.go b/vendor/github.com/satori/go.uuid/codec_test.go new file mode 100644 index 0000000..7158c09 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/codec_test.go @@ -0,0 +1,251 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "bytes" + + . "gopkg.in/check.v1" +) + +type codecTestSuite struct{} + +var _ = Suite(&codecTestSuite{}) + +func (s *codecTestSuite) TestFromBytes(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + u1, err := FromBytes(b1) + c.Assert(err, IsNil) + c.Assert(u1, Equals, u) + + b2 := []byte{} + _, err = FromBytes(b2) + c.Assert(err, NotNil) +} + +func (s *codecTestSuite) BenchmarkFromBytes(c *C) { + bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + for i := 0; i < c.N; i++ { + FromBytes(bytes) + } +} + +func (s *codecTestSuite) TestMarshalBinary(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + b2, err := u.MarshalBinary() + c.Assert(err, IsNil) + c.Assert(bytes.Equal(b1, b2), Equals, true) +} + +func (s *codecTestSuite) BenchmarkMarshalBinary(c *C) { + u, err := NewV4() + c.Assert(err, IsNil) + for i := 0; i < c.N; i++ { + u.MarshalBinary() + } +} + +func (s *codecTestSuite) TestUnmarshalBinary(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + u1 := UUID{} + err := u1.UnmarshalBinary(b1) + c.Assert(err, IsNil) + c.Assert(u1, Equals, u) + + b2 := []byte{} + u2 := UUID{} + err = u2.UnmarshalBinary(b2) + c.Assert(err, NotNil) +} + +func (s *codecTestSuite) TestFromString(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" + s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" + s4 := "6ba7b8109dad11d180b400c04fd430c8" + s5 := "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" + + _, err := FromString("") + c.Assert(err, NotNil) + + u1, err := FromString(s1) + c.Assert(err, IsNil) + c.Assert(u1, Equals, u) + + u2, err := FromString(s2) + c.Assert(err, IsNil) + c.Assert(u2, Equals, u) + + u3, err := FromString(s3) + c.Assert(err, IsNil) + c.Assert(u3, Equals, u) + + u4, err := FromString(s4) + c.Assert(err, IsNil) + c.Assert(u4, Equals, u) + + u5, err := FromString(s5) + c.Assert(err, IsNil) + c.Assert(u5, Equals, u) +} + +func (s *codecTestSuite) BenchmarkFromString(c *C) { + str := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + for i := 0; i < c.N; i++ { + FromString(str) + } +} + +func (s *codecTestSuite) BenchmarkFromStringUrn(c *C) { + str := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" + for i := 0; i < c.N; i++ { + FromString(str) + } +} + +func (s *codecTestSuite) BenchmarkFromStringWithBrackets(c *C) { + str := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" + for i := 0; i < c.N; i++ { + FromString(str) + } +} + +func (s *codecTestSuite) TestFromStringShort(c *C) { + // Invalid 35-character UUID string + s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c" + + for i := len(s1); i >= 0; i-- { + _, err := FromString(s1[:i]) + c.Assert(err, NotNil) + } +} + +func (s *codecTestSuite) TestFromStringLong(c *C) { + // Invalid 37+ character UUID string + strings := []string{ + "6ba7b810-9dad-11d1-80b4-00c04fd430c8=", + "6ba7b810-9dad-11d1-80b4-00c04fd430c8}", + "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}f", + "6ba7b810-9dad-11d1-80b4-00c04fd430c800c04fd430c8", + } + + for _, str := range strings { + _, err := FromString(str) + c.Assert(err, NotNil) + } +} + +func (s *codecTestSuite) TestFromStringInvalid(c *C) { + // Invalid UUID string formats + strings := []string{ + "6ba7b8109dad11d180b400c04fd430c86ba7b8109dad11d180b400c04fd430c8", + "urn:uuid:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", + "uuid:urn:6ba7b810-9dad-11d1-80b4-00c04fd430c8", + "uuid:urn:6ba7b8109dad11d180b400c04fd430c8", + "6ba7b8109-dad-11d1-80b4-00c04fd430c8", + "6ba7b810-9dad1-1d1-80b4-00c04fd430c8", + "6ba7b810-9dad-11d18-0b4-00c04fd430c8", + "6ba7b810-9dad-11d1-80b40-0c04fd430c8", + "6ba7b810+9dad+11d1+80b4+00c04fd430c8", + "(6ba7b810-9dad-11d1-80b4-00c04fd430c8}", + "{6ba7b810-9dad-11d1-80b4-00c04fd430c8>", + "zba7b810-9dad-11d1-80b4-00c04fd430c8", + "6ba7b810-9dad11d180b400c04fd430c8", + "6ba7b8109dad-11d180b400c04fd430c8", + "6ba7b8109dad11d1-80b400c04fd430c8", + "6ba7b8109dad11d180b4-00c04fd430c8", + } + + for _, str := range strings { + _, err := FromString(str) + c.Assert(err, NotNil) + } +} + +func (s *codecTestSuite) TestFromStringOrNil(c *C) { + u := FromStringOrNil("") + c.Assert(u, Equals, Nil) +} + +func (s *codecTestSuite) TestFromBytesOrNil(c *C) { + b := []byte{} + u := FromBytesOrNil(b) + c.Assert(u, Equals, Nil) +} + +func (s *codecTestSuite) TestMarshalText(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + + b2, err := u.MarshalText() + c.Assert(err, IsNil) + c.Assert(bytes.Equal(b1, b2), Equals, true) +} + +func (s *codecTestSuite) BenchmarkMarshalText(c *C) { + u, err := NewV4() + c.Assert(err, IsNil) + for i := 0; i < c.N; i++ { + u.MarshalText() + } +} + +func (s *codecTestSuite) TestUnmarshalText(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + + u1 := UUID{} + err := u1.UnmarshalText(b1) + c.Assert(err, IsNil) + c.Assert(u1, Equals, u) + + b2 := []byte("") + u2 := UUID{} + err = u2.UnmarshalText(b2) + c.Assert(err, NotNil) +} + +func (s *codecTestSuite) BenchmarkUnmarshalText(c *C) { + bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + u := UUID{} + for i := 0; i < c.N; i++ { + u.UnmarshalText(bytes) + } +} + +var sink string + +func (s *codecTestSuite) BenchmarkMarshalToString(c *C) { + u, err := NewV4() + c.Assert(err, IsNil) + for i := 0; i < c.N; i++ { + sink = u.String() + } +} diff --git a/vendor/github.com/satori/go.uuid/generator.go b/vendor/github.com/satori/go.uuid/generator.go new file mode 100644 index 0000000..499dc35 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/generator.go @@ -0,0 +1,265 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "crypto/md5" + "crypto/rand" + "crypto/sha1" + "encoding/binary" + "fmt" + "hash" + "io" + "net" + "os" + "sync" + "time" +) + +// Difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). +const epochStart = 122192928000000000 + +type epochFunc func() time.Time +type hwAddrFunc func() (net.HardwareAddr, error) + +var ( + global = newRFC4122Generator() + + posixUID = uint32(os.Getuid()) + posixGID = uint32(os.Getgid()) +) + +// NewV1 returns UUID based on current timestamp and MAC address. +func NewV1() (UUID, error) { + return global.NewV1() +} + +// NewV2 returns DCE Security UUID based on POSIX UID/GID. +func NewV2(domain byte) (UUID, error) { + return global.NewV2(domain) +} + +// NewV3 returns UUID based on MD5 hash of namespace UUID and name. +func NewV3(ns UUID, name string) UUID { + return global.NewV3(ns, name) +} + +// NewV4 returns random generated UUID. +func NewV4() (UUID, error) { + return global.NewV4() +} + +// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. +func NewV5(ns UUID, name string) UUID { + return global.NewV5(ns, name) +} + +// Generator provides interface for generating UUIDs. +type Generator interface { + NewV1() (UUID, error) + NewV2(domain byte) (UUID, error) + NewV3(ns UUID, name string) UUID + NewV4() (UUID, error) + NewV5(ns UUID, name string) UUID +} + +// Default generator implementation. +type rfc4122Generator struct { + clockSequenceOnce sync.Once + hardwareAddrOnce sync.Once + storageMutex sync.Mutex + + rand io.Reader + + epochFunc epochFunc + hwAddrFunc hwAddrFunc + lastTime uint64 + clockSequence uint16 + hardwareAddr [6]byte +} + +func newRFC4122Generator() Generator { + return &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: defaultHWAddrFunc, + rand: rand.Reader, + } +} + +// NewV1 returns UUID based on current timestamp and MAC address. +func (g *rfc4122Generator) NewV1() (UUID, error) { + u := UUID{} + + timeNow, clockSeq, err := g.getClockSequence() + if err != nil { + return Nil, err + } + binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + + hardwareAddr, err := g.getHardwareAddr() + if err != nil { + return Nil, err + } + copy(u[10:], hardwareAddr) + + u.SetVersion(V1) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV2 returns DCE Security UUID based on POSIX UID/GID. +func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) { + u, err := g.NewV1() + if err != nil { + return Nil, err + } + + switch domain { + case DomainPerson: + binary.BigEndian.PutUint32(u[:], posixUID) + case DomainGroup: + binary.BigEndian.PutUint32(u[:], posixGID) + } + + u[9] = domain + + u.SetVersion(V2) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV3 returns UUID based on MD5 hash of namespace UUID and name. +func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID { + u := newFromHash(md5.New(), ns, name) + u.SetVersion(V3) + u.SetVariant(VariantRFC4122) + + return u +} + +// NewV4 returns random generated UUID. +func (g *rfc4122Generator) NewV4() (UUID, error) { + u := UUID{} + if _, err := g.rand.Read(u[:]); err != nil { + return Nil, err + } + u.SetVersion(V4) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. +func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID { + u := newFromHash(sha1.New(), ns, name) + u.SetVersion(V5) + u.SetVariant(VariantRFC4122) + + return u +} + +// Returns epoch and clock sequence. +func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) { + var err error + g.clockSequenceOnce.Do(func() { + buf := make([]byte, 2) + if _, err = g.rand.Read(buf); err != nil { + return + } + g.clockSequence = binary.BigEndian.Uint16(buf) + }) + if err != nil { + return 0, 0, err + } + + g.storageMutex.Lock() + defer g.storageMutex.Unlock() + + timeNow := g.getEpoch() + // Clock didn't change since last UUID generation. + // Should increase clock sequence. + if timeNow <= g.lastTime { + g.clockSequence++ + } + g.lastTime = timeNow + + return timeNow, g.clockSequence, nil +} + +// Returns hardware address. +func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) { + var err error + g.hardwareAddrOnce.Do(func() { + if hwAddr, err := g.hwAddrFunc(); err == nil { + copy(g.hardwareAddr[:], hwAddr) + return + } + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence. + if _, err = g.rand.Read(g.hardwareAddr[:]); err != nil { + return + } + // Set multicast bit as recommended by RFC 4122 + g.hardwareAddr[0] |= 0x01 + }) + if err != nil { + return []byte{}, err + } + return g.hardwareAddr[:], nil +} + +// Returns difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and current time. +func (g *rfc4122Generator) getEpoch() uint64 { + return epochStart + uint64(g.epochFunc().UnixNano()/100) +} + +// Returns UUID based on hashing of namespace UUID and name. +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} + +// Returns hardware address. +func defaultHWAddrFunc() (net.HardwareAddr, error) { + ifaces, err := net.Interfaces() + if err != nil { + return []byte{}, err + } + for _, iface := range ifaces { + if len(iface.HardwareAddr) >= 6 { + return iface.HardwareAddr, nil + } + } + return []byte{}, fmt.Errorf("uuid: no HW address found") +} diff --git a/vendor/github.com/satori/go.uuid/generator_test.go b/vendor/github.com/satori/go.uuid/generator_test.go new file mode 100644 index 0000000..82a236a --- /dev/null +++ b/vendor/github.com/satori/go.uuid/generator_test.go @@ -0,0 +1,224 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "crypto/rand" + "fmt" + "net" + "time" + + . "gopkg.in/check.v1" +) + +type faultyReader struct { + callsNum int + readToFail int // Read call number to fail +} + +func (r *faultyReader) Read(dest []byte) (int, error) { + r.callsNum++ + if (r.callsNum - 1) == r.readToFail { + return 0, fmt.Errorf("io: reader is faulty") + } + return rand.Read(dest) +} + +type genTestSuite struct{} + +var _ = Suite(&genTestSuite{}) + +func (s *genTestSuite) TestNewV1(c *C) { + u1, err := NewV1() + c.Assert(err, IsNil) + c.Assert(u1.Version(), Equals, V1) + c.Assert(u1.Variant(), Equals, VariantRFC4122) + + u2, err := NewV1() + c.Assert(err, IsNil) + c.Assert(u1, Not(Equals), u2) +} + +func (s *genTestSuite) TestNewV1EpochStale(c *C) { + g := &rfc4122Generator{ + epochFunc: func() time.Time { + return time.Unix(0, 0) + }, + hwAddrFunc: defaultHWAddrFunc, + rand: rand.Reader, + } + u1, err := g.NewV1() + c.Assert(err, IsNil) + u2, err := g.NewV1() + c.Assert(err, IsNil) + c.Assert(u1, Not(Equals), u2) +} + +func (s *genTestSuite) TestNewV1FaultyRand(c *C) { + g := &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: defaultHWAddrFunc, + rand: &faultyReader{}, + } + u1, err := g.NewV1() + c.Assert(err, NotNil) + c.Assert(u1, Equals, Nil) +} + +func (s *genTestSuite) TestNewV1MissingNetworkInterfaces(c *C) { + g := &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: func() (net.HardwareAddr, error) { + return []byte{}, fmt.Errorf("uuid: no hw address found") + }, + rand: rand.Reader, + } + _, err := g.NewV1() + c.Assert(err, IsNil) +} + +func (s *genTestSuite) TestNewV1MissingNetInterfacesAndFaultyRand(c *C) { + g := &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: func() (net.HardwareAddr, error) { + return []byte{}, fmt.Errorf("uuid: no hw address found") + }, + rand: &faultyReader{ + readToFail: 1, + }, + } + u1, err := g.NewV1() + c.Assert(err, NotNil) + c.Assert(u1, Equals, Nil) +} + +func (s *genTestSuite) BenchmarkNewV1(c *C) { + for i := 0; i < c.N; i++ { + NewV1() + } +} + +func (s *genTestSuite) TestNewV2(c *C) { + u1, err := NewV2(DomainPerson) + c.Assert(err, IsNil) + c.Assert(u1.Version(), Equals, V2) + c.Assert(u1.Variant(), Equals, VariantRFC4122) + + u2, err := NewV2(DomainGroup) + c.Assert(err, IsNil) + c.Assert(u2.Version(), Equals, V2) + c.Assert(u2.Variant(), Equals, VariantRFC4122) + + u3, err := NewV2(DomainOrg) + c.Assert(err, IsNil) + c.Assert(u3.Version(), Equals, V2) + c.Assert(u3.Variant(), Equals, VariantRFC4122) +} + +func (s *genTestSuite) TestNewV2FaultyRand(c *C) { + g := &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: defaultHWAddrFunc, + rand: &faultyReader{}, + } + u1, err := g.NewV2(DomainPerson) + c.Assert(err, NotNil) + c.Assert(u1, Equals, Nil) +} + +func (s *genTestSuite) BenchmarkNewV2(c *C) { + for i := 0; i < c.N; i++ { + NewV2(DomainPerson) + } +} + +func (s *genTestSuite) TestNewV3(c *C) { + u1 := NewV3(NamespaceDNS, "www.example.com") + c.Assert(u1.Version(), Equals, V3) + c.Assert(u1.Variant(), Equals, VariantRFC4122) + c.Assert(u1.String(), Equals, "5df41881-3aed-3515-88a7-2f4a814cf09e") + + u2 := NewV3(NamespaceDNS, "example.com") + c.Assert(u2, Not(Equals), u1) + + u3 := NewV3(NamespaceDNS, "example.com") + c.Assert(u3, Equals, u2) + + u4 := NewV3(NamespaceURL, "example.com") + c.Assert(u4, Not(Equals), u3) +} + +func (s *genTestSuite) BenchmarkNewV3(c *C) { + for i := 0; i < c.N; i++ { + NewV3(NamespaceDNS, "www.example.com") + } +} + +func (s *genTestSuite) TestNewV4(c *C) { + u1, err := NewV4() + c.Assert(err, IsNil) + c.Assert(u1.Version(), Equals, V4) + c.Assert(u1.Variant(), Equals, VariantRFC4122) + + u2, err := NewV4() + c.Assert(err, IsNil) + c.Assert(u1, Not(Equals), u2) +} + +func (s *genTestSuite) TestNewV4FaultyRand(c *C) { + g := &rfc4122Generator{ + epochFunc: time.Now, + hwAddrFunc: defaultHWAddrFunc, + rand: &faultyReader{}, + } + u1, err := g.NewV4() + c.Assert(err, NotNil) + c.Assert(u1, Equals, Nil) +} + +func (s *genTestSuite) BenchmarkNewV4(c *C) { + for i := 0; i < c.N; i++ { + NewV4() + } +} + +func (s *genTestSuite) TestNewV5(c *C) { + u1 := NewV5(NamespaceDNS, "www.example.com") + c.Assert(u1.Version(), Equals, V5) + c.Assert(u1.Variant(), Equals, VariantRFC4122) + c.Assert(u1.String(), Equals, "2ed6657d-e927-568b-95e1-2665a8aea6a2") + + u2 := NewV5(NamespaceDNS, "example.com") + c.Assert(u2, Not(Equals), u1) + + u3 := NewV5(NamespaceDNS, "example.com") + c.Assert(u3, Equals, u2) + + u4 := NewV5(NamespaceURL, "example.com") + c.Assert(u4, Not(Equals), u3) +} + +func (s *genTestSuite) BenchmarkNewV5(c *C) { + for i := 0; i < c.N; i++ { + NewV5(NamespaceDNS, "www.example.com") + } +} diff --git a/vendor/github.com/satori/go.uuid/sql.go b/vendor/github.com/satori/go.uuid/sql.go new file mode 100644 index 0000000..56759d3 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/sql.go @@ -0,0 +1,78 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "database/sql/driver" + "fmt" +) + +// Value implements the driver.Valuer interface. +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +// Scan implements the sql.Scanner interface. +// A 16-byte slice is handled by UnmarshalBinary, while +// a longer byte slice or a string is handled by UnmarshalText. +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + if len(src) == Size { + return u.UnmarshalBinary(src) + } + return u.UnmarshalText(src) + + case string: + return u.UnmarshalText([]byte(src)) + } + + return fmt.Errorf("uuid: cannot convert %T to UUID", src) +} + +// NullUUID can be used with the standard sql package to represent a +// UUID value that can be NULL in the database +type NullUUID struct { + UUID UUID + Valid bool +} + +// Value implements the driver.Valuer interface. +func (u NullUUID) Value() (driver.Value, error) { + if !u.Valid { + return nil, nil + } + // Delegate to UUID Value function + return u.UUID.Value() +} + +// Scan implements the sql.Scanner interface. +func (u *NullUUID) Scan(src interface{}) error { + if src == nil { + u.UUID, u.Valid = Nil, false + return nil + } + + // Delegate to UUID Scan function + u.Valid = true + return u.UUID.Scan(src) +} diff --git a/vendor/github.com/satori/go.uuid/sql_test.go b/vendor/github.com/satori/go.uuid/sql_test.go new file mode 100644 index 0000000..74255f5 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/sql_test.go @@ -0,0 +1,136 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + . "gopkg.in/check.v1" +) + +type sqlTestSuite struct{} + +var _ = Suite(&sqlTestSuite{}) + +func (s *sqlTestSuite) TestValue(c *C) { + u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + c.Assert(err, IsNil) + + val, err := u.Value() + c.Assert(err, IsNil) + c.Assert(val, Equals, u.String()) +} + +func (s *sqlTestSuite) TestValueNil(c *C) { + u := UUID{} + + val, err := u.Value() + c.Assert(err, IsNil) + c.Assert(val, Equals, Nil.String()) +} + +func (s *sqlTestSuite) TestNullUUIDValueNil(c *C) { + u := NullUUID{} + + val, err := u.Value() + c.Assert(err, IsNil) + c.Assert(val, IsNil) +} + +func (s *sqlTestSuite) TestScanBinary(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + u1 := UUID{} + err := u1.Scan(b1) + c.Assert(err, IsNil) + c.Assert(u, Equals, u1) + + b2 := []byte{} + u2 := UUID{} + + err = u2.Scan(b2) + c.Assert(err, NotNil) +} + +func (s *sqlTestSuite) TestScanString(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + + u1 := UUID{} + err := u1.Scan(s1) + c.Assert(err, IsNil) + c.Assert(u, Equals, u1) + + s2 := "" + u2 := UUID{} + + err = u2.Scan(s2) + c.Assert(err, NotNil) +} + +func (s *sqlTestSuite) TestScanText(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + + u1 := UUID{} + err := u1.Scan(b1) + c.Assert(err, IsNil) + c.Assert(u, Equals, u1) + + b2 := []byte("") + u2 := UUID{} + err = u2.Scan(b2) + c.Assert(err, NotNil) +} + +func (s *sqlTestSuite) TestScanUnsupported(c *C) { + u := UUID{} + + err := u.Scan(true) + c.Assert(err, NotNil) +} + +func (s *sqlTestSuite) TestScanNil(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + err := u.Scan(nil) + c.Assert(err, NotNil) +} + +func (s *sqlTestSuite) TestNullUUIDScanValid(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + + u1 := NullUUID{} + err := u1.Scan(s1) + c.Assert(err, IsNil) + c.Assert(u1.Valid, Equals, true) + c.Assert(u1.UUID, Equals, u) +} + +func (s *sqlTestSuite) TestNullUUIDScanNil(c *C) { + u := NullUUID{UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, true} + + err := u.Scan(nil) + c.Assert(err, IsNil) + c.Assert(u.Valid, Equals, false) + c.Assert(u.UUID, Equals, Nil) +} diff --git a/vendor/github.com/satori/go.uuid/uuid.go b/vendor/github.com/satori/go.uuid/uuid.go new file mode 100644 index 0000000..a2b8e2c --- /dev/null +++ b/vendor/github.com/satori/go.uuid/uuid.go @@ -0,0 +1,161 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +// Package uuid provides implementation of Universally Unique Identifier (UUID). +// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and +// version 2 (as specified in DCE 1.1). +package uuid + +import ( + "bytes" + "encoding/hex" +) + +// Size of a UUID in bytes. +const Size = 16 + +// UUID representation compliant with specification +// described in RFC 4122. +type UUID [Size]byte + +// UUID versions +const ( + _ byte = iota + V1 + V2 + V3 + V4 + V5 +) + +// UUID layout variants. +const ( + VariantNCS byte = iota + VariantRFC4122 + VariantMicrosoft + VariantFuture +) + +// UUID DCE domains. +const ( + DomainPerson = iota + DomainGroup + DomainOrg +) + +// String parse helpers. +var ( + urnPrefix = []byte("urn:uuid:") + byteGroups = []int{8, 4, 4, 4, 12} +) + +// Nil is special form of UUID that is specified to have all +// 128 bits set to zero. +var Nil = UUID{} + +// Predefined namespace UUIDs. +var ( + NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) + NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) + NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) + NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) +) + +// Equal returns true if u1 and u2 equals, otherwise returns false. +func Equal(u1 UUID, u2 UUID) bool { + return bytes.Equal(u1[:], u2[:]) +} + +// Version returns algorithm version used to generate UUID. +func (u UUID) Version() byte { + return u[6] >> 4 +} + +// Variant returns UUID layout variant. +func (u UUID) Variant() byte { + switch { + case (u[8] >> 7) == 0x00: + return VariantNCS + case (u[8] >> 6) == 0x02: + return VariantRFC4122 + case (u[8] >> 5) == 0x06: + return VariantMicrosoft + case (u[8] >> 5) == 0x07: + fallthrough + default: + return VariantFuture + } +} + +// Bytes returns bytes slice representation of UUID. +func (u UUID) Bytes() []byte { + return u[:] +} + +// Returns canonical string representation of UUID: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = '-' + hex.Encode(buf[9:13], u[4:6]) + buf[13] = '-' + hex.Encode(buf[14:18], u[6:8]) + buf[18] = '-' + hex.Encode(buf[19:23], u[8:10]) + buf[23] = '-' + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} + +// SetVersion sets version bits. +func (u *UUID) SetVersion(v byte) { + u[6] = (u[6] & 0x0f) | (v << 4) +} + +// SetVariant sets variant bits. +func (u *UUID) SetVariant(v byte) { + switch v { + case VariantNCS: + u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) + case VariantRFC4122: + u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) + case VariantMicrosoft: + u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) + case VariantFuture: + fallthrough + default: + u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) + } +} + +// Must is a helper that wraps a call to a function returning (UUID, error) +// and panics if the error is non-nil. It is intended for use in variable +// initializations such as +// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")); +func Must(u UUID, err error) UUID { + if err != nil { + panic(err) + } + return u +} diff --git a/vendor/github.com/satori/go.uuid/uuid_test.go b/vendor/github.com/satori/go.uuid/uuid_test.go new file mode 100644 index 0000000..fa40280 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/uuid_test.go @@ -0,0 +1,100 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// 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. + +package uuid + +import ( + "bytes" + "fmt" + "testing" + + . "gopkg.in/check.v1" +) + +// Hook up gocheck into the "go test" runner. +func TestUUID(t *testing.T) { TestingT(t) } + +type testSuite struct{} + +var _ = Suite(&testSuite{}) + +func (s *testSuite) TestBytes(c *C) { + u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} + + c.Assert(bytes.Equal(u.Bytes(), bytes1), Equals, true) +} + +func (s *testSuite) TestString(c *C) { + c.Assert(NamespaceDNS.String(), Equals, "6ba7b810-9dad-11d1-80b4-00c04fd430c8") +} + +func (s *testSuite) TestEqual(c *C) { + c.Assert(Equal(NamespaceDNS, NamespaceDNS), Equals, true) + c.Assert(Equal(NamespaceDNS, NamespaceURL), Equals, false) +} + +func (s *testSuite) TestVersion(c *C) { + u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + c.Assert(u.Version(), Equals, V1) +} + +func (s *testSuite) TestSetVersion(c *C) { + u := UUID{} + u.SetVersion(4) + c.Assert(u.Version(), Equals, V4) +} + +func (s *testSuite) TestVariant(c *C) { + u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + c.Assert(u1.Variant(), Equals, VariantNCS) + + u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + c.Assert(u2.Variant(), Equals, VariantRFC4122) + + u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + c.Assert(u3.Variant(), Equals, VariantMicrosoft) + + u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + c.Assert(u4.Variant(), Equals, VariantFuture) +} + +func (s *testSuite) TestSetVariant(c *C) { + u := UUID{} + u.SetVariant(VariantNCS) + c.Assert(u.Variant(), Equals, VariantNCS) + u.SetVariant(VariantRFC4122) + c.Assert(u.Variant(), Equals, VariantRFC4122) + u.SetVariant(VariantMicrosoft) + c.Assert(u.Variant(), Equals, VariantMicrosoft) + u.SetVariant(VariantFuture) + c.Assert(u.Variant(), Equals, VariantFuture) +} + +func (s *testSuite) TestMust(c *C) { + defer func() { + c.Assert(recover(), NotNil) + }() + Must(func() (UUID, error) { + return Nil, fmt.Errorf("uuid: expected error") + }()) +} diff --git a/vendor/golang.org/x/sync/AUTHORS b/vendor/golang.org/x/sync/AUTHORS deleted file mode 100644 index 15167cd..0000000 --- a/vendor/golang.org/x/sync/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/sync/CONTRIBUTING.md b/vendor/golang.org/x/sync/CONTRIBUTING.md deleted file mode 100644 index 88dff59..0000000 --- a/vendor/golang.org/x/sync/CONTRIBUTING.md +++ /dev/null @@ -1,31 +0,0 @@ -# Contributing to Go - -Go is an open source project. - -It is the work of hundreds of contributors. We appreciate your help! - - -## Filing issues - -When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: - -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? - -General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. -The gophers there will answer or ask you to file an issue if you've tripped over a bug. - -## Contributing code - -Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) -before sending patches. - -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - -Unless otherwise noted, the Go source files are distributed under -the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/sync/CONTRIBUTORS b/vendor/golang.org/x/sync/CONTRIBUTORS deleted file mode 100644 index 1c4577e..0000000 --- a/vendor/golang.org/x/sync/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE deleted file mode 100644 index 6a66aea..0000000 --- a/vendor/golang.org/x/sync/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS deleted file mode 100644 index 7330990..0000000 --- a/vendor/golang.org/x/sync/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google 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, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/README b/vendor/golang.org/x/sync/README deleted file mode 100644 index 59c9dcb..0000000 --- a/vendor/golang.org/x/sync/README +++ /dev/null @@ -1,2 +0,0 @@ -This repository provides Go concurrency primitives in addition to the -ones provided by the language and "sync" and "sync/atomic" packages. diff --git a/vendor/golang.org/x/sync/codereview.cfg b/vendor/golang.org/x/sync/codereview.cfg deleted file mode 100644 index 3f8b14b..0000000 --- a/vendor/golang.org/x/sync/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -issuerepo: golang/go diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go deleted file mode 100644 index 533438d..0000000 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package errgroup provides synchronization, error propagation, and Context -// cancelation for groups of goroutines working on subtasks of a common task. -package errgroup - -import ( - "sync" - - "golang.org/x/net/context" -) - -// A Group is a collection of goroutines working on subtasks that are part of -// the same overall task. -// -// A zero Group is valid and does not cancel on error. -type Group struct { - cancel func() - - wg sync.WaitGroup - - errOnce sync.Once - err error -} - -// WithContext returns a new Group and an associated Context derived from ctx. -// -// The derived Context is canceled the first time a function passed to Go -// returns a non-nil error or the first time Wait returns, whichever occurs -// first. -func WithContext(ctx context.Context) (*Group, context.Context) { - ctx, cancel := context.WithCancel(ctx) - return &Group{cancel: cancel}, ctx -} - -// Wait blocks until all function calls from the Go method have returned, then -// returns the first non-nil error (if any) from them. -func (g *Group) Wait() error { - g.wg.Wait() - if g.cancel != nil { - g.cancel() - } - return g.err -} - -// Go calls the given function in a new goroutine. -// -// The first call to return a non-nil error cancels the group; its error will be -// returned by Wait. -func (g *Group) Go(f func() error) { - g.wg.Add(1) - - go func() { - defer g.wg.Done() - - if err := f(); err != nil { - g.errOnce.Do(func() { - g.err = err - if g.cancel != nil { - g.cancel() - } - }) - } - }() -} diff --git a/vendor/golang.org/x/sync/errgroup/errgroup_example_md5all_test.go b/vendor/golang.org/x/sync/errgroup/errgroup_example_md5all_test.go deleted file mode 100644 index 714b5ae..0000000 --- a/vendor/golang.org/x/sync/errgroup/errgroup_example_md5all_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package errgroup_test - -import ( - "crypto/md5" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - - "golang.org/x/net/context" - "golang.org/x/sync/errgroup" -) - -// Pipeline demonstrates the use of a Group to implement a multi-stage -// pipeline: a version of the MD5All function with bounded parallelism from -// https://blog.golang.org/pipelines. -func ExampleGroup_pipeline() { - m, err := MD5All(context.Background(), ".") - if err != nil { - log.Fatal(err) - } - - for k, sum := range m { - fmt.Printf("%s:\t%x\n", k, sum) - } -} - -type result struct { - path string - sum [md5.Size]byte -} - -// MD5All reads all the files in the file tree rooted at root and returns a map -// from file path to the MD5 sum of the file's contents. If the directory walk -// fails or any read operation fails, MD5All returns an error. -func MD5All(ctx context.Context, root string) (map[string][md5.Size]byte, error) { - // ctx is canceled when g.Wait() returns. When this version of MD5All returns - // - even in case of error! - we know that all of the goroutines have finished - // and the memory they were using can be garbage-collected. - g, ctx := errgroup.WithContext(ctx) - paths := make(chan string) - - g.Go(func() error { - defer close(paths) - return filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if !info.Mode().IsRegular() { - return nil - } - select { - case paths <- path: - case <-ctx.Done(): - return ctx.Err() - } - return nil - }) - }) - - // Start a fixed number of goroutines to read and digest files. - c := make(chan result) - const numDigesters = 20 - for i := 0; i < numDigesters; i++ { - g.Go(func() error { - for path := range paths { - data, err := ioutil.ReadFile(path) - if err != nil { - return err - } - select { - case c <- result{path, md5.Sum(data)}: - case <-ctx.Done(): - return ctx.Err() - } - } - return nil - }) - } - go func() { - g.Wait() - close(c) - }() - - m := make(map[string][md5.Size]byte) - for r := range c { - m[r.path] = r.sum - } - // Check whether any of the goroutines failed. Since g is accumulating the - // errors, we don't need to send them (or check for them) in the individual - // results sent on the channel. - if err := g.Wait(); err != nil { - return nil, err - } - return m, nil -} diff --git a/vendor/golang.org/x/sync/errgroup/errgroup_test.go b/vendor/golang.org/x/sync/errgroup/errgroup_test.go deleted file mode 100644 index 6a9696e..0000000 --- a/vendor/golang.org/x/sync/errgroup/errgroup_test.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package errgroup_test - -import ( - "errors" - "fmt" - "net/http" - "os" - "testing" - - "golang.org/x/net/context" - "golang.org/x/sync/errgroup" -) - -var ( - Web = fakeSearch("web") - Image = fakeSearch("image") - Video = fakeSearch("video") -) - -type Result string -type Search func(ctx context.Context, query string) (Result, error) - -func fakeSearch(kind string) Search { - return func(_ context.Context, query string) (Result, error) { - return Result(fmt.Sprintf("%s result for %q", kind, query)), nil - } -} - -// JustErrors illustrates the use of a Group in place of a sync.WaitGroup to -// simplify goroutine counting and error handling. This example is derived from -// the sync.WaitGroup example at https://golang.org/pkg/sync/#example_WaitGroup. -func ExampleGroup_justErrors() { - var g errgroup.Group - var urls = []string{ - "http://www.golang.org/", - "http://www.google.com/", - "http://www.somestupidname.com/", - } - for _, url := range urls { - // Launch a goroutine to fetch the URL. - url := url // https://golang.org/doc/faq#closures_and_goroutines - g.Go(func() error { - // Fetch the URL. - resp, err := http.Get(url) - if err == nil { - resp.Body.Close() - } - return err - }) - } - // Wait for all HTTP fetches to complete. - if err := g.Wait(); err == nil { - fmt.Println("Successfully fetched all URLs.") - } -} - -// Parallel illustrates the use of a Group for synchronizing a simple parallel -// task: the "Google Search 2.0" function from -// https://talks.golang.org/2012/concurrency.slide#46, augmented with a Context -// and error-handling. -func ExampleGroup_parallel() { - Google := func(ctx context.Context, query string) ([]Result, error) { - g, ctx := errgroup.WithContext(ctx) - - searches := []Search{Web, Image, Video} - results := make([]Result, len(searches)) - for i, search := range searches { - i, search := i, search // https://golang.org/doc/faq#closures_and_goroutines - g.Go(func() error { - result, err := search(ctx, query) - if err == nil { - results[i] = result - } - return err - }) - } - if err := g.Wait(); err != nil { - return nil, err - } - return results, nil - } - - results, err := Google(context.Background(), "golang") - if err != nil { - fmt.Fprintln(os.Stderr, err) - return - } - for _, result := range results { - fmt.Println(result) - } - - // Output: - // web result for "golang" - // image result for "golang" - // video result for "golang" -} - -func TestZeroGroup(t *testing.T) { - err1 := errors.New("errgroup_test: 1") - err2 := errors.New("errgroup_test: 2") - - cases := []struct { - errs []error - }{ - {errs: []error{}}, - {errs: []error{nil}}, - {errs: []error{err1}}, - {errs: []error{err1, nil}}, - {errs: []error{err1, nil, err2}}, - } - - for _, tc := range cases { - var g errgroup.Group - - var firstErr error - for i, err := range tc.errs { - err := err - g.Go(func() error { return err }) - - if firstErr == nil && err != nil { - firstErr = err - } - - if gErr := g.Wait(); gErr != firstErr { - t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+ - "g.Wait() = %v; want %v", - g, tc.errs[:i+1], err, firstErr) - } - } - } -} - -func TestWithContext(t *testing.T) { - errDoom := errors.New("group_test: doomed") - - cases := []struct { - errs []error - want error - }{ - {want: nil}, - {errs: []error{nil}, want: nil}, - {errs: []error{errDoom}, want: errDoom}, - {errs: []error{errDoom, nil}, want: errDoom}, - } - - for _, tc := range cases { - g, ctx := errgroup.WithContext(context.Background()) - - for _, err := range tc.errs { - err := err - g.Go(func() error { return err }) - } - - if err := g.Wait(); err != tc.want { - t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+ - "g.Wait() = %v; want %v", - g, tc.errs, err, tc.want) - } - - canceled := false - select { - case <-ctx.Done(): - canceled = true - default: - } - if !canceled { - t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+ - "ctx.Done() was not closed", - g, tc.errs) - } - } -} diff --git a/vendor/golang.org/x/sync/semaphore/semaphore.go b/vendor/golang.org/x/sync/semaphore/semaphore.go deleted file mode 100644 index e9d2d79..0000000 --- a/vendor/golang.org/x/sync/semaphore/semaphore.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package semaphore provides a weighted semaphore implementation. -package semaphore // import "golang.org/x/sync/semaphore" - -import ( - "container/list" - "sync" - - // Use the old context because packages that depend on this one - // (e.g. cloud.google.com/go/...) must run on Go 1.6. - // TODO(jba): update to "context" when possible. - "golang.org/x/net/context" -) - -type waiter struct { - n int64 - ready chan<- struct{} // Closed when semaphore acquired. -} - -// NewWeighted creates a new weighted semaphore with the given -// maximum combined weight for concurrent access. -func NewWeighted(n int64) *Weighted { - w := &Weighted{size: n} - return w -} - -// Weighted provides a way to bound concurrent access to a resource. -// The callers can request access with a given weight. -type Weighted struct { - size int64 - cur int64 - mu sync.Mutex - waiters list.List -} - -// Acquire acquires the semaphore with a weight of n, blocking only until ctx -// is done. On success, returns nil. On failure, returns ctx.Err() and leaves -// the semaphore unchanged. -// -// If ctx is already done, Acquire may still succeed without blocking. -func (s *Weighted) Acquire(ctx context.Context, n int64) error { - s.mu.Lock() - if s.size-s.cur >= n && s.waiters.Len() == 0 { - s.cur += n - s.mu.Unlock() - return nil - } - - if n > s.size { - // Don't make other Acquire calls block on one that's doomed to fail. - s.mu.Unlock() - <-ctx.Done() - return ctx.Err() - } - - ready := make(chan struct{}) - w := waiter{n: n, ready: ready} - elem := s.waiters.PushBack(w) - s.mu.Unlock() - - select { - case <-ctx.Done(): - err := ctx.Err() - s.mu.Lock() - select { - case <-ready: - // Acquired the semaphore after we were canceled. Rather than trying to - // fix up the queue, just pretend we didn't notice the cancelation. - err = nil - default: - s.waiters.Remove(elem) - } - s.mu.Unlock() - return err - - case <-ready: - return nil - } -} - -// TryAcquire acquires the semaphore with a weight of n without blocking. -// On success, returns true. On failure, returns false and leaves the semaphore unchanged. -func (s *Weighted) TryAcquire(n int64) bool { - s.mu.Lock() - success := s.size-s.cur >= n && s.waiters.Len() == 0 - if success { - s.cur += n - } - s.mu.Unlock() - return success -} - -// Release releases the semaphore with a weight of n. -func (s *Weighted) Release(n int64) { - s.mu.Lock() - s.cur -= n - if s.cur < 0 { - s.mu.Unlock() - panic("semaphore: bad release") - } - for { - next := s.waiters.Front() - if next == nil { - break // No more waiters blocked. - } - - w := next.Value.(waiter) - if s.size-s.cur < w.n { - // Not enough tokens for the next waiter. We could keep going (to try to - // find a waiter with a smaller request), but under load that could cause - // starvation for large requests; instead, we leave all remaining waiters - // blocked. - // - // Consider a semaphore used as a read-write lock, with N tokens, N - // readers, and one writer. Each reader can Acquire(1) to obtain a read - // lock. The writer can Acquire(N) to obtain a write lock, excluding all - // of the readers. If we allow the readers to jump ahead in the queue, - // the writer will starve — there is always one token available for every - // reader. - break - } - - s.cur += w.n - s.waiters.Remove(next) - close(w.ready) - } - s.mu.Unlock() -} diff --git a/vendor/golang.org/x/sync/semaphore/semaphore_bench_test.go b/vendor/golang.org/x/sync/semaphore/semaphore_bench_test.go deleted file mode 100644 index 5bb2fb3..0000000 --- a/vendor/golang.org/x/sync/semaphore/semaphore_bench_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7 - -package semaphore - -import ( - "fmt" - "testing" - - "golang.org/x/net/context" -) - -// weighted is an interface matching a subset of *Weighted. It allows -// alternate implementations for testing and benchmarking. -type weighted interface { - Acquire(context.Context, int64) error - TryAcquire(int64) bool - Release(int64) -} - -// semChan implements Weighted using a channel for -// comparing against the condition variable-based implementation. -type semChan chan struct{} - -func newSemChan(n int64) semChan { - return semChan(make(chan struct{}, n)) -} - -func (s semChan) Acquire(_ context.Context, n int64) error { - for i := int64(0); i < n; i++ { - s <- struct{}{} - } - return nil -} - -func (s semChan) TryAcquire(n int64) bool { - if int64(len(s))+n > int64(cap(s)) { - return false - } - - for i := int64(0); i < n; i++ { - s <- struct{}{} - } - return true -} - -func (s semChan) Release(n int64) { - for i := int64(0); i < n; i++ { - <-s - } -} - -// acquireN calls Acquire(size) on sem N times and then calls Release(size) N times. -func acquireN(b *testing.B, sem weighted, size int64, N int) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - for j := 0; j < N; j++ { - sem.Acquire(context.Background(), size) - } - for j := 0; j < N; j++ { - sem.Release(size) - } - } -} - -// tryAcquireN calls TryAcquire(size) on sem N times and then calls Release(size) N times. -func tryAcquireN(b *testing.B, sem weighted, size int64, N int) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - for j := 0; j < N; j++ { - if !sem.TryAcquire(size) { - b.Fatalf("TryAcquire(%v) = false, want true", size) - } - } - for j := 0; j < N; j++ { - sem.Release(size) - } - } -} - -func BenchmarkNewSeq(b *testing.B) { - for _, cap := range []int64{1, 128} { - b.Run(fmt.Sprintf("Weighted-%d", cap), func(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = NewWeighted(cap) - } - }) - b.Run(fmt.Sprintf("semChan-%d", cap), func(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = newSemChan(cap) - } - }) - } -} - -func BenchmarkAcquireSeq(b *testing.B) { - for _, c := range []struct { - cap, size int64 - N int - }{ - {1, 1, 1}, - {2, 1, 1}, - {16, 1, 1}, - {128, 1, 1}, - {2, 2, 1}, - {16, 2, 8}, - {128, 2, 64}, - {2, 1, 2}, - {16, 8, 2}, - {128, 64, 2}, - } { - for _, w := range []struct { - name string - w weighted - }{ - {"Weighted", NewWeighted(c.cap)}, - {"semChan", newSemChan(c.cap)}, - } { - b.Run(fmt.Sprintf("%s-acquire-%d-%d-%d", w.name, c.cap, c.size, c.N), func(b *testing.B) { - acquireN(b, w.w, c.size, c.N) - }) - b.Run(fmt.Sprintf("%s-tryAcquire-%d-%d-%d", w.name, c.cap, c.size, c.N), func(b *testing.B) { - tryAcquireN(b, w.w, c.size, c.N) - }) - } - } -} diff --git a/vendor/golang.org/x/sync/semaphore/semaphore_test.go b/vendor/golang.org/x/sync/semaphore/semaphore_test.go deleted file mode 100644 index 3f3bc9f..0000000 --- a/vendor/golang.org/x/sync/semaphore/semaphore_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package semaphore - -import ( - "math/rand" - "runtime" - "sync" - "testing" - "time" - - "golang.org/x/net/context" - "golang.org/x/sync/errgroup" -) - -const maxSleep = 1 * time.Millisecond - -func HammerWeighted(sem *Weighted, n int64, loops int) { - for i := 0; i < loops; i++ { - sem.Acquire(context.Background(), n) - time.Sleep(time.Duration(rand.Int63n(int64(maxSleep/time.Nanosecond))) * time.Nanosecond) - sem.Release(n) - } -} - -func TestWeighted(t *testing.T) { - t.Parallel() - - n := runtime.GOMAXPROCS(0) - loops := 10000 / n - sem := NewWeighted(int64(n)) - var wg sync.WaitGroup - wg.Add(n) - for i := 0; i < n; i++ { - i := i - go func() { - defer wg.Done() - HammerWeighted(sem, int64(i), loops) - }() - } - wg.Wait() -} - -func TestWeightedPanic(t *testing.T) { - t.Parallel() - - defer func() { - if recover() == nil { - t.Fatal("release of an unacquired weighted semaphore did not panic") - } - }() - w := NewWeighted(1) - w.Release(1) -} - -func TestWeightedTryAcquire(t *testing.T) { - t.Parallel() - - ctx := context.Background() - sem := NewWeighted(2) - tries := []bool{} - sem.Acquire(ctx, 1) - tries = append(tries, sem.TryAcquire(1)) - tries = append(tries, sem.TryAcquire(1)) - - sem.Release(2) - - tries = append(tries, sem.TryAcquire(1)) - sem.Acquire(ctx, 1) - tries = append(tries, sem.TryAcquire(1)) - - want := []bool{true, false, true, false} - for i := range tries { - if tries[i] != want[i] { - t.Errorf("tries[%d]: got %t, want %t", i, tries[i], want[i]) - } - } -} - -func TestWeightedAcquire(t *testing.T) { - t.Parallel() - - ctx := context.Background() - sem := NewWeighted(2) - tryAcquire := func(n int64) bool { - ctx, cancel := context.WithTimeout(ctx, 10*time.Millisecond) - defer cancel() - return sem.Acquire(ctx, n) == nil - } - - tries := []bool{} - sem.Acquire(ctx, 1) - tries = append(tries, tryAcquire(1)) - tries = append(tries, tryAcquire(1)) - - sem.Release(2) - - tries = append(tries, tryAcquire(1)) - sem.Acquire(ctx, 1) - tries = append(tries, tryAcquire(1)) - - want := []bool{true, false, true, false} - for i := range tries { - if tries[i] != want[i] { - t.Errorf("tries[%d]: got %t, want %t", i, tries[i], want[i]) - } - } -} - -func TestWeightedDoesntBlockIfTooBig(t *testing.T) { - t.Parallel() - - const n = 2 - sem := NewWeighted(n) - { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go sem.Acquire(ctx, n+1) - } - - g, ctx := errgroup.WithContext(context.Background()) - for i := n * 3; i > 0; i-- { - g.Go(func() error { - err := sem.Acquire(ctx, 1) - if err == nil { - time.Sleep(1 * time.Millisecond) - sem.Release(1) - } - return err - }) - } - if err := g.Wait(); err != nil { - t.Errorf("NewWeighted(%v) failed to AcquireCtx(_, 1) with AcquireCtx(_, %v) pending", n, n+1) - } -} - -// TestLargeAcquireDoesntStarve times out if a large call to Acquire starves. -// Merely returning from the test function indicates success. -func TestLargeAcquireDoesntStarve(t *testing.T) { - t.Parallel() - - ctx := context.Background() - n := int64(runtime.GOMAXPROCS(0)) - sem := NewWeighted(n) - running := true - - var wg sync.WaitGroup - wg.Add(int(n)) - for i := n; i > 0; i-- { - sem.Acquire(ctx, 1) - go func() { - defer func() { - sem.Release(1) - wg.Done() - }() - for running { - time.Sleep(1 * time.Millisecond) - sem.Release(1) - sem.Acquire(ctx, 1) - } - }() - } - - sem.Acquire(ctx, n) - running = false - sem.Release(n) - wg.Wait() -} diff --git a/vendor/golang.org/x/sync/singleflight/singleflight.go b/vendor/golang.org/x/sync/singleflight/singleflight.go deleted file mode 100644 index 9a4f8d5..0000000 --- a/vendor/golang.org/x/sync/singleflight/singleflight.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package singleflight provides a duplicate function call suppression -// mechanism. -package singleflight // import "golang.org/x/sync/singleflight" - -import "sync" - -// call is an in-flight or completed singleflight.Do call -type call struct { - wg sync.WaitGroup - - // These fields are written once before the WaitGroup is done - // and are only read after the WaitGroup is done. - val interface{} - err error - - // These fields are read and written with the singleflight - // mutex held before the WaitGroup is done, and are read but - // not written after the WaitGroup is done. - dups int - chans []chan<- Result -} - -// Group represents a class of work and forms a namespace in -// which units of work can be executed with duplicate suppression. -type Group struct { - mu sync.Mutex // protects m - m map[string]*call // lazily initialized -} - -// Result holds the results of Do, so they can be passed -// on a channel. -type Result struct { - Val interface{} - Err error - Shared bool -} - -// Do executes and returns the results of the given function, making -// sure that only one execution is in-flight for a given key at a -// time. If a duplicate comes in, the duplicate caller waits for the -// original to complete and receives the same results. -// The return value shared indicates whether v was given to multiple callers. -func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) { - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - g.mu.Unlock() - c.wg.Wait() - return c.val, c.err, true - } - c := new(call) - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - g.doCall(c, key, fn) - return c.val, c.err, c.dups > 0 -} - -// DoChan is like Do but returns a channel that will receive the -// results when they are ready. -func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result { - ch := make(chan Result, 1) - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - c.chans = append(c.chans, ch) - g.mu.Unlock() - return ch - } - c := &call{chans: []chan<- Result{ch}} - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - go g.doCall(c, key, fn) - - return ch -} - -// doCall handles the single call for a key. -func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) { - c.val, c.err = fn() - c.wg.Done() - - g.mu.Lock() - delete(g.m, key) - for _, ch := range c.chans { - ch <- Result{c.val, c.err, c.dups > 0} - } - g.mu.Unlock() -} - -// Forget tells the singleflight to forget about a key. Future calls -// to Do for this key will call the function rather than waiting for -// an earlier call to complete. -func (g *Group) Forget(key string) { - g.mu.Lock() - delete(g.m, key) - g.mu.Unlock() -} diff --git a/vendor/golang.org/x/sync/singleflight/singleflight_test.go b/vendor/golang.org/x/sync/singleflight/singleflight_test.go deleted file mode 100644 index 5e6f1b3..0000000 --- a/vendor/golang.org/x/sync/singleflight/singleflight_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package singleflight - -import ( - "errors" - "fmt" - "sync" - "sync/atomic" - "testing" - "time" -) - -func TestDo(t *testing.T) { - var g Group - v, err, _ := g.Do("key", func() (interface{}, error) { - return "bar", nil - }) - if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want { - t.Errorf("Do = %v; want %v", got, want) - } - if err != nil { - t.Errorf("Do error = %v", err) - } -} - -func TestDoErr(t *testing.T) { - var g Group - someErr := errors.New("Some error") - v, err, _ := g.Do("key", func() (interface{}, error) { - return nil, someErr - }) - if err != someErr { - t.Errorf("Do error = %v; want someErr %v", err, someErr) - } - if v != nil { - t.Errorf("unexpected non-nil value %#v", v) - } -} - -func TestDoDupSuppress(t *testing.T) { - var g Group - var wg1, wg2 sync.WaitGroup - c := make(chan string, 1) - var calls int32 - fn := func() (interface{}, error) { - if atomic.AddInt32(&calls, 1) == 1 { - // First invocation. - wg1.Done() - } - v := <-c - c <- v // pump; make available for any future calls - - time.Sleep(10 * time.Millisecond) // let more goroutines enter Do - - return v, nil - } - - const n = 10 - wg1.Add(1) - for i := 0; i < n; i++ { - wg1.Add(1) - wg2.Add(1) - go func() { - defer wg2.Done() - wg1.Done() - v, err, _ := g.Do("key", fn) - if err != nil { - t.Errorf("Do error: %v", err) - return - } - if s, _ := v.(string); s != "bar" { - t.Errorf("Do = %T %v; want %q", v, v, "bar") - } - }() - } - wg1.Wait() - // At least one goroutine is in fn now and all of them have at - // least reached the line before the Do. - c <- "bar" - wg2.Wait() - if got := atomic.LoadInt32(&calls); got <= 0 || got >= n { - t.Errorf("number of calls = %d; want over 0 and less than %d", got, n) - } -} diff --git a/vendor/golang.org/x/sync/syncmap/map.go b/vendor/golang.org/x/sync/syncmap/map.go deleted file mode 100644 index 80e1584..0000000 --- a/vendor/golang.org/x/sync/syncmap/map.go +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package syncmap provides a concurrent map implementation. -// It is a prototype for a proposed addition to the sync package -// in the standard library. -// (https://golang.org/issue/18177) -package syncmap - -import ( - "sync" - "sync/atomic" - "unsafe" -) - -// Map is a concurrent map with amortized-constant-time loads, stores, and deletes. -// It is safe for multiple goroutines to call a Map's methods concurrently. -// -// The zero Map is valid and empty. -// -// A Map must not be copied after first use. -type Map struct { - mu sync.Mutex - - // read contains the portion of the map's contents that are safe for - // concurrent access (with or without mu held). - // - // The read field itself is always safe to load, but must only be stored with - // mu held. - // - // Entries stored in read may be updated concurrently without mu, but updating - // a previously-expunged entry requires that the entry be copied to the dirty - // map and unexpunged with mu held. - read atomic.Value // readOnly - - // dirty contains the portion of the map's contents that require mu to be - // held. To ensure that the dirty map can be promoted to the read map quickly, - // it also includes all of the non-expunged entries in the read map. - // - // Expunged entries are not stored in the dirty map. An expunged entry in the - // clean map must be unexpunged and added to the dirty map before a new value - // can be stored to it. - // - // If the dirty map is nil, the next write to the map will initialize it by - // making a shallow copy of the clean map, omitting stale entries. - dirty map[interface{}]*entry - - // misses counts the number of loads since the read map was last updated that - // needed to lock mu to determine whether the key was present. - // - // Once enough misses have occurred to cover the cost of copying the dirty - // map, the dirty map will be promoted to the read map (in the unamended - // state) and the next store to the map will make a new dirty copy. - misses int -} - -// readOnly is an immutable struct stored atomically in the Map.read field. -type readOnly struct { - m map[interface{}]*entry - amended bool // true if the dirty map contains some key not in m. -} - -// expunged is an arbitrary pointer that marks entries which have been deleted -// from the dirty map. -var expunged = unsafe.Pointer(new(interface{})) - -// An entry is a slot in the map corresponding to a particular key. -type entry struct { - // p points to the interface{} value stored for the entry. - // - // If p == nil, the entry has been deleted and m.dirty == nil. - // - // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry - // is missing from m.dirty. - // - // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty - // != nil, in m.dirty[key]. - // - // An entry can be deleted by atomic replacement with nil: when m.dirty is - // next created, it will atomically replace nil with expunged and leave - // m.dirty[key] unset. - // - // An entry's associated value can be updated by atomic replacement, provided - // p != expunged. If p == expunged, an entry's associated value can be updated - // only after first setting m.dirty[key] = e so that lookups using the dirty - // map find the entry. - p unsafe.Pointer // *interface{} -} - -func newEntry(i interface{}) *entry { - return &entry{p: unsafe.Pointer(&i)} -} - -// Load returns the value stored in the map for a key, or nil if no -// value is present. -// The ok result indicates whether value was found in the map. -func (m *Map) Load(key interface{}) (value interface{}, ok bool) { - read, _ := m.read.Load().(readOnly) - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - // Avoid reporting a spurious miss if m.dirty got promoted while we were - // blocked on m.mu. (If further loads of the same key will not miss, it's - // not worth copying the dirty map for this key.) - read, _ = m.read.Load().(readOnly) - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - // Regardless of whether the entry was present, record a miss: this key - // will take the slow path until the dirty map is promoted to the read - // map. - m.missLocked() - } - m.mu.Unlock() - } - if !ok { - return nil, false - } - return e.load() -} - -func (e *entry) load() (value interface{}, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return nil, false - } - return *(*interface{})(p), true -} - -// Store sets the value for a key. -func (m *Map) Store(key, value interface{}) { - read, _ := m.read.Load().(readOnly) - if e, ok := read.m[key]; ok && e.tryStore(&value) { - return - } - - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - // The entry was previously expunged, which implies that there is a - // non-nil dirty map and this entry is not in it. - m.dirty[key] = e - } - e.storeLocked(&value) - } else if e, ok := m.dirty[key]; ok { - e.storeLocked(&value) - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(readOnly{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - } - m.mu.Unlock() -} - -// tryStore stores a value if the entry has not been expunged. -// -// If the entry is expunged, tryStore returns false and leaves the entry -// unchanged. -func (e *entry) tryStore(i *interface{}) bool { - p := atomic.LoadPointer(&e.p) - if p == expunged { - return false - } - for { - if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) { - return true - } - p = atomic.LoadPointer(&e.p) - if p == expunged { - return false - } - } -} - -// unexpungeLocked ensures that the entry is not marked as expunged. -// -// If the entry was previously expunged, it must be added to the dirty map -// before m.mu is unlocked. -func (e *entry) unexpungeLocked() (wasExpunged bool) { - return atomic.CompareAndSwapPointer(&e.p, expunged, nil) -} - -// storeLocked unconditionally stores a value to the entry. -// -// The entry must be known not to be expunged. -func (e *entry) storeLocked(i *interface{}) { - atomic.StorePointer(&e.p, unsafe.Pointer(i)) -} - -// LoadOrStore 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 *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { - // Avoid locking if it's a clean hit. - read, _ := m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - actual, loaded, ok := e.tryLoadOrStore(value) - if ok { - return actual, loaded - } - } - - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - m.dirty[key] = e - } - actual, loaded, _ = e.tryLoadOrStore(value) - } else if e, ok := m.dirty[key]; ok { - actual, loaded, _ = e.tryLoadOrStore(value) - m.missLocked() - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(readOnly{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - actual, loaded = value, false - } - m.mu.Unlock() - - return actual, loaded -} - -// tryLoadOrStore atomically loads or stores a value if the entry is not -// expunged. -// -// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and -// returns with ok==false. -func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == expunged { - return nil, false, false - } - if p != nil { - return *(*interface{})(p), true, true - } - - // Copy the interface after the first load to make this method more amenable - // to escape analysis: if we hit the "load" path or the entry is expunged, we - // shouldn't bother heap-allocating. - ic := i - for { - if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) { - return i, false, true - } - p = atomic.LoadPointer(&e.p) - if p == expunged { - return nil, false, false - } - if p != nil { - return *(*interface{})(p), true, true - } - } -} - -// Delete deletes the value for a key. -func (m *Map) Delete(key interface{}) { - read, _ := m.read.Load().(readOnly) - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - e, ok = read.m[key] - if !ok && read.amended { - delete(m.dirty, key) - } - m.mu.Unlock() - } - if ok { - e.delete() - } -} - -func (e *entry) delete() (hadValue bool) { - for { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return false - } - if atomic.CompareAndSwapPointer(&e.p, p, nil) { - return true - } - } -} - -// Range calls f sequentially for each key and value present in the map. -// If f returns false, range stops the iteration. -// -// Range does not necessarily correspond to any consistent snapshot of the Map's -// contents: no key will be visited more than once, but if the value for any key -// is stored or deleted concurrently, Range may reflect any mapping for that key -// from any point during the Range call. -// -// Range may be O(N) with the number of elements in the map even if f returns -// false after a constant number of calls. -func (m *Map) Range(f func(key, value interface{}) bool) { - // We need to be able to iterate over all of the keys that were already - // present at the start of the call to Range. - // If read.amended is false, then read.m satisfies that property without - // requiring us to hold m.mu for a long time. - read, _ := m.read.Load().(readOnly) - if read.amended { - // m.dirty contains keys not in read.m. Fortunately, Range is already O(N) - // (assuming the caller does not break out early), so a call to Range - // amortizes an entire copy of the map: we can promote the dirty copy - // immediately! - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if read.amended { - read = readOnly{m: m.dirty} - m.read.Store(read) - m.dirty = nil - m.misses = 0 - } - m.mu.Unlock() - } - - for k, e := range read.m { - v, ok := e.load() - if !ok { - continue - } - if !f(k, v) { - break - } - } -} - -func (m *Map) missLocked() { - m.misses++ - if m.misses < len(m.dirty) { - return - } - m.read.Store(readOnly{m: m.dirty}) - m.dirty = nil - m.misses = 0 -} - -func (m *Map) dirtyLocked() { - if m.dirty != nil { - return - } - - read, _ := m.read.Load().(readOnly) - m.dirty = make(map[interface{}]*entry, len(read.m)) - for k, e := range read.m { - if !e.tryExpungeLocked() { - m.dirty[k] = e - } - } -} - -func (e *entry) tryExpungeLocked() (isExpunged bool) { - p := atomic.LoadPointer(&e.p) - for p == nil { - if atomic.CompareAndSwapPointer(&e.p, nil, expunged) { - return true - } - p = atomic.LoadPointer(&e.p) - } - return p == expunged -} diff --git a/vendor/golang.org/x/sync/syncmap/map_bench_test.go b/vendor/golang.org/x/sync/syncmap/map_bench_test.go deleted file mode 100644 index b279b4f..0000000 --- a/vendor/golang.org/x/sync/syncmap/map_bench_test.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package syncmap_test - -import ( - "fmt" - "reflect" - "sync/atomic" - "testing" - - "golang.org/x/sync/syncmap" -) - -type bench struct { - setup func(*testing.B, mapInterface) - perG func(b *testing.B, pb *testing.PB, i int, m mapInterface) -} - -func benchMap(b *testing.B, bench bench) { - for _, m := range [...]mapInterface{&DeepCopyMap{}, &RWMutexMap{}, &syncmap.Map{}} { - b.Run(fmt.Sprintf("%T", m), func(b *testing.B) { - m = reflect.New(reflect.TypeOf(m).Elem()).Interface().(mapInterface) - if bench.setup != nil { - bench.setup(b, m) - } - - b.ResetTimer() - - var i int64 - b.RunParallel(func(pb *testing.PB) { - id := int(atomic.AddInt64(&i, 1) - 1) - bench.perG(b, pb, id*b.N, m) - }) - }) - } -} - -func BenchmarkLoadMostlyHits(b *testing.B) { - const hits, misses = 1023, 1 - - benchMap(b, bench{ - setup: func(_ *testing.B, m mapInterface) { - for i := 0; i < hits; i++ { - m.LoadOrStore(i, i) - } - // Prime the map to get it into a steady state. - for i := 0; i < hits*2; i++ { - m.Load(i % hits) - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.Load(i % (hits + misses)) - } - }, - }) -} - -func BenchmarkLoadMostlyMisses(b *testing.B) { - const hits, misses = 1, 1023 - - benchMap(b, bench{ - setup: func(_ *testing.B, m mapInterface) { - for i := 0; i < hits; i++ { - m.LoadOrStore(i, i) - } - // Prime the map to get it into a steady state. - for i := 0; i < hits*2; i++ { - m.Load(i % hits) - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.Load(i % (hits + misses)) - } - }, - }) -} - -func BenchmarkLoadOrStoreBalanced(b *testing.B) { - const hits, misses = 128, 128 - - benchMap(b, bench{ - setup: func(b *testing.B, m mapInterface) { - if _, ok := m.(*DeepCopyMap); ok { - b.Skip("DeepCopyMap has quadratic running time.") - } - for i := 0; i < hits; i++ { - m.LoadOrStore(i, i) - } - // Prime the map to get it into a steady state. - for i := 0; i < hits*2; i++ { - m.Load(i % hits) - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - j := i % (hits + misses) - if j < hits { - if _, ok := m.LoadOrStore(j, i); !ok { - b.Fatalf("unexpected miss for %v", j) - } - } else { - if v, loaded := m.LoadOrStore(i, i); loaded { - b.Fatalf("failed to store %v: existing value %v", i, v) - } - } - } - }, - }) -} - -func BenchmarkLoadOrStoreUnique(b *testing.B) { - benchMap(b, bench{ - setup: func(b *testing.B, m mapInterface) { - if _, ok := m.(*DeepCopyMap); ok { - b.Skip("DeepCopyMap has quadratic running time.") - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.LoadOrStore(i, i) - } - }, - }) -} - -func BenchmarkLoadOrStoreCollision(b *testing.B) { - benchMap(b, bench{ - setup: func(_ *testing.B, m mapInterface) { - m.LoadOrStore(0, 0) - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.LoadOrStore(0, 0) - } - }, - }) -} - -func BenchmarkRange(b *testing.B) { - const mapSize = 1 << 10 - - benchMap(b, bench{ - setup: func(_ *testing.B, m mapInterface) { - for i := 0; i < mapSize; i++ { - m.Store(i, i) - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.Range(func(_, _ interface{}) bool { return true }) - } - }, - }) -} - -// BenchmarkAdversarialAlloc tests performance when we store a new value -// immediately whenever the map is promoted to clean and otherwise load a -// unique, missing key. -// -// This forces the Load calls to always acquire the map's mutex. -func BenchmarkAdversarialAlloc(b *testing.B) { - benchMap(b, bench{ - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - var stores, loadsSinceStore int64 - for ; pb.Next(); i++ { - m.Load(i) - if loadsSinceStore++; loadsSinceStore > stores { - m.LoadOrStore(i, stores) - loadsSinceStore = 0 - stores++ - } - } - }, - }) -} - -// BenchmarkAdversarialDelete tests performance when we periodically delete -// one key and add a different one in a large map. -// -// This forces the Load calls to always acquire the map's mutex and periodically -// makes a full copy of the map despite changing only one entry. -func BenchmarkAdversarialDelete(b *testing.B) { - const mapSize = 1 << 10 - - benchMap(b, bench{ - setup: func(_ *testing.B, m mapInterface) { - for i := 0; i < mapSize; i++ { - m.Store(i, i) - } - }, - - perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { - for ; pb.Next(); i++ { - m.Load(i) - - if i%mapSize == 0 { - m.Range(func(k, _ interface{}) bool { - m.Delete(k) - return false - }) - m.Store(i, i) - } - } - }, - }) -} diff --git a/vendor/golang.org/x/sync/syncmap/map_reference_test.go b/vendor/golang.org/x/sync/syncmap/map_reference_test.go deleted file mode 100644 index 923c51b..0000000 --- a/vendor/golang.org/x/sync/syncmap/map_reference_test.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package syncmap_test - -import ( - "sync" - "sync/atomic" -) - -// This file contains reference map implementations for unit-tests. - -// mapInterface is the interface Map implements. -type mapInterface interface { - Load(interface{}) (interface{}, bool) - Store(key, value interface{}) - LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) - Delete(interface{}) - Range(func(key, value interface{}) (shouldContinue bool)) -} - -// RWMutexMap is an implementation of mapInterface using a sync.RWMutex. -type RWMutexMap struct { - mu sync.RWMutex - dirty map[interface{}]interface{} -} - -func (m *RWMutexMap) Load(key interface{}) (value interface{}, ok bool) { - m.mu.RLock() - value, ok = m.dirty[key] - m.mu.RUnlock() - return -} - -func (m *RWMutexMap) Store(key, value interface{}) { - m.mu.Lock() - if m.dirty == nil { - m.dirty = make(map[interface{}]interface{}) - } - m.dirty[key] = value - m.mu.Unlock() -} - -func (m *RWMutexMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { - m.mu.Lock() - actual, loaded = m.dirty[key] - if !loaded { - actual = value - if m.dirty == nil { - m.dirty = make(map[interface{}]interface{}) - } - m.dirty[key] = value - } - m.mu.Unlock() - return actual, loaded -} - -func (m *RWMutexMap) Delete(key interface{}) { - m.mu.Lock() - delete(m.dirty, key) - m.mu.Unlock() -} - -func (m *RWMutexMap) Range(f func(key, value interface{}) (shouldContinue bool)) { - m.mu.RLock() - keys := make([]interface{}, 0, len(m.dirty)) - for k := range m.dirty { - keys = append(keys, k) - } - m.mu.RUnlock() - - for _, k := range keys { - v, ok := m.Load(k) - if !ok { - continue - } - if !f(k, v) { - break - } - } -} - -// DeepCopyMap is an implementation of mapInterface using a Mutex and -// atomic.Value. It makes deep copies of the map on every write to avoid -// acquiring the Mutex in Load. -type DeepCopyMap struct { - mu sync.Mutex - clean atomic.Value -} - -func (m *DeepCopyMap) Load(key interface{}) (value interface{}, ok bool) { - clean, _ := m.clean.Load().(map[interface{}]interface{}) - value, ok = clean[key] - return value, ok -} - -func (m *DeepCopyMap) Store(key, value interface{}) { - m.mu.Lock() - dirty := m.dirty() - dirty[key] = value - m.clean.Store(dirty) - m.mu.Unlock() -} - -func (m *DeepCopyMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { - clean, _ := m.clean.Load().(map[interface{}]interface{}) - actual, loaded = clean[key] - if loaded { - return actual, loaded - } - - m.mu.Lock() - // Reload clean in case it changed while we were waiting on m.mu. - clean, _ = m.clean.Load().(map[interface{}]interface{}) - actual, loaded = clean[key] - if !loaded { - dirty := m.dirty() - dirty[key] = value - actual = value - m.clean.Store(dirty) - } - m.mu.Unlock() - return actual, loaded -} - -func (m *DeepCopyMap) Delete(key interface{}) { - m.mu.Lock() - dirty := m.dirty() - delete(dirty, key) - m.clean.Store(dirty) - m.mu.Unlock() -} - -func (m *DeepCopyMap) Range(f func(key, value interface{}) (shouldContinue bool)) { - clean, _ := m.clean.Load().(map[interface{}]interface{}) - for k, v := range clean { - if !f(k, v) { - break - } - } -} - -func (m *DeepCopyMap) dirty() map[interface{}]interface{} { - clean, _ := m.clean.Load().(map[interface{}]interface{}) - dirty := make(map[interface{}]interface{}, len(clean)+1) - for k, v := range clean { - dirty[k] = v - } - return dirty -} diff --git a/vendor/golang.org/x/sync/syncmap/map_test.go b/vendor/golang.org/x/sync/syncmap/map_test.go deleted file mode 100644 index c883f17..0000000 --- a/vendor/golang.org/x/sync/syncmap/map_test.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package syncmap_test - -import ( - "math/rand" - "reflect" - "runtime" - "sync" - "testing" - "testing/quick" - - "golang.org/x/sync/syncmap" -) - -type mapOp string - -const ( - opLoad = mapOp("Load") - opStore = mapOp("Store") - opLoadOrStore = mapOp("LoadOrStore") - opDelete = mapOp("Delete") -) - -var mapOps = [...]mapOp{opLoad, opStore, opLoadOrStore, opDelete} - -// mapCall is a quick.Generator for calls on mapInterface. -type mapCall struct { - op mapOp - k, v interface{} -} - -func (c mapCall) apply(m mapInterface) (interface{}, bool) { - switch c.op { - case opLoad: - return m.Load(c.k) - case opStore: - m.Store(c.k, c.v) - return nil, false - case opLoadOrStore: - return m.LoadOrStore(c.k, c.v) - case opDelete: - m.Delete(c.k) - return nil, false - default: - panic("invalid mapOp") - } -} - -type mapResult struct { - value interface{} - ok bool -} - -func randValue(r *rand.Rand) interface{} { - b := make([]byte, r.Intn(4)) - for i := range b { - b[i] = 'a' + byte(rand.Intn(26)) - } - return string(b) -} - -func (mapCall) Generate(r *rand.Rand, size int) reflect.Value { - c := mapCall{op: mapOps[rand.Intn(len(mapOps))], k: randValue(r)} - switch c.op { - case opStore, opLoadOrStore: - c.v = randValue(r) - } - return reflect.ValueOf(c) -} - -func applyCalls(m mapInterface, calls []mapCall) (results []mapResult, final map[interface{}]interface{}) { - for _, c := range calls { - v, ok := c.apply(m) - results = append(results, mapResult{v, ok}) - } - - final = make(map[interface{}]interface{}) - m.Range(func(k, v interface{}) bool { - final[k] = v - return true - }) - - return results, final -} - -func applyMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) { - return applyCalls(new(syncmap.Map), calls) -} - -func applyRWMutexMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) { - return applyCalls(new(RWMutexMap), calls) -} - -func applyDeepCopyMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) { - return applyCalls(new(DeepCopyMap), calls) -} - -func TestMapMatchesRWMutex(t *testing.T) { - if err := quick.CheckEqual(applyMap, applyRWMutexMap, nil); err != nil { - t.Error(err) - } -} - -func TestMapMatchesDeepCopy(t *testing.T) { - if err := quick.CheckEqual(applyMap, applyDeepCopyMap, nil); err != nil { - t.Error(err) - } -} - -func TestConcurrentRange(t *testing.T) { - const mapSize = 1 << 10 - - m := new(syncmap.Map) - for n := int64(1); n <= mapSize; n++ { - m.Store(n, int64(n)) - } - - done := make(chan struct{}) - var wg sync.WaitGroup - defer func() { - close(done) - wg.Wait() - }() - for g := int64(runtime.GOMAXPROCS(0)); g > 0; g-- { - r := rand.New(rand.NewSource(g)) - wg.Add(1) - go func(g int64) { - defer wg.Done() - for i := int64(0); ; i++ { - select { - case <-done: - return - default: - } - for n := int64(1); n < mapSize; n++ { - if r.Int63n(mapSize) == 0 { - m.Store(n, n*i*g) - } else { - m.Load(n) - } - } - } - }(g) - } - - iters := 1 << 10 - if testing.Short() { - iters = 16 - } - for n := iters; n > 0; n-- { - seen := make(map[int64]bool, mapSize) - - m.Range(func(ki, vi interface{}) bool { - k, v := ki.(int64), vi.(int64) - if v%k != 0 { - t.Fatalf("while Storing multiples of %v, Range saw value %v", k, v) - } - if seen[k] { - t.Fatalf("Range visited key %v twice", k) - } - seen[k] = true - return true - }) - - if len(seen) != mapSize { - t.Fatalf("Range visited %v elements of %v-element Map", len(seen), mapSize) - } - } -}