// Exercise 04 — Log Crunching: Top-N Endpoints // // ASSIGNMENT // ---------- // Log lines look like: // // 2026-08-28T10:00:01Z GET /api/users 200 123ms // // Implement TopN(r, n) so that it: // // 1. Streams the input (must handle logs far larger than memory — no // io.ReadAll). // 2. Counts requests per endpoint (3rd whitespace-separated field). // 3. Skips malformed lines (fewer than 3 fields) without failing. // 4. Handles lines longer than 64KB (hint: bufio.Scanner's default limit). // 5. Returns the n most frequent endpoints, most frequent first. // Ties: order among equal counts is unspecified. // // Run the tests: go test -race ./04-log-topn/ package main import ( "fmt" "io" "strings" ) type KV struct { Endpoint string Count int } // TopN returns the n most frequent endpoints in the log stream. // TODO: implement me. func TopN(r io.Reader, n int) ([]KV, error) { // TODO: // - bufio.Scanner with an enlarged buffer // - map[string]int for counting // - copy map into []KV and sort by count desc (maps can't be sorted) // - truncate to n return nil, nil } func main() { logs := `2026-08-28T10:00:01Z GET /api/users 200 12ms 2026-08-28T10:00:02Z GET /api/orders 200 40ms 2026-08-28T10:00:03Z GET /api/users 500 3ms garbage line 2026-08-28T10:00:04Z POST /api/users 201 88ms` top, err := TopN(strings.NewReader(logs), 2) fmt.Println(top, err) }