cache

package
v0.0.0-...-83ad1ac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package cache provides caching mechanisms for rendered sprites and images.

The cache package implements an LRU (Least Recently Used) cache for Ebiten images, specifically designed for caching procedurally generated sprites, animation frames, and composite images. This reduces redundant generation and improves performance.

Phase 44 enhancements:

  • Support for 64x64 sprites (16KB each)
  • MemoryMonitor for automatic cleanup (<300MB limit)
  • PreGenerator for batch sprite pre-generation
  • Enhanced statistics and monitoring

Key features:

  • LRU eviction policy to manage memory usage
  • Size-based limits (configurable max cache size in bytes)
  • Thread-safe operations with fine-grained locking
  • Cache hit/miss statistics for monitoring
  • Memory monitoring with soft/hard limits
  • Batch pre-generation for cache warming

Basic Usage:

cache := cache.NewSpriteCache(300 * 1024 * 1024) // 300MB limit
key := cache.GenerateKey(seed, "idle", 0)

// Try to get from cache
if img, ok := cache.Get(key); ok {
    return img // Cache hit
}

// Generate and store in cache
img := generateSprite(seed, "idle", 0)
cache.Put(key, img)

// Check statistics
stats := cache.Stats()
logrus.WithField("hit_rate", stats.HitRate()*100).Info("cache statistics")

Memory Monitoring (Phase 44):

monitor := cache.NewMemoryMonitor(cache)
monitor.SetLimits(250*1024*1024, 300*1024*1024) // 250MB soft, 300MB hard
monitor.Start()
defer monitor.Stop()

// Check health
if monitor.IsHealthy() {
    logrus.WithField("usage_percent", monitor.UsagePercentage()).Info("cache health status")
}

Pre-Generation (Phase 44):

pregen := cache.NewPreGenerator(cache)

// Queue sprites for pre-generation
for i := 0; i < 100; i++ {
    key := cache.GenerateKey(int64(i), "idle", 0)
    pregen.Queue(key, func() (*ebiten.Image, error) {
        return generateSprite(i), nil
    })
}

// Generate in batch
count := pregen.Generate()
logrus.WithField("sprite_count", count).Info("pre-generated sprites")

Package cache provides sprite caching with predictive warming. This file implements predictive cache warming based on access pattern analysis.

Index

Constants

View Source
const (
	// BytesPerPixel is the number of bytes per RGBA pixel.
	BytesPerPixel = 4

	// Sprite32MemorySize is the memory size of a 32×32 RGBA sprite in bytes.
	Sprite32MemorySize = 32 * 32 * BytesPerPixel // 4KB

	// Sprite64MemorySize is the memory size of a 64×64 RGBA sprite in bytes.
	// This is the default size for Phase 45 sprites and tiles.
	Sprite64MemorySize = 64 * 64 * BytesPerPixel // 16KB

	// Sprite128MemorySize is the memory size of a 128×128 RGBA sprite in bytes.
	Sprite128MemorySize = 128 * 128 * BytesPerPixel // 64KB

	// Deprecated: use Sprite32MemorySize instead.
	SpriteSize32 = Sprite32MemorySize

	// Deprecated: use Sprite64MemorySize instead.
	SpriteSize64 = Sprite64MemorySize

	// Deprecated: use Sprite128MemorySize instead.
	SpriteSize128 = Sprite128MemorySize

	// DefaultCacheSize is the recommended cache size for typical gameplay.
	// Allows ~1024 64×64 sprites (16MB / 16KB = 1024 sprites).
	DefaultCacheSize = 16 * 1024 * 1024 // 16MB

	// MaxCacheSize is the maximum recommended cache size to stay under 300MB.
	// Allows ~18,750 64×64 sprites (300MB / 16KB = 18,750 sprites).
	MaxCacheSize = 300 * 1024 * 1024 // 300MB
)

Sprite size constants for cache capacity calculations. Phase 45: Default sprite/tile size is now 64×64 (previously 32×32).

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessPattern

type AccessPattern struct {
	Key         CacheKey
	AccessCount int
	LastAccess  int64
	NextKeys    []CacheKey // Keys typically accessed after this one
}

AccessPattern tracks access statistics for a single sprite.

type AccessRecord

type AccessRecord struct {
	Key       CacheKey
	Hit       bool
	Timestamp int64 // Game tick or frame number
}

AccessRecord tracks a single cache access.

type CacheKey

type CacheKey string

CacheKey represents a unique identifier for a cached sprite.

func GenerateCompositeKey

func GenerateCompositeKey(seed int64, layers []string) CacheKey

GenerateCompositeKey creates a cache key for composite sprites. Optimized to use strconv instead of fmt.Fprintf to reduce allocations.

func GenerateKey

func GenerateKey(seed int64, state string, frame int) CacheKey

GenerateKey creates a cache key from seed, state, and frame information. Optimized to use strconv instead of fmt.Sprintf to reduce allocations.

type GeneratorFunc

type GeneratorFunc func() (*ebiten.Image, error)

GeneratorFunc represents a function that generates a sprite image.

type MemoryMonitor

type MemoryMonitor struct {
	// contains filtered or unexported fields
}

MemoryMonitor tracks cache memory usage and triggers cleanup when needed. Phase 44: Monitors sprite cache to ensure <300MB limit for 64x64 sprites.

func NewMemoryMonitor

func NewMemoryMonitor(cache *SpriteCache) *MemoryMonitor

NewMemoryMonitor creates memory monitor with default limits. Default: 250MB soft limit, 300MB hard limit (Phase 44 target).

func (*MemoryMonitor) EstimatedSpriteCapacity

func (m *MemoryMonitor) EstimatedSpriteCapacity() int

EstimatedSpriteCapacity estimates max 64x64 sprites at current usage. 64x64 RGBA = 16KB per sprite.

func (*MemoryMonitor) IsHealthy

func (m *MemoryMonitor) IsHealthy() bool

IsHealthy returns true if cache is within limits.

func (*MemoryMonitor) SetInterval

func (m *MemoryMonitor) SetInterval(interval time.Duration)

SetInterval configures monitoring interval.

func (*MemoryMonitor) SetLimits

func (m *MemoryMonitor) SetLimits(softLimit, hardLimit int64)

SetLimits configures memory limits in bytes. If softLimit > hardLimit, softLimit is clamped to hardLimit.

func (*MemoryMonitor) Start

func (m *MemoryMonitor) Start()

Start begins background monitoring.

func (*MemoryMonitor) Stats

func (m *MemoryMonitor) Stats() MemoryStats

Stats returns current monitoring statistics.

func (*MemoryMonitor) Stop

func (m *MemoryMonitor) Stop()

Stop terminates background monitoring. Safe to call multiple times.

func (*MemoryMonitor) UsagePercentage

func (m *MemoryMonitor) UsagePercentage() float64

UsagePercentage returns cache usage as percentage of hard limit.

type MemoryStats

type MemoryStats struct {
	CurrentUsage   int64
	PeakUsage      int64
	CleanupCount   uint64
	EvictionCount  uint64
	LastCleanupAt  time.Time
	SystemMemoryMB uint64
}

MemoryStats tracks memory monitoring metrics.

type PreGenRequest

type PreGenRequest struct {
	Key       CacheKey
	Generator GeneratorFunc
}

PreGenRequest represents a sprite pre-generation request.

type PreGenStats

type PreGenStats struct {
	RequestsQueued   int
	RequestsComplete int
	RequestsFailed   int
	CacheHits        int // Requests that were already cached
}

PreGenStats tracks pre-generation metrics.

type PreGenerator

type PreGenerator struct {
	// contains filtered or unexported fields
}

PreGenerator handles batch pre-generation of sprites to warm the cache. Phase 44: Pre-generates common sprites to improve cache hit rate.

func NewPreGenerator

func NewPreGenerator(cache *SpriteCache) *PreGenerator

NewPreGenerator creates a new pre-generator.

func (*PreGenerator) Clear

func (p *PreGenerator) Clear()

Clear removes all queued requests.

func (*PreGenerator) Generate

func (p *PreGenerator) Generate() int

Generate processes all queued requests. Returns number of sprites generated.

func (*PreGenerator) GenerateAsync

func (p *PreGenerator) GenerateAsync(doneCh chan<- int)

GenerateAsync processes queued requests in background. Returns immediately, generation happens in goroutine.

func (*PreGenerator) HitRate

func (p *PreGenerator) HitRate() float64

HitRate returns cache hit rate for pre-generation requests.

func (*PreGenerator) Queue

func (p *PreGenerator) Queue(key CacheKey, generator GeneratorFunc)

Queue adds a sprite generation request to the queue.

func (*PreGenerator) QueueBatch

func (p *PreGenerator) QueueBatch(requests []PreGenRequest)

QueueBatch adds multiple generation requests.

func (*PreGenerator) QueueSize

func (p *PreGenerator) QueueSize() int

QueueSize returns number of pending requests.

func (*PreGenerator) Stats

func (p *PreGenerator) Stats() PreGenStats

Stats returns pre-generation statistics.

func (*PreGenerator) SuccessRate

func (p *PreGenerator) SuccessRate() float64

SuccessRate returns successful generation rate.

type PredictiveCacheWarmer

type PredictiveCacheWarmer struct {
	// contains filtered or unexported fields
}

PredictiveCacheWarmer tracks sprite access patterns and predicts which sprites will be needed soon, enabling proactive cache warming for higher hit rates.

The warmer uses a sliding window of recent accesses to identify: - Frequently accessed sprites (hot sprites) - Sequential access patterns (animation frames) - Nearby entity sprites (spatial locality)

Target: >98% cache hit rate by preloading predicted sprites.

func NewPredictiveCacheWarmer

func NewPredictiveCacheWarmer(cache *SpriteCache, pregen *PreGenerator, config PredictiveWarmerConfig) *PredictiveCacheWarmer

NewPredictiveCacheWarmer creates a predictive cache warmer.

func (*PredictiveCacheWarmer) AnalyzeAnimationSequence

func (w *PredictiveCacheWarmer) AnalyzeAnimationSequence(frameKeys []CacheKey)

AnalyzeAnimationSequence analyzes a sequence of animation frame keys and registers them as a sequential access pattern. This enables preloading entire animation sequences when the first frame is accessed.

func (*PredictiveCacheWarmer) GetHotSprites

func (w *PredictiveCacheWarmer) GetHotSprites() []CacheKey

GetHotSprites returns the most frequently accessed sprites in the window.

func (*PredictiveCacheWarmer) PredictAnimationFrames

func (w *PredictiveCacheWarmer) PredictAnimationFrames(startKey CacheKey) []CacheKey

PredictAnimationFrames returns all predicted frames for a given sprite. Useful for preloading entire animation sequences.

func (*PredictiveCacheWarmer) PredictNext

func (w *PredictiveCacheWarmer) PredictNext() []CacheKey

PredictNext returns sprites likely to be accessed soon based on patterns. Analyzes the most recent access and returns sprites that typically follow it.

func (*PredictiveCacheWarmer) QueuePredictedSprites

func (w *PredictiveCacheWarmer) QueuePredictedSprites(generator func(key CacheKey) GeneratorFunc) int

QueuePredictedSprites queues predicted sprites for pre-generation. Call this periodically (e.g., every 60 frames) to maintain high hit rates. The generator function is used to create sprites for predicted keys.

func (*PredictiveCacheWarmer) RecordAccess

func (w *PredictiveCacheWarmer) RecordAccess(key CacheKey, hit bool, tick int64)

RecordAccess logs a cache access for pattern analysis. Call this after every cache Get() operation.

func (*PredictiveCacheWarmer) Reset

func (w *PredictiveCacheWarmer) Reset()

Reset clears all access history and patterns.

func (*PredictiveCacheWarmer) Stats

Stats returns current warmer statistics.

type PredictiveWarmerConfig

type PredictiveWarmerConfig struct {
	WindowSize     int // Access history size (default: 1000)
	HotThreshold   int // Accesses to be "hot" (default: 5)
	MaxPredictions int // Max predictions per cycle (default: 50)
}

PredictiveWarmerConfig configures the predictive warmer.

func DefaultWarmerConfig

func DefaultWarmerConfig() PredictiveWarmerConfig

DefaultWarmerConfig returns sensible defaults for predictive warming.

type SpriteCache

type SpriteCache struct {
	// contains filtered or unexported fields
}

SpriteCache implements an LRU cache for Ebiten images.

func NewSpriteCache

func NewSpriteCache(maxSize int64) *SpriteCache

NewSpriteCache creates a new sprite cache with the specified maximum size in bytes.

Recommended sizes (Phase 45: 64×64 default sprites):

  • DefaultCacheSize (16MB): ~1000 64×64 sprites, good for typical gameplay
  • MaxCacheSize (300MB): ~18,000 64×64 sprites, maximum for memory targets

Example usage:

cache := NewSpriteCache(cache.DefaultCacheSize)

func (*SpriteCache) Clear

func (c *SpriteCache) Clear()

Clear removes all entries from the cache.

func (*SpriteCache) Contains

func (c *SpriteCache) Contains(key CacheKey) bool

Contains checks if a key exists in the cache without affecting LRU order.

func (*SpriteCache) Count

func (c *SpriteCache) Count() int

Count returns the number of entries in the cache.

func (*SpriteCache) Get

func (c *SpriteCache) Get(key CacheKey) (*ebiten.Image, bool)

Get retrieves a sprite from the cache. Returns (image, true) if found, (nil, false) if not found.

func (*SpriteCache) MaxSize

func (c *SpriteCache) MaxSize() int64

MaxSize returns the maximum cache size in bytes.

func (*SpriteCache) Put

func (c *SpriteCache) Put(key CacheKey, img *ebiten.Image)

Put adds a sprite to the cache. If the cache is full, it evicts the least recently used entries.

func (*SpriteCache) Remove

func (c *SpriteCache) Remove(key CacheKey) bool

Remove removes a specific entry from the cache.

func (*SpriteCache) SetMaxSize

func (c *SpriteCache) SetMaxSize(maxSize int64)

SetMaxSize updates the maximum cache size and evicts entries if necessary.

func (*SpriteCache) Size

func (c *SpriteCache) Size() int64

Size returns the current cache size in bytes.

func (*SpriteCache) Stats

func (c *SpriteCache) Stats() Statistics

Stats returns a copy of the current cache statistics.

type Statistics

type Statistics struct {
	Hits       uint64
	Misses     uint64
	Evictions  uint64
	TotalSize  int64
	EntryCount int
}

Statistics holds cache performance metrics.

func (*Statistics) HitRate

func (s *Statistics) HitRate() float64

HitRate returns the cache hit rate as a value between 0.0 and 1.0.

type WarmerStats

type WarmerStats struct {
	AccessLogSize   int
	PatternCount    int
	HotSpriteCount  int
	PredictionCount int
	WindowHitRate   float64 // Hit rate within sliding window
	WindowMissRate  float64 // Miss rate within sliding window
}

WarmerStats contains predictive warmer statistics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL