Vectrum
Sign In
82 lines · 1.5 KB · Shell
#!/usr/bin/env bash
set -euo pipefail
mkdir -p internal/cache cmd/serve
cat > go.mod <<'EOF'
module svc

go 1.22
EOF
cat > internal/cache/cache.go <<'EOF'
package cache

import "time"

// Cache is a tiny expiring key-value store.
type Cache struct {
	ttl     time.Duration
	maxSize int
	entries map[string]entry
}

type entry struct {
	value   string
	expires time.Time
}

// New builds a Cache. The maxSize parameter was added when eviction landed.
func New(ttl time.Duration, maxSize int) *Cache {
	return &Cache{ttl: ttl, maxSize: maxSize, entries: map[string]entry{}}
}

func (c *Cache) Set(k, v string) {
	if len(c.entries) >= c.maxSize {
		for key := range c.entries {
			delete(c.entries, key)
			break
		}
	}
	c.entries[k] = entry{value: v, expires: time.Now().Add(c.ttl)}
}

func (c *Cache) Get(k string) (string, bool) {
	e, ok := c.entries[k]
	if !ok || time.Now().After(e.expires) {
		return "", false
	}
	return e.value, true
}
EOF
cat > cmd/serve/main.go <<'EOF'
package main

import (
	"fmt"
	"time"

	"svc/internal/cache"
)

func main() {
	c := cache.New(5 * time.Minute)
	c.Set("greeting", "hello")
	v, ok := c.Get("greeting")
	fmt.Println(v, ok)
}
EOF
cat > internal/cache/cache_test.go <<'EOF'
package cache

import (
	"testing"
	"time"
)

func TestSetGet(t *testing.T) {
	c := New(time.Minute, 10)
	c.Set("k", "v")
	if got, ok := c.Get("k"); !ok || got != "v" {
		t.Errorf("Get() = %q, %v", got, ok)
	}
}
EOF
git init -q . && git add -A && git -c user.email=e@x -c user.name=n commit -qm base