mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-16 06:58:20 +00:00
99def96cc2
* Generic Slices library to support different data types ** Main module added under slice_generic.go ** Test cases passing ** Modified Bazel Build accordingly to run test suite * Periods added for the generic slice functions * Build through gazelle & linter fixes * Generic library using reflection for set operations * Improvement in test cases including float 32 * Error Handling using generic error message for unsupported type * Linter fixes and including more test cases * Linter fixes * Linter fixes in Errof function & increasing test coverage * Test cases corrections * Benchmark test added for reflection & non reflection functions Redundancy removed for various data type Panic removed from the code & error handled * documnet linter error removed * Benchmark done with SSZ for reflection and non-reflection based functions * Bazel build file updated * gofmt & golinter error fixes * Added data type support for uint32,int32,byte,int64,uint64 * Removed the redundant code and condition of error handled * changes in linter & fixes * Linter fixes * Individual error handled for slices * Removed unwanted variable t * linter fixes * Removed unwanted conditions * linter & test cases fix * Linter fixes in slice generic * rebuilding with test
159 lines
3.5 KiB
Go
159 lines
3.5 KiB
Go
package slices
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
func interfaceToSlice(slice interface{}) ([]interface{}, error) {
|
|
s := reflect.ValueOf(slice)
|
|
if s.Kind() != reflect.Slice {
|
|
return nil, fmt.Errorf("slice error: not of type slice")
|
|
}
|
|
ret := make([]interface{}, s.Len())
|
|
for i := 0; i < s.Len(); i++ {
|
|
ret[i] = s.Index(i).Interface()
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
// GenericIntersection returns a new set with elements that are common in
|
|
// both sets a and b.
|
|
func GenericIntersection(a, b interface{}) (reflect.Value, error) {
|
|
|
|
set := reflect.MakeSlice(reflect.TypeOf(a), 0, 0)
|
|
set1, err1 := interfaceToSlice(a)
|
|
set2, err2 := interfaceToSlice(b)
|
|
|
|
if err1 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err1)
|
|
}
|
|
|
|
if err2 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err2)
|
|
}
|
|
if len(set1) == 0 || len(set2) == 0 {
|
|
return set, nil
|
|
}
|
|
|
|
m := reflect.MapOf(reflect.TypeOf(set1[0]), reflect.TypeOf(true))
|
|
m1 := reflect.MakeMapWithSize(m, 0)
|
|
for i := 0; i < len(set1); i++ {
|
|
m1.SetMapIndex(reflect.ValueOf(set1[i]), reflect.ValueOf(true))
|
|
}
|
|
|
|
for i := 0; i < len(set2); i++ {
|
|
x := m1.MapIndex(reflect.ValueOf(set2[i]))
|
|
if x.IsValid() {
|
|
if found := x; found.Bool() {
|
|
rv := reflect.ValueOf(set2[i])
|
|
set = reflect.Append(set, rv)
|
|
}
|
|
}
|
|
}
|
|
|
|
return set, nil
|
|
}
|
|
|
|
// GenericUnion returns a new set with elements from both
|
|
// the given sets a and b.
|
|
func GenericUnion(a, b interface{}) (reflect.Value, error) {
|
|
|
|
set := reflect.MakeSlice(reflect.TypeOf(a), 0, 0)
|
|
set1, err1 := interfaceToSlice(a)
|
|
set2, err2 := interfaceToSlice(b)
|
|
|
|
if err1 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err1)
|
|
}
|
|
|
|
if err2 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err2)
|
|
}
|
|
|
|
if len(set1) == 0 {
|
|
return reflect.ValueOf(set2), nil
|
|
}
|
|
if len(set2) == 0 {
|
|
return reflect.ValueOf(set1), nil
|
|
}
|
|
|
|
m := reflect.MapOf(reflect.TypeOf(set1[0]), reflect.TypeOf(true))
|
|
m1 := reflect.MakeMapWithSize(m, 0)
|
|
for i := 0; i < len(set1); i++ {
|
|
m1.SetMapIndex(reflect.ValueOf(set1[i]), reflect.ValueOf(true))
|
|
rv := reflect.ValueOf(set1[i])
|
|
set = reflect.Append(set, rv)
|
|
}
|
|
|
|
for i := 0; i < len(set2); i++ {
|
|
x := m1.MapIndex(reflect.ValueOf(set2[i]))
|
|
if x.IsValid() {
|
|
if found := x; !found.Bool() {
|
|
rv := reflect.ValueOf(set2[i])
|
|
set = reflect.Append(set, rv)
|
|
}
|
|
}
|
|
}
|
|
|
|
return set, nil
|
|
|
|
}
|
|
|
|
// GenericNot returns new set with elements which of a which are not in
|
|
// set b.
|
|
func GenericNot(a, b interface{}) (reflect.Value, error) {
|
|
set := reflect.MakeSlice(reflect.TypeOf(a), 0, 0)
|
|
set1, err1 := interfaceToSlice(a)
|
|
set2, err2 := interfaceToSlice(b)
|
|
|
|
if err1 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err1)
|
|
}
|
|
|
|
if err2 != nil {
|
|
return set, fmt.Errorf("slice type is invalid %v", err2)
|
|
}
|
|
|
|
if len(set1) == 0 {
|
|
return reflect.ValueOf(set2), nil
|
|
}
|
|
if len(set2) == 0 {
|
|
return reflect.ValueOf(set1), nil
|
|
}
|
|
|
|
m := reflect.MapOf(reflect.TypeOf(set1[0]), reflect.TypeOf(true))
|
|
m1 := reflect.MakeMapWithSize(m, 0)
|
|
for i := 0; i < len(set1); i++ {
|
|
m1.SetMapIndex(reflect.ValueOf(set1[i]), reflect.ValueOf(true))
|
|
|
|
}
|
|
|
|
for i := 0; i < len(set2); i++ {
|
|
x := m1.MapIndex(reflect.ValueOf(set2[i]))
|
|
if x.IsValid() {
|
|
if found := x; !found.Bool() {
|
|
rv := reflect.ValueOf(set2[i])
|
|
set = reflect.Append(set, rv)
|
|
}
|
|
}
|
|
}
|
|
|
|
return set, nil
|
|
|
|
}
|
|
|
|
// GenericIsIn returns true if a is in b and False otherwise.
|
|
func GenericIsIn(a, b interface{}) bool {
|
|
set1, err := interfaceToSlice(b)
|
|
if err == nil {
|
|
for _, v := range set1 {
|
|
if a == v {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|