// MIT License - Copyright (c) 2026 wallstop
// Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE
namespace WallstopStudios.UnityHelpers.Core.DataStructure
{
using System;
using UnityEngine;
///
/// Configuration options for constructing a .
/// This is a value type to avoid allocations. Reference-type properties (delegates)
/// are stored as references within the struct.
/// Use for a fluent API.
///
/// The type of keys in the cache.
/// The type of values in the cache.
public struct CacheOptions
{
///
/// Default maximum number of entries in a cache.
///
public const int DefaultMaximumSize = 1000;
///
/// Default value indicating no time-based expiration.
///
public const float DefaultExpireAfterWriteSeconds = 0f;
///
/// Default value indicating no sliding expiration.
///
public const float DefaultExpireAfterAccessSeconds = 0f;
///
/// Default eviction policy.
///
public const EvictionPolicy DefaultEvictionPolicy = EvictionPolicy.Lru;
///
/// Default ratio of protected segment for SLRU (80%).
///
public const float DefaultProtectedRatio = 0.8f;
///
/// Default growth factor when dynamic sizing is enabled.
///
public const float DefaultGrowthFactor = 1.5f;
///
/// Default evictions per second threshold for thrash detection.
///
public const float DefaultThrashThreshold = 100f;
///
/// Default initial capacity used as a fallback when an invalid value (zero or negative)
/// is explicitly passed to .
/// Note: When is not specified,
/// defaults to using as the initial capacity.
///
public const int DefaultInitialCapacity = 16;
///
/// Maximum allowed initial capacity to prevent accidental large allocations.
///
internal const int MaxReasonableInitialCapacity = 65536;
///
/// The maximum number of entries the cache can hold before eviction occurs.
/// If zero, is used.
///
public int MaximumSize;
///
/// The initial capacity of the cache's internal data structures.
/// If zero or negative, defaults to using .
/// The cache grows dynamically as needed up to .
/// This can be set smaller than to reduce upfront allocations
/// when the cache is expected to start with fewer entries.
/// Values larger than are clamped to prevent
/// accidental memory issues.
///
public int InitialCapacity;
///
/// The maximum total weight of all cache entries.
/// Only used when is specified.
///
public long MaximumWeight;
///
/// Function to compute the weight of a cache entry.
/// When specified, is used instead of .
///
public Func Weigher;
///
/// Time in seconds after which an entry expires following its creation or last update.
/// A value of 0 or less disables write-based expiration.
///
public float ExpireAfterWriteSeconds;
///
/// Time in seconds after which an entry expires following its last access (sliding window).
/// A value of 0 or less disables access-based expiration.
///
public float ExpireAfterAccessSeconds;
///
/// Function to compute a custom expiration time (in seconds) for each entry.
/// Takes precedence over when specified.
///
public Func ExpireAfter;
///
/// When true, adds a random jitter to expiration times to prevent thundering herd.
///
public bool UseJitter;
///
/// Maximum jitter in seconds to add to expiration times.
/// If zero, defaults to 10% of the TTL.
///
public float JitterMaxSeconds;
///
/// The eviction algorithm to use when the cache reaches capacity.
///
public EvictionPolicy Policy;
///
/// For , the ratio of the cache dedicated to the protected segment.
/// Value should be between 0 and 1. Default is 0.8 (80% protected, 20% probation).
///
public float ProtectedRatio;
///
/// When true, allows the cache to grow beyond when thrashing is detected.
///
public bool AllowGrowth;
///
/// The factor by which to grow the cache when thrashing is detected.
///
public float GrowthFactor;
///
/// The maximum size the cache can grow to when dynamic sizing is enabled.
/// If zero, growth is unbounded.
///
public int MaxGrowthSize;
///
/// The evictions per second threshold above which the cache is considered thrashing.
///
public float ThrashThresholdEvictionsPerSecond;
///
/// Callback invoked when an entry is evicted from the cache.
///
public Action OnEviction;
///
/// Callback invoked when an entry is retrieved from the cache (hit).
///
public Action OnGet;
///
/// Callback invoked when an entry is added or updated in the cache.
///
public Action OnSet;
///
/// When true, the cache records statistics accessible via .
///
public bool RecordStatistics;
///
/// Function that returns the current time in seconds.
/// Defaults to a Stopwatch-based provider when null (safe during static initialization).
///
public Func TimeProvider;
///
/// Factory function used to load values when they are not present in the cache.
/// When specified,
/// uses this loader if no explicit factory is provided.
///
public Func Loader;
///
/// Creates a new options instance with default values.
///
/// A new with defaults.
public static CacheOptions Default()
{
return new CacheOptions
{
MaximumSize = DefaultMaximumSize,
ExpireAfterWriteSeconds = DefaultExpireAfterWriteSeconds,
ExpireAfterAccessSeconds = DefaultExpireAfterAccessSeconds,
Policy = DefaultEvictionPolicy,
ProtectedRatio = DefaultProtectedRatio,
GrowthFactor = DefaultGrowthFactor,
ThrashThresholdEvictionsPerSecond = DefaultThrashThreshold,
};
}
}
}