Skip to content

Instantly share code, notes, and snippets.

@Mattie112
Last active April 19, 2022 14:08
Show Gist options
  • Save Mattie112/3118743a33086f3329121f9b2721e66a to your computer and use it in GitHub Desktop.
Save Mattie112/3118743a33086f3329121f9b2721e66a to your computer and use it in GitHub Desktop.
Munisense Golang Workshop
package main
import (
"fmt"
"math/rand"
"time"
)
const n = 20
func main() {
startTime := time.Now().UnixMilli()
fmt.Print("Filling input channel.... ")
inputCh := make(chan InputItem, n)
generateInput(n, inputCh)
close(inputCh)
fmt.Println("DONE!")
outputCh := make(chan OutputItem, 1000)
dataMap := map[time.Time][]uint64{}
// First we group the inputs per day in a map
for input := range inputCh {
// Calculate the start of day
startOfDayTimestamp := startOfDay(input.Timestamp)
// Make sure the dataMap has an entry for each startOfDay
if _, exists := dataMap[startOfDayTimestamp]; !exists {
dataMap[startOfDayTimestamp] = make([]uint64, 0)
}
dataMap[startOfDayTimestamp] = append(dataMap[startOfDayTimestamp], input.Value)
}
for day, elems := range dataMap {
min, max, avg := calculate(elems)
outputCh <- OutputItem{
Timestamp: day,
DayMax: max,
DayMin: min,
DayAvg: avg,
}
}
close(outputCh)
// Listens on the output channel and prints the results
for item := range outputCh {
fmt.Printf("Day: %s, Avg: %0.2f, Min: %d, Max: %d\n", item.Timestamp, item.DayAvg, item.DayMin, item.DayMax)
}
fmt.Printf("Done in %d milliseconds!", time.Now().UnixMilli()-startTime)
}
type InputItem struct {
Timestamp time.Time
Value uint64
}
type OutputItem struct {
Timestamp time.Time
DayMax uint64
DayMin uint64
DayAvg float32
}
func calculate(elems []uint64) (min, max uint64, avg float32) {
// Fake expensive operation like connecting to a database
time.Sleep(100 * time.Millisecond)
total := uint64(0)
min = 18446744073709551615
max = 0
for _, elem := range elems {
total += elem
if elem < min {
min = elem
}
if elem > max {
max = elem
}
}
avg = float32(total) / float32(len(elems))
return
}
func generateInput(n int, inputCh chan<- InputItem) {
for i := 0; i < n; i++ {
rand.Seed(int64(i))
minTimestamp := int64(1640991600)
maxTimestamp := int64(1648764000)
unix := time.Unix(rand.Int63n(maxTimestamp-minTimestamp+1)+minTimestamp, 0)
inputCh <- InputItem{
Timestamp: unix,
Value: uint64(rand.Intn(1000)),
}
}
}
func startOfDay(input time.Time) time.Time {
return input.Truncate(time.Hour * 24)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment