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
- type AccessPattern
- type AccessRecord
- type CacheKey
- type GeneratorFunc
- type MemoryMonitor
- func (m *MemoryMonitor) EstimatedSpriteCapacity() int
- func (m *MemoryMonitor) IsHealthy() bool
- func (m *MemoryMonitor) SetInterval(interval time.Duration)
- func (m *MemoryMonitor) SetLimits(softLimit, hardLimit int64)
- func (m *MemoryMonitor) Start()
- func (m *MemoryMonitor) Stats() MemoryStats
- func (m *MemoryMonitor) Stop()
- func (m *MemoryMonitor) UsagePercentage() float64
- type MemoryStats
- type PreGenRequest
- type PreGenStats
- type PreGenerator
- func (p *PreGenerator) Clear()
- func (p *PreGenerator) Generate() int
- func (p *PreGenerator) GenerateAsync(doneCh chan<- int)
- func (p *PreGenerator) HitRate() float64
- func (p *PreGenerator) Queue(key CacheKey, generator GeneratorFunc)
- func (p *PreGenerator) QueueBatch(requests []PreGenRequest)
- func (p *PreGenerator) QueueSize() int
- func (p *PreGenerator) Stats() PreGenStats
- func (p *PreGenerator) SuccessRate() float64
- type PredictiveCacheWarmer
- func (w *PredictiveCacheWarmer) AnalyzeAnimationSequence(frameKeys []CacheKey)
- func (w *PredictiveCacheWarmer) GetHotSprites() []CacheKey
- func (w *PredictiveCacheWarmer) PredictAnimationFrames(startKey CacheKey) []CacheKey
- func (w *PredictiveCacheWarmer) PredictNext() []CacheKey
- func (w *PredictiveCacheWarmer) QueuePredictedSprites(generator func(key CacheKey) GeneratorFunc) int
- func (w *PredictiveCacheWarmer) RecordAccess(key CacheKey, hit bool, tick int64)
- func (w *PredictiveCacheWarmer) Reset()
- func (w *PredictiveCacheWarmer) Stats() WarmerStats
- type PredictiveWarmerConfig
- type SpriteCache
- func (c *SpriteCache) Clear()
- func (c *SpriteCache) Contains(key CacheKey) bool
- func (c *SpriteCache) Count() int
- func (c *SpriteCache) Get(key CacheKey) (*ebiten.Image, bool)
- func (c *SpriteCache) MaxSize() int64
- func (c *SpriteCache) Put(key CacheKey, img *ebiten.Image)
- func (c *SpriteCache) Remove(key CacheKey) bool
- func (c *SpriteCache) SetMaxSize(maxSize int64)
- func (c *SpriteCache) Size() int64
- func (c *SpriteCache) Stats() Statistics
- type Statistics
- type WarmerStats
Constants ¶
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 ¶
AccessRecord tracks a single cache access.
type CacheKey ¶
type CacheKey string
CacheKey represents a unique identifier for a cached sprite.
func GenerateCompositeKey ¶
GenerateCompositeKey creates a cache key for composite sprites. Optimized to use strconv instead of fmt.Fprintf to reduce allocations.
type GeneratorFunc ¶
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) 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) 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 ¶
func (w *PredictiveCacheWarmer) Stats() WarmerStats
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) 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.