update dependencies

This commit is contained in:
Mechiel Lukkien 2023-07-28 22:47:28 +02:00
parent 01adad62b2
commit 3ef1f31359
No known key found for this signature in database
43 changed files with 17416 additions and 1678 deletions

10
go.mod
View file

@ -10,10 +10,10 @@ require (
github.com/mjl-/sherpaprom v0.0.2 github.com/mjl-/sherpaprom v0.0.2
github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_golang v1.14.0
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
golang.org/x/crypto v0.10.0 golang.org/x/crypto v0.11.0
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691
golang.org/x/net v0.11.0 golang.org/x/net v0.12.0
golang.org/x/text v0.10.0 golang.org/x/text v0.11.0
) )
require ( require (
@ -26,7 +26,7 @@ require (
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
golang.org/x/mod v0.11.0 // indirect golang.org/x/mod v0.11.0 // indirect
golang.org/x/sys v0.9.0 // indirect golang.org/x/sys v0.10.0 // indirect
golang.org/x/tools v0.6.0 // indirect golang.org/x/tools v0.6.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
) )

20
go.sum
View file

@ -224,8 +224,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -236,8 +236,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -292,8 +292,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -349,8 +349,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -360,8 +360,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

44
vendor/golang.org/x/exp/slices/cmp.go generated vendored Normal file
View file

@ -0,0 +1,44 @@
// Copyright 2023 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 slices
import "golang.org/x/exp/constraints"
// min is a version of the predeclared function from the Go 1.21 release.
func min[T constraints.Ordered](a, b T) T {
if a < b || isNaN(a) {
return a
}
return b
}
// max is a version of the predeclared function from the Go 1.21 release.
func max[T constraints.Ordered](a, b T) T {
if a > b || isNaN(a) {
return a
}
return b
}
// cmpLess is a copy of cmp.Less from the Go 1.21 release.
func cmpLess[T constraints.Ordered](x, y T) bool {
return (isNaN(x) && !isNaN(y)) || x < y
}
// cmpCompare is a copy of cmp.Compare from the Go 1.21 release.
func cmpCompare[T constraints.Ordered](x, y T) int {
xNaN := isNaN(x)
yNaN := isNaN(y)
if xNaN && yNaN {
return 0
}
if xNaN || x < y {
return -1
}
if yNaN || x > y {
return +1
}
return 0
}

View file

@ -3,23 +3,20 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package slices defines various functions useful with slices of any type. // Package slices defines various functions useful with slices of any type.
// Unless otherwise specified, these functions all apply to the elements
// of a slice at index 0 <= i < len(s).
//
// Note that the less function in IsSortedFunc, SortFunc, SortStableFunc requires a
// strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings),
// or the sorting may fail to sort correctly. A common case is when sorting slices of
// floating-point numbers containing NaN values.
package slices package slices
import "golang.org/x/exp/constraints" import (
"unsafe"
"golang.org/x/exp/constraints"
)
// Equal reports whether two slices are equal: the same length and all // Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false. // elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in increasing index order, and the // Otherwise, the elements are compared in increasing index order, and the
// comparison stops at the first unequal pair. // comparison stops at the first unequal pair.
// Floating point NaNs are not considered equal. // Floating point NaNs are not considered equal.
func Equal[E comparable](s1, s2 []E) bool { func Equal[S ~[]E, E comparable](s1, s2 S) bool {
if len(s1) != len(s2) { if len(s1) != len(s2) {
return false return false
} }
@ -31,12 +28,12 @@ func Equal[E comparable](s1, s2 []E) bool {
return true return true
} }
// EqualFunc reports whether two slices are equal using a comparison // EqualFunc reports whether two slices are equal using an equality
// function on each pair of elements. If the lengths are different, // function on each pair of elements. If the lengths are different,
// EqualFunc returns false. Otherwise, the elements are compared in // EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index // increasing index order, and the comparison stops at the first index
// for which eq returns false. // for which eq returns false.
func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool { func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
if len(s1) != len(s2) { if len(s1) != len(s2) {
return false return false
} }
@ -49,45 +46,37 @@ func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
return true return true
} }
// Compare compares the elements of s1 and s2. // Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
// The elements are compared sequentially, starting at index 0, // of elements. The elements are compared sequentially, starting at index 0,
// until one element is not equal to the other. // until one element is not equal to the other.
// The result of comparing the first non-matching elements is returned. // The result of comparing the first non-matching elements is returned.
// If both slices are equal until one of them ends, the shorter slice is // If both slices are equal until one of them ends, the shorter slice is
// considered less than the longer one. // considered less than the longer one.
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. // The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
// Comparisons involving floating point NaNs are ignored. func Compare[S ~[]E, E constraints.Ordered](s1, s2 S) int {
func Compare[E constraints.Ordered](s1, s2 []E) int {
s2len := len(s2)
for i, v1 := range s1 { for i, v1 := range s1 {
if i >= s2len { if i >= len(s2) {
return +1 return +1
} }
v2 := s2[i] v2 := s2[i]
switch { if c := cmpCompare(v1, v2); c != 0 {
case v1 < v2: return c
return -1
case v1 > v2:
return +1
} }
} }
if len(s1) < s2len { if len(s1) < len(s2) {
return -1 return -1
} }
return 0 return 0
} }
// CompareFunc is like Compare but uses a comparison function // CompareFunc is like [Compare] but uses a custom comparison function on each
// on each pair of elements. The elements are compared in increasing // pair of elements.
// index order, and the comparisons stop after the first time cmp
// returns non-zero.
// The result is the first non-zero result of cmp; if cmp always // The result is the first non-zero result of cmp; if cmp always
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), // returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
// and +1 if len(s1) > len(s2). // and +1 if len(s1) > len(s2).
func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int { func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
s2len := len(s2)
for i, v1 := range s1 { for i, v1 := range s1 {
if i >= s2len { if i >= len(s2) {
return +1 return +1
} }
v2 := s2[i] v2 := s2[i]
@ -95,7 +84,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
return c return c
} }
} }
if len(s1) < s2len { if len(s1) < len(s2) {
return -1 return -1
} }
return 0 return 0
@ -103,7 +92,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
// Index returns the index of the first occurrence of v in s, // Index returns the index of the first occurrence of v in s,
// or -1 if not present. // or -1 if not present.
func Index[E comparable](s []E, v E) int { func Index[S ~[]E, E comparable](s S, v E) int {
for i := range s { for i := range s {
if v == s[i] { if v == s[i] {
return i return i
@ -114,7 +103,7 @@ func Index[E comparable](s []E, v E) int {
// IndexFunc returns the first index i satisfying f(s[i]), // IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do. // or -1 if none do.
func IndexFunc[E any](s []E, f func(E) bool) int { func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
for i := range s { for i := range s {
if f(s[i]) { if f(s[i]) {
return i return i
@ -124,39 +113,104 @@ func IndexFunc[E any](s []E, f func(E) bool) int {
} }
// Contains reports whether v is present in s. // Contains reports whether v is present in s.
func Contains[E comparable](s []E, v E) bool { func Contains[S ~[]E, E comparable](s S, v E) bool {
return Index(s, v) >= 0 return Index(s, v) >= 0
} }
// ContainsFunc reports whether at least one // ContainsFunc reports whether at least one
// element e of s satisfies f(e). // element e of s satisfies f(e).
func ContainsFunc[E any](s []E, f func(E) bool) bool { func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
return IndexFunc(s, f) >= 0 return IndexFunc(s, f) >= 0
} }
// Insert inserts the values v... into s at index i, // Insert inserts the values v... into s at index i,
// returning the modified slice. // returning the modified slice.
// In the returned slice r, r[i] == v[0]. // The elements at s[i:] are shifted up to make room.
// In the returned slice r, r[i] == v[0],
// and r[i+len(v)] == value originally at r[i].
// Insert panics if i is out of range. // Insert panics if i is out of range.
// This function is O(len(s) + len(v)). // This function is O(len(s) + len(v)).
func Insert[S ~[]E, E any](s S, i int, v ...E) S { func Insert[S ~[]E, E any](s S, i int, v ...E) S {
tot := len(s) + len(v) m := len(v)
if tot <= cap(s) { if m == 0 {
s2 := s[:tot] return s
copy(s2[i+len(v):], s[i:]) }
n := len(s)
if i == n {
return append(s, v...)
}
if n+m > cap(s) {
// Use append rather than make so that we bump the size of
// the slice up to the next storage class.
// This is what Grow does but we don't call Grow because
// that might copy the values twice.
s2 := append(s[:i], make(S, n+m-i)...)
copy(s2[i:], v) copy(s2[i:], v)
copy(s2[i+m:], s[i:])
return s2 return s2
} }
s2 := make(S, tot) s = s[:n+m]
copy(s2, s[:i])
copy(s2[i:], v) // before:
copy(s2[i+len(v):], s[i:]) // s: aaaaaaaabbbbccccccccdddd
return s2 // ^ ^ ^ ^
// i i+m n n+m
// after:
// s: aaaaaaaavvvvbbbbcccccccc
// ^ ^ ^ ^
// i i+m n n+m
//
// a are the values that don't move in s.
// v are the values copied in from v.
// b and c are the values from s that are shifted up in index.
// d are the values that get overwritten, never to be seen again.
if !overlaps(v, s[i+m:]) {
// Easy case - v does not overlap either the c or d regions.
// (It might be in some of a or b, or elsewhere entirely.)
// The data we copy up doesn't write to v at all, so just do it.
copy(s[i+m:], s[i:])
// Now we have
// s: aaaaaaaabbbbbbbbcccccccc
// ^ ^ ^ ^
// i i+m n n+m
// Note the b values are duplicated.
copy(s[i:], v)
// Now we have
// s: aaaaaaaavvvvbbbbcccccccc
// ^ ^ ^ ^
// i i+m n n+m
// That's the result we want.
return s
}
// The hard case - v overlaps c or d. We can't just shift up
// the data because we'd move or clobber the values we're trying
// to insert.
// So instead, write v on top of d, then rotate.
copy(s[n:], v)
// Now we have
// s: aaaaaaaabbbbccccccccvvvv
// ^ ^ ^ ^
// i i+m n n+m
rotateRight(s[i:], m)
// Now we have
// s: aaaaaaaavvvvbbbbcccccccc
// ^ ^ ^ ^
// i i+m n n+m
// That's the result we want.
return s
} }
// Delete removes the elements s[i:j] from s, returning the modified slice. // Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if s[i:j] is not a valid slice of s. // Delete panics if s[i:j] is not a valid slice of s.
// Delete modifies the contents of the slice s; it does not create a new slice.
// Delete is O(len(s)-j), so if many items must be deleted, it is better to // Delete is O(len(s)-j), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time. // make a single call deleting them all together than to delete one at a time.
// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those // Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
@ -168,22 +222,113 @@ func Delete[S ~[]E, E any](s S, i, j int) S {
return append(s[:i], s[j:]...) return append(s[:i], s[j:]...)
} }
// DeleteFunc removes any elements from s for which del returns true,
// returning the modified slice.
// When DeleteFunc removes m elements, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage
// collected.
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
i := IndexFunc(s, del)
if i == -1 {
return s
}
// Don't start copying elements until we find one to delete.
for j := i + 1; j < len(s); j++ {
if v := s[j]; !del(v) {
s[i] = v
i++
}
}
return s[:i]
}
// Replace replaces the elements s[i:j] by the given v, and returns the // Replace replaces the elements s[i:j] by the given v, and returns the
// modified slice. Replace panics if s[i:j] is not a valid slice of s. // modified slice. Replace panics if s[i:j] is not a valid slice of s.
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S { func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
_ = s[i:j] // verify that i:j is a valid subslice _ = s[i:j] // verify that i:j is a valid subslice
if i == j {
return Insert(s, i, v...)
}
if j == len(s) {
return append(s[:i], v...)
}
tot := len(s[:i]) + len(v) + len(s[j:]) tot := len(s[:i]) + len(v) + len(s[j:])
if tot <= cap(s) { if tot > cap(s) {
s2 := s[:tot] // Too big to fit, allocate and copy over.
copy(s2[i+len(v):], s[j:]) s2 := append(s[:i], make(S, tot-i)...) // See Insert
copy(s2[i:], v) copy(s2[i:], v)
copy(s2[i+len(v):], s[j:])
return s2 return s2
} }
s2 := make(S, tot)
copy(s2, s[:i]) r := s[:tot]
copy(s2[i:], v)
copy(s2[i+len(v):], s[j:]) if i+len(v) <= j {
return s2 // Easy, as v fits in the deleted portion.
copy(r[i:], v)
if i+len(v) != j {
copy(r[i+len(v):], s[j:])
}
return r
}
// We are expanding (v is bigger than j-i).
// The situation is something like this:
// (example has i=4,j=8,len(s)=16,len(v)=6)
// s: aaaaxxxxbbbbbbbbyy
// ^ ^ ^ ^
// i j len(s) tot
// a: prefix of s
// x: deleted range
// b: more of s
// y: area to expand into
if !overlaps(r[i+len(v):], v) {
// Easy, as v is not clobbered by the first copy.
copy(r[i+len(v):], s[j:])
copy(r[i:], v)
return r
}
// This is a situation where we don't have a single place to which
// we can copy v. Parts of it need to go to two different places.
// We want to copy the prefix of v into y and the suffix into x, then
// rotate |y| spots to the right.
//
// v[2:] v[:2]
// | |
// s: aaaavvvvbbbbbbbbvv
// ^ ^ ^ ^
// i j len(s) tot
//
// If either of those two destinations don't alias v, then we're good.
y := len(v) - (j - i) // length of y portion
if !overlaps(r[i:j], v) {
copy(r[i:j], v[y:])
copy(r[len(s):], v[:y])
rotateRight(r[i:], y)
return r
}
if !overlaps(r[len(s):], v) {
copy(r[len(s):], v[:y])
copy(r[i:j], v[y:])
rotateRight(r[i:], y)
return r
}
// Now we know that v overlaps both x and y.
// That means that the entirety of b is *inside* v.
// So we don't need to preserve b at all; instead we
// can copy v first, then copy the b part of v out of
// v to the right destination.
k := startIdx(v, s[j:])
copy(r[i:], v)
copy(r[i+len(v):], r[i+k:])
return r
} }
// Clone returns a copy of the slice. // Clone returns a copy of the slice.
@ -198,7 +343,8 @@ func Clone[S ~[]E, E any](s S) S {
// Compact replaces consecutive runs of equal elements with a single copy. // Compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix. // This is like the uniq command found on Unix.
// Compact modifies the contents of the slice s; it does not create a new slice. // Compact modifies the contents of the slice s and returns the modified slice,
// which may have a smaller length.
// When Compact discards m elements in total, it might not modify the elements // When Compact discards m elements in total, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider // s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage collected. // zeroing those elements so that objects they reference can be garbage collected.
@ -218,7 +364,8 @@ func Compact[S ~[]E, E comparable](s S) S {
return s[:i] return s[:i]
} }
// CompactFunc is like Compact but uses a comparison function. // CompactFunc is like [Compact] but uses an equality function to compare elements.
// For runs of elements that compare equal, CompactFunc keeps the first one.
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
if len(s) < 2 { if len(s) < 2 {
return s return s
@ -256,3 +403,97 @@ func Grow[S ~[]E, E any](s S, n int) S {
func Clip[S ~[]E, E any](s S) S { func Clip[S ~[]E, E any](s S) S {
return s[:len(s):len(s)] return s[:len(s):len(s)]
} }
// Rotation algorithm explanation:
//
// rotate left by 2
// start with
// 0123456789
// split up like this
// 01 234567 89
// swap first 2 and last 2
// 89 234567 01
// join first parts
// 89234567 01
// recursively rotate first left part by 2
// 23456789 01
// join at the end
// 2345678901
//
// rotate left by 8
// start with
// 0123456789
// split up like this
// 01 234567 89
// swap first 2 and last 2
// 89 234567 01
// join last parts
// 89 23456701
// recursively rotate second part left by 6
// 89 01234567
// join at the end
// 8901234567
// TODO: There are other rotate algorithms.
// This algorithm has the desirable property that it moves each element exactly twice.
// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes.
// The follow-cycles algorithm can be 1-write but it is not very cache friendly.
// rotateLeft rotates b left by n spaces.
// s_final[i] = s_orig[i+r], wrapping around.
func rotateLeft[E any](s []E, r int) {
for r != 0 && r != len(s) {
if r*2 <= len(s) {
swap(s[:r], s[len(s)-r:])
s = s[:len(s)-r]
} else {
swap(s[:len(s)-r], s[r:])
s, r = s[len(s)-r:], r*2-len(s)
}
}
}
func rotateRight[E any](s []E, r int) {
rotateLeft(s, len(s)-r)
}
// swap swaps the contents of x and y. x and y must be equal length and disjoint.
func swap[E any](x, y []E) {
for i := 0; i < len(x); i++ {
x[i], y[i] = y[i], x[i]
}
}
// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap.
func overlaps[E any](a, b []E) bool {
if len(a) == 0 || len(b) == 0 {
return false
}
elemSize := unsafe.Sizeof(a[0])
if elemSize == 0 {
return false
}
// TODO: use a runtime/unsafe facility once one becomes available. See issue 12445.
// Also see crypto/internal/alias/alias.go:AnyOverlap
return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) &&
uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1)
}
// startIdx returns the index in haystack where the needle starts.
// prerequisite: the needle must be aliased entirely inside the haystack.
func startIdx[E any](haystack, needle []E) int {
p := &needle[0]
for i := range haystack {
if p == &haystack[i] {
return i
}
}
// TODO: what if the overlap is by a non-integral number of Es?
panic("needle not found")
}
// Reverse reverses the elements of the slice in place.
func Reverse[S ~[]E, E any](s S) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -exp
package slices package slices
import ( import (
@ -11,57 +13,116 @@ import (
) )
// Sort sorts a slice of any ordered type in ascending order. // Sort sorts a slice of any ordered type in ascending order.
// Sort may fail to sort correctly when sorting slices of floating-point // When sorting floating-point numbers, NaNs are ordered before other values.
// numbers containing Not-a-number (NaN) values. func Sort[S ~[]E, E constraints.Ordered](x S) {
// Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))})
// instead if the input may contain NaNs.
func Sort[E constraints.Ordered](x []E) {
n := len(x) n := len(x)
pdqsortOrdered(x, 0, n, bits.Len(uint(n))) pdqsortOrdered(x, 0, n, bits.Len(uint(n)))
} }
// SortFunc sorts the slice x in ascending order as determined by the less function. // SortFunc sorts the slice x in ascending order as determined by the cmp
// This sort is not guaranteed to be stable. // function. This sort is not guaranteed to be stable.
// cmp(a, b) should return a negative number when a < b, a positive number when
// a > b and zero when a == b.
// //
// SortFunc requires that less is a strict weak ordering. // SortFunc requires that cmp is a strict weak ordering.
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. // See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
func SortFunc[E any](x []E, less func(a, b E) bool) { func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
n := len(x) n := len(x)
pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less) pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp)
} }
// SortStableFunc sorts the slice x while keeping the original order of equal // SortStableFunc sorts the slice x while keeping the original order of equal
// elements, using less to compare elements. // elements, using cmp to compare elements in the same way as [SortFunc].
func SortStableFunc[E any](x []E, less func(a, b E) bool) { func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
stableLessFunc(x, len(x), less) stableCmpFunc(x, len(x), cmp)
} }
// IsSorted reports whether x is sorted in ascending order. // IsSorted reports whether x is sorted in ascending order.
func IsSorted[E constraints.Ordered](x []E) bool { func IsSorted[S ~[]E, E constraints.Ordered](x S) bool {
for i := len(x) - 1; i > 0; i-- { for i := len(x) - 1; i > 0; i-- {
if x[i] < x[i-1] { if cmpLess(x[i], x[i-1]) {
return false return false
} }
} }
return true return true
} }
// IsSortedFunc reports whether x is sorted in ascending order, with less as the // IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
// comparison function. // comparison function as defined by [SortFunc].
func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool { func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
for i := len(x) - 1; i > 0; i-- { for i := len(x) - 1; i > 0; i-- {
if less(x[i], x[i-1]) { if cmp(x[i], x[i-1]) < 0 {
return false return false
} }
} }
return true return true
} }
// Min returns the minimal value in x. It panics if x is empty.
// For floating-point numbers, Min propagates NaNs (any NaN value in x
// forces the output to be NaN).
func Min[S ~[]E, E constraints.Ordered](x S) E {
if len(x) < 1 {
panic("slices.Min: empty list")
}
m := x[0]
for i := 1; i < len(x); i++ {
m = min(m, x[i])
}
return m
}
// MinFunc returns the minimal value in x, using cmp to compare elements.
// It panics if x is empty. If there is more than one minimal element
// according to the cmp function, MinFunc returns the first one.
func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
if len(x) < 1 {
panic("slices.MinFunc: empty list")
}
m := x[0]
for i := 1; i < len(x); i++ {
if cmp(x[i], m) < 0 {
m = x[i]
}
}
return m
}
// Max returns the maximal value in x. It panics if x is empty.
// For floating-point E, Max propagates NaNs (any NaN value in x
// forces the output to be NaN).
func Max[S ~[]E, E constraints.Ordered](x S) E {
if len(x) < 1 {
panic("slices.Max: empty list")
}
m := x[0]
for i := 1; i < len(x); i++ {
m = max(m, x[i])
}
return m
}
// MaxFunc returns the maximal value in x, using cmp to compare elements.
// It panics if x is empty. If there is more than one maximal element
// according to the cmp function, MaxFunc returns the first one.
func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
if len(x) < 1 {
panic("slices.MaxFunc: empty list")
}
m := x[0]
for i := 1; i < len(x); i++ {
if cmp(x[i], m) > 0 {
m = x[i]
}
}
return m
}
// BinarySearch searches for target in a sorted slice and returns the position // BinarySearch searches for target in a sorted slice and returns the position
// where target is found, or the position where target would appear in the // where target is found, or the position where target would appear in the
// sort order; it also returns a bool saying whether the target is really found // sort order; it also returns a bool saying whether the target is really found
// in the slice. The slice must be sorted in increasing order. // in the slice. The slice must be sorted in increasing order.
func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) { func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) (int, bool) {
// Inlining is faster than calling BinarySearchFunc with a lambda. // Inlining is faster than calling BinarySearchFunc with a lambda.
n := len(x) n := len(x)
// Define x[-1] < target and x[n] >= target. // Define x[-1] < target and x[n] >= target.
@ -70,24 +131,24 @@ func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
for i < j { for i < j {
h := int(uint(i+j) >> 1) // avoid overflow when computing h h := int(uint(i+j) >> 1) // avoid overflow when computing h
// i ≤ h < j // i ≤ h < j
if x[h] < target { if cmpLess(x[h], target) {
i = h + 1 // preserves x[i-1] < target i = h + 1 // preserves x[i-1] < target
} else { } else {
j = h // preserves x[j] >= target j = h // preserves x[j] >= target
} }
} }
// i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i. // i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i.
return i, i < n && x[i] == target return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target)))
} }
// BinarySearchFunc works like BinarySearch, but uses a custom comparison // BinarySearchFunc works like [BinarySearch], but uses a custom comparison
// function. The slice must be sorted in increasing order, where "increasing" // function. The slice must be sorted in increasing order, where "increasing"
// is defined by cmp. cmp should return 0 if the slice element matches // is defined by cmp. cmp should return 0 if the slice element matches
// the target, a negative number if the slice element precedes the target, // the target, a negative number if the slice element precedes the target,
// or a positive number if the slice element follows the target. // or a positive number if the slice element follows the target.
// cmp must implement the same ordering as the slice, such that if // cmp must implement the same ordering as the slice, such that if
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice. // cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool) { func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
n := len(x) n := len(x)
// Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 . // Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 .
// Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0. // Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0.
@ -126,3 +187,9 @@ func (r *xorshift) Next() uint64 {
func nextPowerOfTwo(length int) uint { func nextPowerOfTwo(length int) uint {
return 1 << bits.Len(uint(length)) return 1 << bits.Len(uint(length))
} }
// isNaN reports whether x is a NaN without requiring the math package.
// This will always return false if T is not floating-point.
func isNaN[T constraints.Ordered](x T) bool {
return x != x
}

View file

@ -6,28 +6,28 @@
package slices package slices
// insertionSortLessFunc sorts data[a:b] using insertion sort. // insertionSortCmpFunc sorts data[a:b] using insertion sort.
func insertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
for i := a + 1; i < b; i++ { for i := a + 1; i < b; i++ {
for j := i; j > a && less(data[j], data[j-1]); j-- { for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- {
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
} }
} }
} }
// siftDownLessFunc implements the heap property on data[lo:hi]. // siftDownCmpFunc implements the heap property on data[lo:hi].
// first is an offset into the array where the root of the heap lies. // first is an offset into the array where the root of the heap lies.
func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool) { func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) {
root := lo root := lo
for { for {
child := 2*root + 1 child := 2*root + 1
if child >= hi { if child >= hi {
break break
} }
if child+1 < hi && less(data[first+child], data[first+child+1]) { if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) {
child++ child++
} }
if !less(data[first+root], data[first+child]) { if !(cmp(data[first+root], data[first+child]) < 0) {
return return
} }
data[first+root], data[first+child] = data[first+child], data[first+root] data[first+root], data[first+child] = data[first+child], data[first+root]
@ -35,30 +35,30 @@ func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool
} }
} }
func heapSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
first := a first := a
lo := 0 lo := 0
hi := b - a hi := b - a
// Build heap with greatest element at top. // Build heap with greatest element at top.
for i := (hi - 1) / 2; i >= 0; i-- { for i := (hi - 1) / 2; i >= 0; i-- {
siftDownLessFunc(data, i, hi, first, less) siftDownCmpFunc(data, i, hi, first, cmp)
} }
// Pop elements, largest first, into end of data. // Pop elements, largest first, into end of data.
for i := hi - 1; i >= 0; i-- { for i := hi - 1; i >= 0; i-- {
data[first], data[first+i] = data[first+i], data[first] data[first], data[first+i] = data[first+i], data[first]
siftDownLessFunc(data, lo, i, first, less) siftDownCmpFunc(data, lo, i, first, cmp)
} }
} }
// pdqsortLessFunc sorts data[a:b]. // pdqsortCmpFunc sorts data[a:b].
// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. // The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort.
// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf // pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf
// C++ implementation: https://github.com/orlp/pdqsort // C++ implementation: https://github.com/orlp/pdqsort
// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ // Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/
// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. // limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort.
func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) { func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) {
const maxInsertion = 12 const maxInsertion = 12
var ( var (
@ -70,25 +70,25 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
length := b - a length := b - a
if length <= maxInsertion { if length <= maxInsertion {
insertionSortLessFunc(data, a, b, less) insertionSortCmpFunc(data, a, b, cmp)
return return
} }
// Fall back to heapsort if too many bad choices were made. // Fall back to heapsort if too many bad choices were made.
if limit == 0 { if limit == 0 {
heapSortLessFunc(data, a, b, less) heapSortCmpFunc(data, a, b, cmp)
return return
} }
// If the last partitioning was imbalanced, we need to breaking patterns. // If the last partitioning was imbalanced, we need to breaking patterns.
if !wasBalanced { if !wasBalanced {
breakPatternsLessFunc(data, a, b, less) breakPatternsCmpFunc(data, a, b, cmp)
limit-- limit--
} }
pivot, hint := choosePivotLessFunc(data, a, b, less) pivot, hint := choosePivotCmpFunc(data, a, b, cmp)
if hint == decreasingHint { if hint == decreasingHint {
reverseRangeLessFunc(data, a, b, less) reverseRangeCmpFunc(data, a, b, cmp)
// The chosen pivot was pivot-a elements after the start of the array. // The chosen pivot was pivot-a elements after the start of the array.
// After reversing it is pivot-a elements before the end of the array. // After reversing it is pivot-a elements before the end of the array.
// The idea came from Rust's implementation. // The idea came from Rust's implementation.
@ -98,48 +98,48 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
// The slice is likely already sorted. // The slice is likely already sorted.
if wasBalanced && wasPartitioned && hint == increasingHint { if wasBalanced && wasPartitioned && hint == increasingHint {
if partialInsertionSortLessFunc(data, a, b, less) { if partialInsertionSortCmpFunc(data, a, b, cmp) {
return return
} }
} }
// Probably the slice contains many duplicate elements, partition the slice into // Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot. // elements equal to and elements greater than the pivot.
if a > 0 && !less(data[a-1], data[pivot]) { if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) {
mid := partitionEqualLessFunc(data, a, b, pivot, less) mid := partitionEqualCmpFunc(data, a, b, pivot, cmp)
a = mid a = mid
continue continue
} }
mid, alreadyPartitioned := partitionLessFunc(data, a, b, pivot, less) mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp)
wasPartitioned = alreadyPartitioned wasPartitioned = alreadyPartitioned
leftLen, rightLen := mid-a, b-mid leftLen, rightLen := mid-a, b-mid
balanceThreshold := length / 8 balanceThreshold := length / 8
if leftLen < rightLen { if leftLen < rightLen {
wasBalanced = leftLen >= balanceThreshold wasBalanced = leftLen >= balanceThreshold
pdqsortLessFunc(data, a, mid, limit, less) pdqsortCmpFunc(data, a, mid, limit, cmp)
a = mid + 1 a = mid + 1
} else { } else {
wasBalanced = rightLen >= balanceThreshold wasBalanced = rightLen >= balanceThreshold
pdqsortLessFunc(data, mid+1, b, limit, less) pdqsortCmpFunc(data, mid+1, b, limit, cmp)
b = mid b = mid
} }
} }
} }
// partitionLessFunc does one quicksort partition. // partitionCmpFunc does one quicksort partition.
// Let p = data[pivot] // Let p = data[pivot]
// Moves elements in data[a:b] around, so that data[i]<p and data[j]>=p for i<newpivot and j>newpivot. // Moves elements in data[a:b] around, so that data[i]<p and data[j]>=p for i<newpivot and j>newpivot.
// On return, data[newpivot] = p // On return, data[newpivot] = p
func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int, alreadyPartitioned bool) { func partitionCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int, alreadyPartitioned bool) {
data[a], data[pivot] = data[pivot], data[a] data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for i <= j && less(data[i], data[a]) { for i <= j && (cmp(data[i], data[a]) < 0) {
i++ i++
} }
for i <= j && !less(data[j], data[a]) { for i <= j && !(cmp(data[j], data[a]) < 0) {
j-- j--
} }
if i > j { if i > j {
@ -151,10 +151,10 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
j-- j--
for { for {
for i <= j && less(data[i], data[a]) { for i <= j && (cmp(data[i], data[a]) < 0) {
i++ i++
} }
for i <= j && !less(data[j], data[a]) { for i <= j && !(cmp(data[j], data[a]) < 0) {
j-- j--
} }
if i > j { if i > j {
@ -168,17 +168,17 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
return j, false return j, false
} }
// partitionEqualLessFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. // partitionEqualCmpFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. // It assumed that data[a:b] does not contain elements smaller than the data[pivot].
func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int) { func partitionEqualCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int) {
data[a], data[pivot] = data[pivot], data[a] data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for { for {
for i <= j && !less(data[a], data[i]) { for i <= j && !(cmp(data[a], data[i]) < 0) {
i++ i++
} }
for i <= j && less(data[a], data[j]) { for i <= j && (cmp(data[a], data[j]) < 0) {
j-- j--
} }
if i > j { if i > j {
@ -191,15 +191,15 @@ func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E)
return i return i
} }
// partialInsertionSortLessFunc partially sorts a slice, returns true if the slice is sorted at the end. // partialInsertionSortCmpFunc partially sorts a slice, returns true if the slice is sorted at the end.
func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) bool { func partialInsertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) bool {
const ( const (
maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted
shortestShifting = 50 // don't shift any elements on short arrays shortestShifting = 50 // don't shift any elements on short arrays
) )
i := a + 1 i := a + 1
for j := 0; j < maxSteps; j++ { for j := 0; j < maxSteps; j++ {
for i < b && !less(data[i], data[i-1]) { for i < b && !(cmp(data[i], data[i-1]) < 0) {
i++ i++
} }
@ -216,7 +216,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the smaller one to the left. // Shift the smaller one to the left.
if i-a >= 2 { if i-a >= 2 {
for j := i - 1; j >= 1; j-- { for j := i - 1; j >= 1; j-- {
if !less(data[j], data[j-1]) { if !(cmp(data[j], data[j-1]) < 0) {
break break
} }
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
@ -225,7 +225,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the greater one to the right. // Shift the greater one to the right.
if b-i >= 2 { if b-i >= 2 {
for j := i + 1; j < b; j++ { for j := i + 1; j < b; j++ {
if !less(data[j], data[j-1]) { if !(cmp(data[j], data[j-1]) < 0) {
break break
} }
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
@ -235,9 +235,9 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
return false return false
} }
// breakPatternsLessFunc scatters some elements around in an attempt to break some patterns // breakPatternsCmpFunc scatters some elements around in an attempt to break some patterns
// that might cause imbalanced partitions in quicksort. // that might cause imbalanced partitions in quicksort.
func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { func breakPatternsCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
length := b - a length := b - a
if length >= 8 { if length >= 8 {
random := xorshift(length) random := xorshift(length)
@ -253,12 +253,12 @@ func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
} }
} }
// choosePivotLessFunc chooses a pivot in data[a:b]. // choosePivotCmpFunc chooses a pivot in data[a:b].
// //
// [0,8): chooses a static pivot. // [0,8): chooses a static pivot.
// [8,shortestNinther): uses the simple median-of-three method. // [8,shortestNinther): uses the simple median-of-three method.
// [shortestNinther,∞): uses the Tukey ninther method. // [shortestNinther,∞): uses the Tukey ninther method.
func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (pivot int, hint sortedHint) { func choosePivotCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) (pivot int, hint sortedHint) {
const ( const (
shortestNinther = 50 shortestNinther = 50
maxSwaps = 4 * 3 maxSwaps = 4 * 3
@ -276,12 +276,12 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
if l >= 8 { if l >= 8 {
if l >= shortestNinther { if l >= shortestNinther {
// Tukey ninther method, the idea came from Rust's implementation. // Tukey ninther method, the idea came from Rust's implementation.
i = medianAdjacentLessFunc(data, i, &swaps, less) i = medianAdjacentCmpFunc(data, i, &swaps, cmp)
j = medianAdjacentLessFunc(data, j, &swaps, less) j = medianAdjacentCmpFunc(data, j, &swaps, cmp)
k = medianAdjacentLessFunc(data, k, &swaps, less) k = medianAdjacentCmpFunc(data, k, &swaps, cmp)
} }
// Find the median among i, j, k and stores it into j. // Find the median among i, j, k and stores it into j.
j = medianLessFunc(data, i, j, k, &swaps, less) j = medianCmpFunc(data, i, j, k, &swaps, cmp)
} }
switch swaps { switch swaps {
@ -294,29 +294,29 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
} }
} }
// order2LessFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. // order2CmpFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
func order2LessFunc[E any](data []E, a, b int, swaps *int, less func(a, b E) bool) (int, int) { func order2CmpFunc[E any](data []E, a, b int, swaps *int, cmp func(a, b E) int) (int, int) {
if less(data[b], data[a]) { if cmp(data[b], data[a]) < 0 {
*swaps++ *swaps++
return b, a return b, a
} }
return a, b return a, b
} }
// medianLessFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. // medianCmpFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
func medianLessFunc[E any](data []E, a, b, c int, swaps *int, less func(a, b E) bool) int { func medianCmpFunc[E any](data []E, a, b, c int, swaps *int, cmp func(a, b E) int) int {
a, b = order2LessFunc(data, a, b, swaps, less) a, b = order2CmpFunc(data, a, b, swaps, cmp)
b, c = order2LessFunc(data, b, c, swaps, less) b, c = order2CmpFunc(data, b, c, swaps, cmp)
a, b = order2LessFunc(data, a, b, swaps, less) a, b = order2CmpFunc(data, a, b, swaps, cmp)
return b return b
} }
// medianAdjacentLessFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. // medianAdjacentCmpFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
func medianAdjacentLessFunc[E any](data []E, a int, swaps *int, less func(a, b E) bool) int { func medianAdjacentCmpFunc[E any](data []E, a int, swaps *int, cmp func(a, b E) int) int {
return medianLessFunc(data, a-1, a, a+1, swaps, less) return medianCmpFunc(data, a-1, a, a+1, swaps, cmp)
} }
func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { func reverseRangeCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
i := a i := a
j := b - 1 j := b - 1
for i < j { for i < j {
@ -326,37 +326,37 @@ func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
} }
} }
func swapRangeLessFunc[E any](data []E, a, b, n int, less func(a, b E) bool) { func swapRangeCmpFunc[E any](data []E, a, b, n int, cmp func(a, b E) int) {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
data[a+i], data[b+i] = data[b+i], data[a+i] data[a+i], data[b+i] = data[b+i], data[a+i]
} }
} }
func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) { func stableCmpFunc[E any](data []E, n int, cmp func(a, b E) int) {
blockSize := 20 // must be > 0 blockSize := 20 // must be > 0
a, b := 0, blockSize a, b := 0, blockSize
for b <= n { for b <= n {
insertionSortLessFunc(data, a, b, less) insertionSortCmpFunc(data, a, b, cmp)
a = b a = b
b += blockSize b += blockSize
} }
insertionSortLessFunc(data, a, n, less) insertionSortCmpFunc(data, a, n, cmp)
for blockSize < n { for blockSize < n {
a, b = 0, 2*blockSize a, b = 0, 2*blockSize
for b <= n { for b <= n {
symMergeLessFunc(data, a, a+blockSize, b, less) symMergeCmpFunc(data, a, a+blockSize, b, cmp)
a = b a = b
b += 2 * blockSize b += 2 * blockSize
} }
if m := a + blockSize; m < n { if m := a + blockSize; m < n {
symMergeLessFunc(data, a, m, n, less) symMergeCmpFunc(data, a, m, n, cmp)
} }
blockSize *= 2 blockSize *= 2
} }
} }
// symMergeLessFunc merges the two sorted subsequences data[a:m] and data[m:b] using // symMergeCmpFunc merges the two sorted subsequences data[a:m] and data[m:b] using
// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum // the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz // Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in // Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
@ -375,7 +375,7 @@ func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) {
// symMerge assumes non-degenerate arguments: a < m && m < b. // symMerge assumes non-degenerate arguments: a < m && m < b.
// Having the caller check this condition eliminates many leaf recursion calls, // Having the caller check this condition eliminates many leaf recursion calls,
// which improves performance. // which improves performance.
func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { func symMergeCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
// Avoid unnecessary recursions of symMerge // Avoid unnecessary recursions of symMerge
// by direct insertion of data[a] into data[m:b] // by direct insertion of data[a] into data[m:b]
// if data[a:m] only contains one element. // if data[a:m] only contains one element.
@ -387,7 +387,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := b j := b
for i < j { for i < j {
h := int(uint(i+j) >> 1) h := int(uint(i+j) >> 1)
if less(data[h], data[a]) { if cmp(data[h], data[a]) < 0 {
i = h + 1 i = h + 1
} else { } else {
j = h j = h
@ -411,7 +411,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := m j := m
for i < j { for i < j {
h := int(uint(i+j) >> 1) h := int(uint(i+j) >> 1)
if !less(data[m], data[h]) { if !(cmp(data[m], data[h]) < 0) {
i = h + 1 i = h + 1
} else { } else {
j = h j = h
@ -438,7 +438,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
for start < r { for start < r {
c := int(uint(start+r) >> 1) c := int(uint(start+r) >> 1)
if !less(data[p-c], data[c]) { if !(cmp(data[p-c], data[c]) < 0) {
start = c + 1 start = c + 1
} else { } else {
r = c r = c
@ -447,33 +447,33 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
end := n - start end := n - start
if start < m && m < end { if start < m && m < end {
rotateLessFunc(data, start, m, end, less) rotateCmpFunc(data, start, m, end, cmp)
} }
if a < start && start < mid { if a < start && start < mid {
symMergeLessFunc(data, a, start, mid, less) symMergeCmpFunc(data, a, start, mid, cmp)
} }
if mid < end && end < b { if mid < end && end < b {
symMergeLessFunc(data, mid, end, b, less) symMergeCmpFunc(data, mid, end, b, cmp)
} }
} }
// rotateLessFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: // rotateCmpFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
// Data of the form 'x u v y' is changed to 'x v u y'. // Data of the form 'x u v y' is changed to 'x v u y'.
// rotate performs at most b-a many calls to data.Swap, // rotate performs at most b-a many calls to data.Swap,
// and it assumes non-degenerate arguments: a < m && m < b. // and it assumes non-degenerate arguments: a < m && m < b.
func rotateLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { func rotateCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
i := m - a i := m - a
j := b - m j := b - m
for i != j { for i != j {
if i > j { if i > j {
swapRangeLessFunc(data, m-i, m, j, less) swapRangeCmpFunc(data, m-i, m, j, cmp)
i -= j i -= j
} else { } else {
swapRangeLessFunc(data, m-i, m+j-i, i, less) swapRangeCmpFunc(data, m-i, m+j-i, i, cmp)
j -= i j -= i
} }
} }
// i == j // i == j
swapRangeLessFunc(data, m-i, m, i, less) swapRangeCmpFunc(data, m-i, m, i, cmp)
} }

View file

@ -11,7 +11,7 @@ import "golang.org/x/exp/constraints"
// insertionSortOrdered sorts data[a:b] using insertion sort. // insertionSortOrdered sorts data[a:b] using insertion sort.
func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) { func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) {
for i := a + 1; i < b; i++ { for i := a + 1; i < b; i++ {
for j := i; j > a && (data[j] < data[j-1]); j-- { for j := i; j > a && cmpLess(data[j], data[j-1]); j-- {
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
} }
} }
@ -26,10 +26,10 @@ func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) {
if child >= hi { if child >= hi {
break break
} }
if child+1 < hi && (data[first+child] < data[first+child+1]) { if child+1 < hi && cmpLess(data[first+child], data[first+child+1]) {
child++ child++
} }
if !(data[first+root] < data[first+child]) { if !cmpLess(data[first+root], data[first+child]) {
return return
} }
data[first+root], data[first+child] = data[first+child], data[first+root] data[first+root], data[first+child] = data[first+child], data[first+root]
@ -107,7 +107,7 @@ func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) {
// Probably the slice contains many duplicate elements, partition the slice into // Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot. // elements equal to and elements greater than the pivot.
if a > 0 && !(data[a-1] < data[pivot]) { if a > 0 && !cmpLess(data[a-1], data[pivot]) {
mid := partitionEqualOrdered(data, a, b, pivot) mid := partitionEqualOrdered(data, a, b, pivot)
a = mid a = mid
continue continue
@ -138,10 +138,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
data[a], data[pivot] = data[pivot], data[a] data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for i <= j && (data[i] < data[a]) { for i <= j && cmpLess(data[i], data[a]) {
i++ i++
} }
for i <= j && !(data[j] < data[a]) { for i <= j && !cmpLess(data[j], data[a]) {
j-- j--
} }
if i > j { if i > j {
@ -153,10 +153,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
j-- j--
for { for {
for i <= j && (data[i] < data[a]) { for i <= j && cmpLess(data[i], data[a]) {
i++ i++
} }
for i <= j && !(data[j] < data[a]) { for i <= j && !cmpLess(data[j], data[a]) {
j-- j--
} }
if i > j { if i > j {
@ -177,10 +177,10 @@ func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (ne
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for { for {
for i <= j && !(data[a] < data[i]) { for i <= j && !cmpLess(data[a], data[i]) {
i++ i++
} }
for i <= j && (data[a] < data[j]) { for i <= j && cmpLess(data[a], data[j]) {
j-- j--
} }
if i > j { if i > j {
@ -201,7 +201,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
) )
i := a + 1 i := a + 1
for j := 0; j < maxSteps; j++ { for j := 0; j < maxSteps; j++ {
for i < b && !(data[i] < data[i-1]) { for i < b && !cmpLess(data[i], data[i-1]) {
i++ i++
} }
@ -218,7 +218,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the smaller one to the left. // Shift the smaller one to the left.
if i-a >= 2 { if i-a >= 2 {
for j := i - 1; j >= 1; j-- { for j := i - 1; j >= 1; j-- {
if !(data[j] < data[j-1]) { if !cmpLess(data[j], data[j-1]) {
break break
} }
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
@ -227,7 +227,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the greater one to the right. // Shift the greater one to the right.
if b-i >= 2 { if b-i >= 2 {
for j := i + 1; j < b; j++ { for j := i + 1; j < b; j++ {
if !(data[j] < data[j-1]) { if !cmpLess(data[j], data[j-1]) {
break break
} }
data[j], data[j-1] = data[j-1], data[j] data[j], data[j-1] = data[j-1], data[j]
@ -298,7 +298,7 @@ func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, h
// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. // order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) { func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) {
if data[b] < data[a] { if cmpLess(data[b], data[a]) {
*swaps++ *swaps++
return b, a return b, a
} }
@ -389,7 +389,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := b j := b
for i < j { for i < j {
h := int(uint(i+j) >> 1) h := int(uint(i+j) >> 1)
if data[h] < data[a] { if cmpLess(data[h], data[a]) {
i = h + 1 i = h + 1
} else { } else {
j = h j = h
@ -413,7 +413,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := m j := m
for i < j { for i < j {
h := int(uint(i+j) >> 1) h := int(uint(i+j) >> 1)
if !(data[m] < data[h]) { if !cmpLess(data[m], data[h]) {
i = h + 1 i = h + 1
} else { } else {
j = h j = h
@ -440,7 +440,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
for start < r { for start < r {
c := int(uint(start+r) >> 1) c := int(uint(start+r) >> 1)
if !(data[p-c] < data[c]) { if !cmpLess(data[p-c], data[c]) {
start = c + 1 start = c + 1
} else { } else {
r = c r = c

View file

@ -913,7 +913,14 @@ func (z *Tokenizer) readTagAttrKey() {
case ' ', '\n', '\r', '\t', '\f', '/': case ' ', '\n', '\r', '\t', '\f', '/':
z.pendingAttr[0].end = z.raw.end - 1 z.pendingAttr[0].end = z.raw.end - 1
return return
case '=', '>': case '=':
if z.pendingAttr[0].start+1 == z.raw.end {
// WHATWG 13.2.5.32, if we see an equals sign before the attribute name
// begins, we treat it as a character in the attribute name and continue.
continue
}
fallthrough
case '>':
z.raw.end-- z.raw.end--
z.pendingAttr[0].end = z.raw.end z.pendingAttr[0].end = z.raw.end
return return

View file

@ -121,7 +121,7 @@ func CheckJoiners(enable bool) Option {
} }
} }
// StrictDomainName limits the set of permissable ASCII characters to those // StrictDomainName limits the set of permissible ASCII characters to those
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the // allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
// hyphen). This is set by default for MapForLookup and ValidateForRegistration, // hyphen). This is set by default for MapForLookup and ValidateForRegistration,
// but is only useful if ValidateLabels is set. // but is only useful if ValidateLabels is set.

File diff suppressed because it is too large Load diff

5145
vendor/golang.org/x/net/idna/tables15.0.0.go generated vendored Normal file

File diff suppressed because it is too large Load diff

21
vendor/golang.org/x/net/idna/trie.go generated vendored
View file

@ -6,27 +6,6 @@
package idna package idna
// appendMapping appends the mapping for the respective rune. isMapped must be
// true. A mapping is a categorization of a rune as defined in UTS #46.
func (c info) appendMapping(b []byte, s string) []byte {
index := int(c >> indexShift)
if c&xorBit == 0 {
s := mappings[index:]
return append(b, s[1:s[0]+1]...)
}
b = append(b, s...)
if c&inlineXOR == inlineXOR {
// TODO: support and handle two-byte inline masks
b[len(b)-1] ^= byte(index)
} else {
for p := len(b) - int(xorData[index]); p < len(b); p++ {
index++
b[p] ^= xorData[index]
}
}
return b
}
// Sparse block handling code. // Sparse block handling code.
type valueRange struct { type valueRange struct {

31
vendor/golang.org/x/net/idna/trie12.0.0.go generated vendored Normal file
View file

@ -0,0 +1,31 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
// 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.
//go:build !go1.16
// +build !go1.16
package idna
// appendMapping appends the mapping for the respective rune. isMapped must be
// true. A mapping is a categorization of a rune as defined in UTS #46.
func (c info) appendMapping(b []byte, s string) []byte {
index := int(c >> indexShift)
if c&xorBit == 0 {
s := mappings[index:]
return append(b, s[1:s[0]+1]...)
}
b = append(b, s...)
if c&inlineXOR == inlineXOR {
// TODO: support and handle two-byte inline masks
b[len(b)-1] ^= byte(index)
} else {
for p := len(b) - int(xorData[index]); p < len(b); p++ {
index++
b[p] ^= xorData[index]
}
}
return b
}

31
vendor/golang.org/x/net/idna/trie13.0.0.go generated vendored Normal file
View file

@ -0,0 +1,31 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
// 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.
//go:build go1.16
// +build go1.16
package idna
// appendMapping appends the mapping for the respective rune. isMapped must be
// true. A mapping is a categorization of a rune as defined in UTS #46.
func (c info) appendMapping(b []byte, s string) []byte {
index := int(c >> indexShift)
if c&xorBit == 0 {
p := index
return append(b, mappings[mappingIndex[p]:mappingIndex[p+1]]...)
}
b = append(b, s...)
if c&inlineXOR == inlineXOR {
// TODO: support and handle two-byte inline masks
b[len(b)-1] ^= byte(index)
} else {
for p := len(b) - int(xorData[index]); p < len(b); p++ {
index++
b[p] ^= xorData[index]
}
}
return b
}

View file

@ -519,7 +519,7 @@ ccflags="$@"
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^RAW_PAYLOAD_/ || $2 ~ /^RAW_PAYLOAD_/ ||

40
vendor/golang.org/x/sys/unix/mremap.go generated vendored Normal file
View file

@ -0,0 +1,40 @@
// Copyright 2023 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.
//go:build linux
// +build linux
package unix
import "unsafe"
type mremapMmapper struct {
mmapper
mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
}
func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&MREMAP_FIXED != 0 {
return nil, EINVAL
}
pOld := &oldData[cap(oldData)-1]
m.Lock()
defer m.Unlock()
bOld := m.active[pOld]
if bOld == nil || &bOld[0] != &oldData[0] {
return nil, EINVAL
}
newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
if errno != nil {
return nil, errno
}
bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
pNew := &bNew[cap(bNew)-1]
if flags&MREMAP_DONTUNMAP == 0 {
delete(m.active, pOld)
}
m.active[pNew] = bNew
return bNew, nil
}

View file

@ -2124,11 +2124,15 @@ func writevRacedetect(iovecs []Iovec, n int) {
// mmap varies by architecture; see syscall_linux_*.go. // mmap varies by architecture; see syscall_linux_*.go.
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
var mapper = &mmapper{ var mapper = &mremapMmapper{
active: make(map[*byte][]byte), mmapper: mmapper{
mmap: mmap, active: make(map[*byte][]byte),
munmap: munmap, mmap: mmap,
munmap: munmap,
},
mremap: mremap,
} }
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
@ -2139,6 +2143,10 @@ func Munmap(b []byte) (err error) {
return mapper.Munmap(b) return mapper.Munmap(b)
} }
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags)
}
//sys Madvise(b []byte, advice int) (err error) //sys Madvise(b []byte, advice int) (err error)
//sys Mprotect(b []byte, prot int) (err error) //sys Mprotect(b []byte, prot int) (err error)
//sys Mlock(b []byte) (err error) //sys Mlock(b []byte) (err error)
@ -2487,7 +2495,6 @@ func Getresgid() (rgid, egid, sgid int) {
// MqTimedreceive // MqTimedreceive
// MqTimedsend // MqTimedsend
// MqUnlink // MqUnlink
// Mremap
// Msgctl // Msgctl
// Msgget // Msgget
// Msgrcv // Msgrcv

View file

@ -493,6 +493,7 @@ const (
BPF_F_TEST_RUN_ON_CPU = 0x1 BPF_F_TEST_RUN_ON_CPU = 0x1
BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_STATE_FREQ = 0x8
BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 BPF_F_TEST_XDP_LIVE_FRAMES = 0x2
BPF_F_XDP_DEV_BOUND_ONLY = 0x40
BPF_F_XDP_HAS_FRAGS = 0x20 BPF_F_XDP_HAS_FRAGS = 0x20
BPF_H = 0x8 BPF_H = 0x8
BPF_IMM = 0x0 BPF_IMM = 0x0
@ -826,9 +827,9 @@ const (
DM_UUID_FLAG = 0x4000 DM_UUID_FLAG = 0x4000
DM_UUID_LEN = 0x81 DM_UUID_LEN = 0x81
DM_VERSION = 0xc138fd00 DM_VERSION = 0xc138fd00
DM_VERSION_EXTRA = "-ioctl (2022-07-28)" DM_VERSION_EXTRA = "-ioctl (2023-03-01)"
DM_VERSION_MAJOR = 0x4 DM_VERSION_MAJOR = 0x4
DM_VERSION_MINOR = 0x2f DM_VERSION_MINOR = 0x30
DM_VERSION_PATCHLEVEL = 0x0 DM_VERSION_PATCHLEVEL = 0x0
DT_BLK = 0x6 DT_BLK = 0x6
DT_CHR = 0x2 DT_CHR = 0x2
@ -1197,6 +1198,7 @@ const (
FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000 FAN_EVENT_ON_CHILD = 0x8000000
FAN_FS_ERROR = 0x8000 FAN_FS_ERROR = 0x8000
FAN_INFO = 0x20
FAN_MARK_ADD = 0x1 FAN_MARK_ADD = 0x1
FAN_MARK_DONT_FOLLOW = 0x4 FAN_MARK_DONT_FOLLOW = 0x4
FAN_MARK_EVICTABLE = 0x200 FAN_MARK_EVICTABLE = 0x200
@ -1233,6 +1235,8 @@ const (
FAN_REPORT_PIDFD = 0x80 FAN_REPORT_PIDFD = 0x80
FAN_REPORT_TARGET_FID = 0x1000 FAN_REPORT_TARGET_FID = 0x1000
FAN_REPORT_TID = 0x100 FAN_REPORT_TID = 0x100
FAN_RESPONSE_INFO_AUDIT_RULE = 0x1
FAN_RESPONSE_INFO_NONE = 0x0
FAN_UNLIMITED_MARKS = 0x20 FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10 FAN_UNLIMITED_QUEUE = 0x10
FD_CLOEXEC = 0x1 FD_CLOEXEC = 0x1
@ -1860,6 +1864,7 @@ const (
MEMWRITEOOB64 = 0xc0184d15 MEMWRITEOOB64 = 0xc0184d15
MFD_ALLOW_SEALING = 0x2 MFD_ALLOW_SEALING = 0x2
MFD_CLOEXEC = 0x1 MFD_CLOEXEC = 0x1
MFD_EXEC = 0x10
MFD_HUGETLB = 0x4 MFD_HUGETLB = 0x4
MFD_HUGE_16GB = 0x88000000 MFD_HUGE_16GB = 0x88000000
MFD_HUGE_16MB = 0x60000000 MFD_HUGE_16MB = 0x60000000
@ -1875,6 +1880,7 @@ const (
MFD_HUGE_8MB = 0x5c000000 MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f MFD_HUGE_MASK = 0x3f
MFD_HUGE_SHIFT = 0x1a MFD_HUGE_SHIFT = 0x1a
MFD_NOEXEC_SEAL = 0x8
MINIX2_SUPER_MAGIC = 0x2468 MINIX2_SUPER_MAGIC = 0x2468
MINIX2_SUPER_MAGIC2 = 0x2478 MINIX2_SUPER_MAGIC2 = 0x2478
MINIX3_SUPER_MAGIC = 0x4d5a MINIX3_SUPER_MAGIC = 0x4d5a
@ -1898,6 +1904,9 @@ const (
MOUNT_ATTR_SIZE_VER0 = 0x20 MOUNT_ATTR_SIZE_VER0 = 0x20
MOUNT_ATTR_STRICTATIME = 0x20 MOUNT_ATTR_STRICTATIME = 0x20
MOUNT_ATTR__ATIME = 0x70 MOUNT_ATTR__ATIME = 0x70
MREMAP_DONTUNMAP = 0x4
MREMAP_FIXED = 0x2
MREMAP_MAYMOVE = 0x1
MSDOS_SUPER_MAGIC = 0x4d44 MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000 MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000 MSG_CMSG_CLOEXEC = 0x40000000
@ -2204,6 +2213,7 @@ const (
PACKET_USER = 0x6 PACKET_USER = 0x6
PACKET_VERSION = 0xa PACKET_VERSION = 0xa
PACKET_VNET_HDR = 0xf PACKET_VNET_HDR = 0xf
PACKET_VNET_HDR_SZ = 0x18
PARITY_CRC16_PR0 = 0x2 PARITY_CRC16_PR0 = 0x2
PARITY_CRC16_PR0_CCITT = 0x4 PARITY_CRC16_PR0_CCITT = 0x4
PARITY_CRC16_PR1 = 0x3 PARITY_CRC16_PR1 = 0x3
@ -2221,6 +2231,7 @@ const (
PERF_ATTR_SIZE_VER5 = 0x70 PERF_ATTR_SIZE_VER5 = 0x70
PERF_ATTR_SIZE_VER6 = 0x78 PERF_ATTR_SIZE_VER6 = 0x78
PERF_ATTR_SIZE_VER7 = 0x80 PERF_ATTR_SIZE_VER7 = 0x80
PERF_ATTR_SIZE_VER8 = 0x88
PERF_AUX_FLAG_COLLISION = 0x8 PERF_AUX_FLAG_COLLISION = 0x8
PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0 PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0
PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100 PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100
@ -2361,6 +2372,7 @@ const (
PR_FP_EXC_UND = 0x40000 PR_FP_EXC_UND = 0x40000
PR_FP_MODE_FR = 0x1 PR_FP_MODE_FR = 0x1
PR_FP_MODE_FRE = 0x2 PR_FP_MODE_FRE = 0x2
PR_GET_AUXV = 0x41555856
PR_GET_CHILD_SUBREAPER = 0x25 PR_GET_CHILD_SUBREAPER = 0x25
PR_GET_DUMPABLE = 0x3 PR_GET_DUMPABLE = 0x3
PR_GET_ENDIAN = 0x13 PR_GET_ENDIAN = 0x13
@ -2369,6 +2381,8 @@ const (
PR_GET_FP_MODE = 0x2e PR_GET_FP_MODE = 0x2e
PR_GET_IO_FLUSHER = 0x3a PR_GET_IO_FLUSHER = 0x3a
PR_GET_KEEPCAPS = 0x7 PR_GET_KEEPCAPS = 0x7
PR_GET_MDWE = 0x42
PR_GET_MEMORY_MERGE = 0x44
PR_GET_NAME = 0x10 PR_GET_NAME = 0x10
PR_GET_NO_NEW_PRIVS = 0x27 PR_GET_NO_NEW_PRIVS = 0x27
PR_GET_PDEATHSIG = 0x2 PR_GET_PDEATHSIG = 0x2
@ -2389,6 +2403,7 @@ const (
PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_GET = 0x22
PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_LATE = 0x0
PR_MCE_KILL_SET = 0x1 PR_MCE_KILL_SET = 0x1
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_DISABLE_MANAGEMENT = 0x2c
PR_MPX_ENABLE_MANAGEMENT = 0x2b PR_MPX_ENABLE_MANAGEMENT = 0x2b
PR_MTE_TAG_MASK = 0x7fff8 PR_MTE_TAG_MASK = 0x7fff8
@ -2423,6 +2438,8 @@ const (
PR_SET_FP_MODE = 0x2d PR_SET_FP_MODE = 0x2d
PR_SET_IO_FLUSHER = 0x39 PR_SET_IO_FLUSHER = 0x39
PR_SET_KEEPCAPS = 0x8 PR_SET_KEEPCAPS = 0x8
PR_SET_MDWE = 0x41
PR_SET_MEMORY_MERGE = 0x43
PR_SET_MM = 0x23 PR_SET_MM = 0x23
PR_SET_MM_ARG_END = 0x9 PR_SET_MM_ARG_END = 0x9
PR_SET_MM_ARG_START = 0x8 PR_SET_MM_ARG_START = 0x8
@ -2506,6 +2523,7 @@ const (
PTRACE_GETSIGMASK = 0x420a PTRACE_GETSIGMASK = 0x420a
PTRACE_GET_RSEQ_CONFIGURATION = 0x420f PTRACE_GET_RSEQ_CONFIGURATION = 0x420f
PTRACE_GET_SYSCALL_INFO = 0x420e PTRACE_GET_SYSCALL_INFO = 0x420e
PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG = 0x4211
PTRACE_INTERRUPT = 0x4207 PTRACE_INTERRUPT = 0x4207
PTRACE_KILL = 0x8 PTRACE_KILL = 0x8
PTRACE_LISTEN = 0x4208 PTRACE_LISTEN = 0x4208
@ -2536,6 +2554,7 @@ const (
PTRACE_SETREGSET = 0x4205 PTRACE_SETREGSET = 0x4205
PTRACE_SETSIGINFO = 0x4203 PTRACE_SETSIGINFO = 0x4203
PTRACE_SETSIGMASK = 0x420b PTRACE_SETSIGMASK = 0x420b
PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210
PTRACE_SINGLESTEP = 0x9 PTRACE_SINGLESTEP = 0x9
PTRACE_SYSCALL = 0x18 PTRACE_SYSCALL = 0x18
PTRACE_SYSCALL_INFO_ENTRY = 0x1 PTRACE_SYSCALL_INFO_ENTRY = 0x1
@ -3072,7 +3091,7 @@ const (
TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_NAME = "TASKSTATS"
TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_GENL_VERSION = 0x1
TASKSTATS_TYPE_MAX = 0x6 TASKSTATS_TYPE_MAX = 0x6
TASKSTATS_VERSION = 0xd TASKSTATS_VERSION = 0xe
TCIFLUSH = 0x0 TCIFLUSH = 0x0
TCIOFF = 0x2 TCIOFF = 0x2
TCIOFLUSH = 0x2 TCIOFLUSH = 0x2
@ -3238,6 +3257,7 @@ const (
TP_STATUS_COPY = 0x2 TP_STATUS_COPY = 0x2
TP_STATUS_CSUMNOTREADY = 0x8 TP_STATUS_CSUMNOTREADY = 0x8
TP_STATUS_CSUM_VALID = 0x80 TP_STATUS_CSUM_VALID = 0x80
TP_STATUS_GSO_TCP = 0x100
TP_STATUS_KERNEL = 0x0 TP_STATUS_KERNEL = 0x0
TP_STATUS_LOSING = 0x4 TP_STATUS_LOSING = 0x4
TP_STATUS_SENDING = 0x2 TP_STATUS_SENDING = 0x2

View file

@ -443,6 +443,7 @@ const (
TIOCSWINSZ = 0x5414 TIOCSWINSZ = 0x5414
TIOCVHANGUP = 0x5437 TIOCVHANGUP = 0x5437
TOSTOP = 0x100 TOSTOP = 0x100
TPIDR2_MAGIC = 0x54504902
TUNATTACHFILTER = 0x401054d5 TUNATTACHFILTER = 0x401054d5
TUNDETACHFILTER = 0x401054d6 TUNDETACHFILTER = 0x401054d6
TUNGETDEVNETNS = 0x54e3 TUNGETDEVNETNS = 0x54e3
@ -515,6 +516,7 @@ const (
XCASE = 0x4 XCASE = 0x4
XTABS = 0x1800 XTABS = 0x1800
ZA_MAGIC = 0x54366345 ZA_MAGIC = 0x54366345
ZT_MAGIC = 0x5a544e01
_HIDIOCGRAWNAME = 0x80804804 _HIDIOCGRAWNAME = 0x80804804
_HIDIOCGRAWPHYS = 0x80404805 _HIDIOCGRAWPHYS = 0x80404805
_HIDIOCGRAWUNIQ = 0x80404808 _HIDIOCGRAWUNIQ = 0x80404808

View file

@ -1868,6 +1868,17 @@ func munmap(addr uintptr, length uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) {
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldaddr), uintptr(oldlength), uintptr(newlength), uintptr(flags), uintptr(newaddr), 0)
xaddr = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Madvise(b []byte, advice int) (err error) { func Madvise(b []byte, advice int) (err error) {
var _p0 unsafe.Pointer var _p0 unsafe.Pointer
if len(b) > 0 { if len(b) > 0 {

View file

@ -372,6 +372,7 @@ const (
SYS_LANDLOCK_CREATE_RULESET = 444 SYS_LANDLOCK_CREATE_RULESET = 444
SYS_LANDLOCK_ADD_RULE = 445 SYS_LANDLOCK_ADD_RULE = 445
SYS_LANDLOCK_RESTRICT_SELF = 446 SYS_LANDLOCK_RESTRICT_SELF = 446
SYS_MEMFD_SECRET = 447
SYS_PROCESS_MRELEASE = 448 SYS_PROCESS_MRELEASE = 448
SYS_FUTEX_WAITV = 449 SYS_FUTEX_WAITV = 449
SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_SET_MEMPOLICY_HOME_NODE = 450

View file

@ -1538,6 +1538,10 @@ const (
IFLA_GRO_MAX_SIZE = 0x3a IFLA_GRO_MAX_SIZE = 0x3a
IFLA_TSO_MAX_SIZE = 0x3b IFLA_TSO_MAX_SIZE = 0x3b
IFLA_TSO_MAX_SEGS = 0x3c IFLA_TSO_MAX_SEGS = 0x3c
IFLA_ALLMULTI = 0x3d
IFLA_DEVLINK_PORT = 0x3e
IFLA_GSO_IPV4_MAX_SIZE = 0x3f
IFLA_GRO_IPV4_MAX_SIZE = 0x40
IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0
IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_MASK = 0x1
IFLA_PROTO_DOWN_REASON_VALUE = 0x2 IFLA_PROTO_DOWN_REASON_VALUE = 0x2
@ -1968,7 +1972,7 @@ const (
NFT_MSG_GETFLOWTABLE = 0x17 NFT_MSG_GETFLOWTABLE = 0x17
NFT_MSG_DELFLOWTABLE = 0x18 NFT_MSG_DELFLOWTABLE = 0x18
NFT_MSG_GETRULE_RESET = 0x19 NFT_MSG_GETRULE_RESET = 0x19
NFT_MSG_MAX = 0x1a NFT_MSG_MAX = 0x21
NFTA_LIST_UNSPEC = 0x0 NFTA_LIST_UNSPEC = 0x0
NFTA_LIST_ELEM = 0x1 NFTA_LIST_ELEM = 0x1
NFTA_HOOK_UNSPEC = 0x0 NFTA_HOOK_UNSPEC = 0x0
@ -3651,7 +3655,7 @@ const (
ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_GET = 0x24
ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_PSE_SET = 0x25
ETHTOOL_MSG_RSS_GET = 0x26 ETHTOOL_MSG_RSS_GET = 0x26
ETHTOOL_MSG_USER_MAX = 0x26 ETHTOOL_MSG_USER_MAX = 0x2b
ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_KERNEL_NONE = 0x0
ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1
ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2
@ -3691,7 +3695,7 @@ const (
ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_MODULE_NTF = 0x24
ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_PSE_GET_REPLY = 0x25
ETHTOOL_MSG_RSS_GET_REPLY = 0x26 ETHTOOL_MSG_RSS_GET_REPLY = 0x26
ETHTOOL_MSG_KERNEL_MAX = 0x26 ETHTOOL_MSG_KERNEL_MAX = 0x2b
ETHTOOL_A_HEADER_UNSPEC = 0x0 ETHTOOL_A_HEADER_UNSPEC = 0x0
ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_INDEX = 0x1
ETHTOOL_A_HEADER_DEV_NAME = 0x2 ETHTOOL_A_HEADER_DEV_NAME = 0x2
@ -3795,7 +3799,7 @@ const (
ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb
ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_CQE_SIZE = 0xc
ETHTOOL_A_RINGS_TX_PUSH = 0xd ETHTOOL_A_RINGS_TX_PUSH = 0xd
ETHTOOL_A_RINGS_MAX = 0xd ETHTOOL_A_RINGS_MAX = 0x10
ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_UNSPEC = 0x0
ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_HEADER = 0x1
ETHTOOL_A_CHANNELS_RX_MAX = 0x2 ETHTOOL_A_CHANNELS_RX_MAX = 0x2
@ -3833,14 +3837,14 @@ const (
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17
ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18 ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18
ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19 ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19
ETHTOOL_A_COALESCE_MAX = 0x19 ETHTOOL_A_COALESCE_MAX = 0x1c
ETHTOOL_A_PAUSE_UNSPEC = 0x0 ETHTOOL_A_PAUSE_UNSPEC = 0x0
ETHTOOL_A_PAUSE_HEADER = 0x1 ETHTOOL_A_PAUSE_HEADER = 0x1
ETHTOOL_A_PAUSE_AUTONEG = 0x2 ETHTOOL_A_PAUSE_AUTONEG = 0x2
ETHTOOL_A_PAUSE_RX = 0x3 ETHTOOL_A_PAUSE_RX = 0x3
ETHTOOL_A_PAUSE_TX = 0x4 ETHTOOL_A_PAUSE_TX = 0x4
ETHTOOL_A_PAUSE_STATS = 0x5 ETHTOOL_A_PAUSE_STATS = 0x5
ETHTOOL_A_PAUSE_MAX = 0x5 ETHTOOL_A_PAUSE_MAX = 0x6
ETHTOOL_A_PAUSE_STAT_UNSPEC = 0x0 ETHTOOL_A_PAUSE_STAT_UNSPEC = 0x0
ETHTOOL_A_PAUSE_STAT_PAD = 0x1 ETHTOOL_A_PAUSE_STAT_PAD = 0x1
ETHTOOL_A_PAUSE_STAT_TX_FRAMES = 0x2 ETHTOOL_A_PAUSE_STAT_TX_FRAMES = 0x2
@ -4490,7 +4494,7 @@ const (
NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_HINT = 0xc8
NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAC_MASK = 0xd7
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
NL80211_ATTR_MAX = 0x141 NL80211_ATTR_MAX = 0x145
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_MATCH_SETS = 0x85
@ -4719,7 +4723,7 @@ const (
NL80211_BAND_ATTR_HT_CAPA = 0x4 NL80211_BAND_ATTR_HT_CAPA = 0x4
NL80211_BAND_ATTR_HT_MCS_SET = 0x3 NL80211_BAND_ATTR_HT_MCS_SET = 0x3
NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_IFTYPE_DATA = 0x9
NL80211_BAND_ATTR_MAX = 0xb NL80211_BAND_ATTR_MAX = 0xd
NL80211_BAND_ATTR_RATES = 0x2 NL80211_BAND_ATTR_RATES = 0x2
NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_CAPA = 0x8
NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7
@ -4860,7 +4864,7 @@ const (
NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_IBSS = 0x2c
NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_MESH = 0x45
NL80211_CMD_LEAVE_OCB = 0x6d NL80211_CMD_LEAVE_OCB = 0x6d
NL80211_CMD_MAX = 0x98 NL80211_CMD_MAX = 0x99
NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29
NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_MODIFY_LINK_STA = 0x97
NL80211_CMD_NAN_MATCH = 0x78 NL80211_CMD_NAN_MATCH = 0x78
@ -5841,6 +5845,8 @@ const (
TUN_F_TSO6 = 0x4 TUN_F_TSO6 = 0x4
TUN_F_TSO_ECN = 0x8 TUN_F_TSO_ECN = 0x8
TUN_F_UFO = 0x10 TUN_F_UFO = 0x10
TUN_F_USO4 = 0x20
TUN_F_USO6 = 0x40
) )
const ( const (
@ -5850,9 +5856,10 @@ const (
) )
const ( const (
VIRTIO_NET_HDR_GSO_NONE = 0x0 VIRTIO_NET_HDR_GSO_NONE = 0x0
VIRTIO_NET_HDR_GSO_TCPV4 = 0x1 VIRTIO_NET_HDR_GSO_TCPV4 = 0x1
VIRTIO_NET_HDR_GSO_UDP = 0x3 VIRTIO_NET_HDR_GSO_UDP = 0x3
VIRTIO_NET_HDR_GSO_TCPV6 = 0x4 VIRTIO_NET_HDR_GSO_TCPV6 = 0x4
VIRTIO_NET_HDR_GSO_ECN = 0x80 VIRTIO_NET_HDR_GSO_UDP_L4 = 0x5
VIRTIO_NET_HDR_GSO_ECN = 0x80
) )

View file

@ -337,6 +337,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint32 type cpuMask uint32

View file

@ -350,6 +350,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -328,6 +328,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint32 type cpuMask uint32

View file

@ -329,6 +329,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -330,6 +330,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -333,6 +333,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint32 type cpuMask uint32

View file

@ -332,6 +332,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -332,6 +332,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -333,6 +333,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint32 type cpuMask uint32

View file

@ -340,6 +340,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint32 type cpuMask uint32

View file

@ -339,6 +339,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -339,6 +339,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -357,6 +357,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -352,6 +352,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -334,6 +334,8 @@ type Taskstats struct {
Ac_exe_inode uint64 Ac_exe_inode uint64
Wpcopy_count uint64 Wpcopy_count uint64
Wpcopy_delay_total uint64 Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
} }
type cpuMask uint64 type cpuMask uint64

View file

@ -218,6 +218,10 @@ type SERVICE_FAILURE_ACTIONS struct {
Actions *SC_ACTION Actions *SC_ACTION
} }
type SERVICE_FAILURE_ACTIONS_FLAG struct {
FailureActionsOnNonCrashFailures int32
}
type SC_ACTION struct { type SC_ACTION struct {
Type uint32 Type uint32
Delay uint32 Delay uint32

View file

@ -1,7 +1,7 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.16 //go:build go1.16 && !go1.21
// +build go1.16 // +build go1.16,!go1.21
package bidi package bidi

2043
vendor/golang.org/x/text/unicode/bidi/tables15.0.0.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.16 //go:build go1.16 && !go1.21
// +build go1.16 // +build go1.16,!go1.21
package norm package norm

7908
vendor/golang.org/x/text/unicode/norm/tables15.0.0.go generated vendored Normal file

File diff suppressed because it is too large Load diff

10
vendor/modules.txt vendored
View file

@ -52,7 +52,7 @@ github.com/prometheus/procfs/internal/util
# go.etcd.io/bbolt v1.3.7 # go.etcd.io/bbolt v1.3.7
## explicit; go 1.17 ## explicit; go 1.17
go.etcd.io/bbolt go.etcd.io/bbolt
# golang.org/x/crypto v0.10.0 # golang.org/x/crypto v0.11.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/crypto/acme golang.org/x/crypto/acme
golang.org/x/crypto/acme/autocert golang.org/x/crypto/acme/autocert
@ -60,7 +60,7 @@ golang.org/x/crypto/bcrypt
golang.org/x/crypto/blake2b golang.org/x/crypto/blake2b
golang.org/x/crypto/blowfish golang.org/x/crypto/blowfish
golang.org/x/crypto/pbkdf2 golang.org/x/crypto/pbkdf2
# golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df # golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691
## explicit; go 1.20 ## explicit; go 1.20
golang.org/x/exp/constraints golang.org/x/exp/constraints
golang.org/x/exp/maps golang.org/x/exp/maps
@ -71,7 +71,7 @@ golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile golang.org/x/mod/modfile
golang.org/x/mod/module golang.org/x/mod/module
golang.org/x/mod/semver golang.org/x/mod/semver
# golang.org/x/net v0.11.0 # golang.org/x/net v0.12.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/net/html golang.org/x/net/html
golang.org/x/net/html/atom golang.org/x/net/html/atom
@ -79,14 +79,14 @@ golang.org/x/net/idna
golang.org/x/net/internal/socks golang.org/x/net/internal/socks
golang.org/x/net/proxy golang.org/x/net/proxy
golang.org/x/net/websocket golang.org/x/net/websocket
# golang.org/x/sys v0.9.0 # golang.org/x/sys v0.10.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/sys/cpu golang.org/x/sys/cpu
golang.org/x/sys/execabs golang.org/x/sys/execabs
golang.org/x/sys/internal/unsafeheader golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/unix golang.org/x/sys/unix
golang.org/x/sys/windows golang.org/x/sys/windows
# golang.org/x/text v0.10.0 # golang.org/x/text v0.11.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/text/encoding golang.org/x/text/encoding
golang.org/x/text/encoding/charmap golang.org/x/text/encoding/charmap