Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
jslching committed Nov 11, 2023
2 parents 6bcd9d2 + 1e5e562 commit 7fb95e2
Show file tree
Hide file tree
Showing 7 changed files with 457 additions and 33 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
os: [ ubuntu-latest ]
go-version: [ 1.17.x ]
go-version: [ 1.19.x ]
steps:
- name: Install Go
uses: actions/setup-go@v2
Expand Down Expand Up @@ -36,21 +36,21 @@ jobs:
env:
FULL_REVISION: ${{ github.event.after }}
run: |
echo "::set-output name=rev::${FULL_REVISION:0:8}"
echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
echo "::set-output name=os::$(uname -sr)"
echo "::set-output name=go_version::$(go version | cut -d " " -f 3-)"
echo "rev=${FULL_REVISION:0:8}" >> $GITHUB_OUTPUT
echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
echo "os=$(uname -sr)" >> $GITHUB_OUTPUT
echo "go_version=$(go version | cut -d " " -f 3-)" >> $GITHUB_OUTPUT
if [[ "${{ job.status }}" == "success" ]]; then
echo "::set-output name=status:::moneybag: SUCCESS"
echo "status=:moneybag: SUCCESS" >> $GITHUB_OUTPUT
else
echo "::set-output name=status:::hankey: FAILURE"
echo "status=:hankey: FAILURE" >> $GITHUB_OUTPUT
fi
- name: Post to Slack
id: slack
if: always()
uses: slackapi/slack-github-action@v1.16.0
uses: slackapi/slack-github-action@v1.24.0
with:
# Slack channel id, channel name, or user id to post message.
# See also: https://api.slack.com/methods/chat.postMessage#channels
Expand Down
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/eluv-io/common-go

go 1.17
go 1.19

require (
github.com/PaesslerAG/gval v1.1.2
Expand All @@ -17,7 +17,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/gin-gonic/gin v1.7.7
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/maruel/panicparse/v2 v2.2.0
github.com/maruel/panicparse/v2 v2.3.1
github.com/mattn/go-runewidth v0.0.9
github.com/mitchellh/mapstructure v1.4.3
github.com/modern-go/gls v0.0.0-20220109145502-612d0167dce5
Expand All @@ -33,6 +33,7 @@ require (
github.com/stretchr/testify v1.7.0
github.com/ugorji/go/codec v1.1.7
go.uber.org/atomic v1.9.0
golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5
)

require (
Expand All @@ -56,11 +57,11 @@ require (
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
Expand Down
22 changes: 12 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
Expand Down Expand Up @@ -118,11 +118,11 @@ github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOS
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-msgio v0.1.0 h1:8Q7g/528ivAlfXTFWvWhVjTE8XG8sDTkRUKPYh9+5Q8=
github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE=
github.com/maruel/panicparse/v2 v2.2.0 h1:4/Pd1VuUKlxD7+Dwx9sm49vgAr/tTMexKSh6uPnZQkw=
github.com/maruel/panicparse/v2 v2.2.0/go.mod h1:pMxsKyCewnV3xPaFvvT9NfwvDTcIx2Xqg0qL5Gq0SjM=
github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA=
github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
Expand Down Expand Up @@ -167,8 +167,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285 h1:d54EL9l+XteliUfUCGsEwwuk65dmmxX85VXF+9T6+50=
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285/go.mod h1:fxIDly1xtudczrZeOOlfaUvd2OPb2qZAPuWdU2BsBTk=
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY=
github.com/rjeczalik/notify v0.9.3/go.mod h1:gF3zSOrafR9DQEWSE8TjfI9NkooDxbyT4UgRGKZA0lc=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
Expand Down Expand Up @@ -216,6 +216,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 h1:rxKZ2gOnYxjfmakvUUqh9Gyb6KXfrj7JWTxORTYqb0E=
golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -229,6 +231,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -243,9 +246,8 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand Down
137 changes: 126 additions & 11 deletions util/sliceutil/sliceutil.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package sliceutil

import "reflect"
import (
"reflect"

"golang.org/x/exp/constraints"
)

// Clone is an alias of Copy and returns a shallow copy of the given slice. Returns nil if the given slice is nil.
// Returns an empty slice if the given slice is empty.
func Clone[T any](target []T) []T {
return CopyWithCap(target, 0)
}

// Copy returns a shallow copy of the given slice. Returns nil if the given slice is nil. Returns an empty slice if
// the given slice is empty.
func Copy(target []interface{}) []interface{} {
func Copy[T any](target []T) []T {
return CopyWithCap(target, 0)
}

Expand All @@ -13,7 +23,7 @@ func Copy(target []interface{}) []interface{} {
//
// The duplicate slice will be created with the given capacity (or the original capacity if smaller than the slice's
// length).
func CopyWithCap(target []interface{}, capacity int) []interface{} {
func CopyWithCap[T any](target []T, capacity int) []T {
if target == nil {
return nil
}
Expand All @@ -23,15 +33,15 @@ func CopyWithCap(target []interface{}, capacity int) []interface{} {
c = capacity
}

dup := make([]interface{}, len(target), c)
dup := make([]T, len(target), c)
copy(dup, target)
return dup
}

// Append appends all elements of source to target.
//
// If makeCopy is true, it returns the result in a newly allocated slice and leaves the source/target slices unchanged.
func Append(source []interface{}, target []interface{}, makeCopy bool) (res []interface{}) {
func Append[T any](source []T, target []T, makeCopy bool) (res []T) {
if source == nil && target == nil {
return nil
}
Expand All @@ -48,7 +58,7 @@ func Append(source []interface{}, target []interface{}, makeCopy bool) (res []in
// appended elements.
//
// If makeCopy is true, it returns the result in a newly allocated slice and leaves the source/target slices unchanged.
func Squash(source []interface{}, target []interface{}, makeCopy bool) (res []interface{}) {
func Squash[T any](source []T, target []T, makeCopy bool) (res []T) {
if source == nil && target == nil {
return nil
}
Expand All @@ -69,7 +79,7 @@ func Squash(source []interface{}, target []interface{}, makeCopy bool) (res []in
// SquashAndDedupe appends all elements of source to target and returns the deduped result.
//
// If makeCopy is true, it returns the result in a newly allocated slice and leaves the source/target slices unchanged.
func SquashAndDedupe(source []interface{}, target []interface{}, makeCopy bool) (res []interface{}) {
func SquashAndDedupe[T any](source []T, target []T, makeCopy bool) (res []T) {
if source == nil && target == nil {
return nil
}
Expand All @@ -81,14 +91,14 @@ func SquashAndDedupe(source []interface{}, target []interface{}, makeCopy bool)
// Dedupe removes any duplicates of all elements in target slice.
//
// If makeCopy is true, it returns the result in a newly allocated slice and leaves the target slice unchanged.
func Dedupe(target []interface{}, makeCopy bool) (res []interface{}) {
func Dedupe[T any](target []T, makeCopy bool) (res []T) {
if target == nil {
return nil
}

res = target[:0] // empty slice with same backing array as target
if makeCopy {
res = make([]interface{}, 0, len(target))
res = make([]T, 0, len(target))
}
for _, el := range target {
if !Contains(res, el) {
Expand All @@ -98,12 +108,117 @@ func Dedupe(target []interface{}, makeCopy bool) (res []interface{}) {
return
}

// Equaler is the interface for structs implementing an Equal() function.
type Equaler[T any] interface {
Equal(other T) bool
}

func eq[T any](e1, e2 T) bool {
return any(e1).(Equaler[T]).Equal(e2)
}

func deepEqual[T any](e1, e2 T) bool {
return reflect.DeepEqual(e1, e2)
}

// Contains returns true if the given slice contains the given elements, false otherwise.
func Contains(slice []interface{}, element interface{}) (res bool) {
func Contains[T any](slice []T, element T) (res bool) {
if _, ok := any(element).(Equaler[T]); ok {
return ContainsFn(slice, element, eq[T])
}
return ContainsFn(slice, element, deepEqual[T])
}

// ContainsFn returns true if the slice contains the given element using the provided function to compare elements,
// false otherwise.
func ContainsFn[T any](slice []T, element T, equal func(e1, e2 T) bool) (res bool) {
for _, el := range slice {
if reflect.DeepEqual(el, element) {
if equal(el, element) {
return true
}
}
return false
}

// Remove removes all occurrences of an element from the given slice. Returns the new slice and the number of removed
// elements.
func Remove[T any](slice []T, element T) ([]T, int) {
if _, ok := any(element).(Equaler[T]); ok {
return RemoveFn(slice, element, eq[T])
}
return RemoveFn(slice, element, func(e1, e2 T) bool {
return reflect.DeepEqual(e1, e2)
})
}

// RemoveFn removes all occurrences of an element from the given slice, using the provided function to compare elements.
// Returns the new slice and the number of removed elements.
func RemoveFn[T any](slice []T, element T, equal func(e1, e2 T) bool) ([]T, int) {
return RemoveMatch(slice, func(e T) bool {
return equal(e, element)
})
}

// RemoveMatch removes all elements that match according to the provided match function from the given slice. Removal is
// performed inline, freed up slots at the end of the slice are zeroed out. Returns the updated slice and the number of
// removed elements.
func RemoveMatch[T any](slice []T, match func(e T) bool) ([]T, int) {
var zero T
removed := 0
for i := 0; i < len(slice); i++ {
if match(slice[i]) {
removed++
slice[i] = zero
} else {
if removed > 0 {
slice[i-removed] = slice[i]
slice[i] = zero
}
}
}
return slice[:len(slice)-removed], removed
}

// RemoveIndex removes the element at the given index from the provided slice. Removes nothing if the index is
// out-of-bounds.
func RemoveIndex[T any](slice []T, idx int) []T {
if idx < 0 || idx >= len(slice) {
return slice
}
var zero T
copy(slice[idx:], slice[idx+1:])
slice[len(slice)-1] = zero
return slice[:len(slice)-1]
}

// Compare compares the elements of s1 and s2. The elements are compared sequentially, starting at index 0, until one
// element is not equal to the other. 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 considered less than the longer one. 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[T constraints.Ordered](s1, s2 []T) int {
s2len := len(s2)
for i, v1 := range s1 {
if i >= s2len {
return +1
}
v2 := s2[i]
switch {
case v1 < v2:
return -1
case v1 > v2:
return +1
}
}
if len(s1) < s2len {
return -1
}
return 0
}

// Reverse reverses the order of the elements in the provided slice.
func Reverse[T any](slice []T) {
max := len(slice) - 1
for i := 0; i < (max+1)/2; i++ {
slice[i], slice[max-i] = slice[max-i], slice[i]
}
}
Loading

0 comments on commit 7fb95e2

Please sign in to comment.