mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-10-19 13:49:53 +00:00
ff3e84ad67
updating kubernetes to 1.28.0 in the main repo. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
128 lines
3.8 KiB
Go
128 lines
3.8 KiB
Go
// Copyright 2022 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 (
|
|
"math/bits"
|
|
|
|
"golang.org/x/exp/constraints"
|
|
)
|
|
|
|
// Sort sorts a slice of any ordered type in ascending order.
|
|
// Sort may fail to sort correctly when sorting slices of floating-point
|
|
// numbers containing Not-a-number (NaN) values.
|
|
// 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)
|
|
pdqsortOrdered(x, 0, n, bits.Len(uint(n)))
|
|
}
|
|
|
|
// SortFunc sorts the slice x in ascending order as determined by the less function.
|
|
// This sort is not guaranteed to be stable.
|
|
//
|
|
// SortFunc requires that less is a strict weak ordering.
|
|
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
|
|
func SortFunc[E any](x []E, less func(a, b E) bool) {
|
|
n := len(x)
|
|
pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less)
|
|
}
|
|
|
|
// SortStable sorts the slice x while keeping the original order of equal
|
|
// elements, using less to compare elements.
|
|
func SortStableFunc[E any](x []E, less func(a, b E) bool) {
|
|
stableLessFunc(x, len(x), less)
|
|
}
|
|
|
|
// IsSorted reports whether x is sorted in ascending order.
|
|
func IsSorted[E constraints.Ordered](x []E) bool {
|
|
for i := len(x) - 1; i > 0; i-- {
|
|
if x[i] < x[i-1] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// IsSortedFunc reports whether x is sorted in ascending order, with less as the
|
|
// comparison function.
|
|
func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool {
|
|
for i := len(x) - 1; i > 0; i-- {
|
|
if less(x[i], x[i-1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// 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
|
|
// 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.
|
|
func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
|
|
// search returns the leftmost position where f returns true, or len(x) if f
|
|
// returns false for all x. This is the insertion position for target in x,
|
|
// and could point to an element that's either == target or not.
|
|
pos := search(len(x), func(i int) bool { return x[i] >= target })
|
|
if pos >= len(x) || x[pos] != target {
|
|
return pos, false
|
|
} else {
|
|
return pos, true
|
|
}
|
|
}
|
|
|
|
// BinarySearchFunc works like BinarySearch, but uses a custom comparison
|
|
// function. The slice must be sorted in increasing order, where "increasing" is
|
|
// defined by cmp. cmp(a, b) is expected to return an integer comparing the two
|
|
// parameters: 0 if a == b, a negative number if a < b and a positive number if
|
|
// a > b.
|
|
func BinarySearchFunc[E any](x []E, target E, cmp func(E, E) int) (int, bool) {
|
|
pos := search(len(x), func(i int) bool { return cmp(x[i], target) >= 0 })
|
|
if pos >= len(x) || cmp(x[pos], target) != 0 {
|
|
return pos, false
|
|
} else {
|
|
return pos, true
|
|
}
|
|
}
|
|
|
|
func search(n int, f func(int) bool) int {
|
|
// Define f(-1) == false and f(n) == true.
|
|
// Invariant: f(i-1) == false, f(j) == true.
|
|
i, j := 0, n
|
|
for i < j {
|
|
h := int(uint(i+j) >> 1) // avoid overflow when computing h
|
|
// i ≤ h < j
|
|
if !f(h) {
|
|
i = h + 1 // preserves f(i-1) == false
|
|
} else {
|
|
j = h // preserves f(j) == true
|
|
}
|
|
}
|
|
// i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
|
|
return i
|
|
}
|
|
|
|
type sortedHint int // hint for pdqsort when choosing the pivot
|
|
|
|
const (
|
|
unknownHint sortedHint = iota
|
|
increasingHint
|
|
decreasingHint
|
|
)
|
|
|
|
// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
|
|
type xorshift uint64
|
|
|
|
func (r *xorshift) Next() uint64 {
|
|
*r ^= *r << 13
|
|
*r ^= *r >> 17
|
|
*r ^= *r << 5
|
|
return uint64(*r)
|
|
}
|
|
|
|
func nextPowerOfTwo(length int) uint {
|
|
return 1 << bits.Len(uint(length))
|
|
}
|