feat: DuckDB quantiles in-process (gcc CGO), not Ladybug. (#34)
OQ3: internal/duckstats + bin/qa/stats.go. Zig stays Ladybug-only. mikefarah/yq for small structured slices. Gitea #30.
This commit is contained in:
Executable
+73
@@ -0,0 +1,73 @@
|
||||
//usr/bin/env go run -tags=qa_stats "$0" "$@"; exit
|
||||
//go:build qa_stats
|
||||
//
|
||||
// bin/qa/stats.go - DuckDB quantiles over a JSON number array or JSONL count.
|
||||
//
|
||||
// ./bin/qa/stats.go <<< '[1,2,3,4,5]'
|
||||
// ./bin/qa/stats.go --jsonl rows.jsonl
|
||||
//
|
||||
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
|
||||
// DuckDB CGO needs gcc/g++ (not Zig). After eval "$(bin/cgo/zig env)":
|
||||
// CC=gcc CXX=g++ CGO_CFLAGS= CGO_LDFLAGS= ./bin/qa/stats.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/eSlider/2dph/internal/duckstats"
|
||||
)
|
||||
|
||||
func main() {
|
||||
os.Exit(run(os.Args[1:]))
|
||||
}
|
||||
|
||||
func run(args []string) int {
|
||||
jsonl := ""
|
||||
for i := 0; i < len(args); i++ {
|
||||
a := args[i]
|
||||
switch {
|
||||
case a == "--jsonl" && i+1 < len(args):
|
||||
i++
|
||||
jsonl = args[i]
|
||||
case strings.HasPrefix(a, "--jsonl="):
|
||||
jsonl = strings.TrimPrefix(a, "--jsonl=")
|
||||
case a == "-h" || a == "--help":
|
||||
fmt.Fprintln(os.Stderr, "bin/qa/stats.go [--jsonl FILE] # stdin = JSON [float,…]")
|
||||
return 0
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "unknown arg:", a)
|
||||
return 2
|
||||
}
|
||||
}
|
||||
if jsonl != "" {
|
||||
n, err := duckstats.CountJSONL(jsonl)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 1
|
||||
}
|
||||
fmt.Printf("n: %d\n", n)
|
||||
return 0
|
||||
}
|
||||
raw, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 1
|
||||
}
|
||||
var samples []float64
|
||||
if err := json.Unmarshal(raw, &samples); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 1
|
||||
}
|
||||
s, err := duckstats.Quantiles(samples)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 1
|
||||
}
|
||||
fmt.Printf("n: %d\nmin: %g\np50: %g\np95: %g\nmax: %g\navg: %g\n",
|
||||
s.N, s.Min, s.P50, s.P95, s.Max, s.Avg)
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user