diff options
| author | Will Hawkins <[email protected]> | 2022-07-16 04:08:42 -0400 |
|---|---|---|
| committer | Will Hawkins <[email protected]> | 2022-07-16 04:08:42 -0400 |
| commit | 23d16686f2320f9a5fe35aebbaa2e036b27421ca (patch) | |
| tree | c5e5d097f68fb9e7cfe2e3c794cfad4bc3266adb /utilities/utilities.go | |
| parent | f0a9f4a3a50b63127a5e3d4ab2bdda3bbe4d8d0d (diff) | |
[Feature] Support spec v2 (4/4); Add data logging
Besides work to complete the support for v2 of the RFC, this patch adds
support for logging each of the probe results to a CSV file
(--logger-filename).
Diffstat (limited to 'utilities/utilities.go')
| -rw-r--r-- | utilities/utilities.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/utilities/utilities.go b/utilities/utilities.go index 7b96bef..d4303ec 100644 --- a/utilities/utilities.go +++ b/utilities/utilities.go @@ -20,6 +20,8 @@ import ( "math/rand" "os" "reflect" + "sort" + "strings" "sync/atomic" "time" ) @@ -129,3 +131,56 @@ func Max(x, y uint64) uint64 { } return y } + +func ChannelToSlice[S any](channel <-chan S) (slice []S) { + slice = make([]S, 0) + for element := range channel { + slice = append(slice, element) + } + return +} + +func Fmap[S any, F any](elements []S, mapper func(S) F) []F { + result := make([]F, 0) + for _, s := range elements { + result = append(result, mapper(s)) + } + return result +} + +func CalculatePercentile[S float32 | int32 | float64 | int64](elements []S, percentile int) S { + sort.Slice(elements, func(a, b int) bool { return elements[a] < elements[b] }) + elementsCount := len(elements) + percentileIdx := elementsCount * (percentile / 100) + return elements[percentileIdx] +} + +func OrTimeout(f func(), timeout time.Duration) { + completeChannel := func() chan interface{} { + completed := make(chan interface{}) + go func() { + // This idea taken from https://stackoverflow.com/a/32843750. + // Closing the channel will let the read of it proceed immediately. + // Making that operation a defer ensures that it will happen even if + // the function f panics during its execution. + defer close(completed) + f() + }() + return completed + }() + select { + case _ = <-completeChannel: + break + case _ = <-time.After(timeout): + break + } +} + +func FilenameAppend(filename, appendage string) string { + pieces := strings.SplitN(filename, ".", 2) + result := pieces[0] + appendage + if len(pieces) > 1 { + result = result + "." + strings.Join(pieces[1:], ".") + } + return result +} |
