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()
fmt.Printf("Hit rate: %.2f%%\n", stats.HitRate()*100)
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() {
fmt.Printf("Cache usage: %.1f%%\n", monitor.UsagePercentage())
}
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()
fmt.Printf("Pre-generated %d sprites\n", count)
Index ¶
- Constants
- 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 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
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 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.
func (*MemoryMonitor) Stats ¶
func (m *MemoryMonitor) Stats() MemoryStats
Stats returns current monitoring statistics.
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 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.