Skip to content

Caching

provide.foundation.utils.caching

Caching utilities for Foundation.

Provides efficient caching mechanisms for frequently accessed data with configurable size limits and optional TTL support.

Classes

LRUCache

LRUCache(maxsize: int = 128)

Thread-safe LRU cache with configurable size.

This is a simple LRU cache that maintains insertion order and evicts least recently used items when the cache is full.

Initialize LRU cache.

Parameters:

Name Type Description Default
maxsize int

Maximum number of items to cache

128
Source code in provide/foundation/utils/caching.py
def __init__(self, maxsize: int = 128) -> None:
    """Initialize LRU cache.

    Args:
        maxsize: Maximum number of items to cache
    """
    self.maxsize = maxsize
    self._cache: OrderedDict[Any, Any] = OrderedDict()
    self._lock = threading.RLock()
    self._hits = 0
    self._misses = 0
Functions
clear
clear() -> None

Clear all cached items.

Source code in provide/foundation/utils/caching.py
def clear(self) -> None:
    """Clear all cached items."""
    with self._lock:
        self._cache.clear()
        self._hits = 0
        self._misses = 0
get
get(key: Any, default: Any = None) -> Any

Get value from cache.

Parameters:

Name Type Description Default
key Any

Cache key

required
default Any

Default value if key not found

None

Returns:

Type Description
Any

Cached value or default

Source code in provide/foundation/utils/caching.py
def get(self, key: Any, default: Any = None) -> Any:
    """Get value from cache.

    Args:
        key: Cache key
        default: Default value if key not found

    Returns:
        Cached value or default
    """
    with self._lock:
        if key in self._cache:
            # Move to end (most recently used)
            self._cache.move_to_end(key)
            self._hits += 1
            return self._cache[key]
        self._misses += 1
        return default
set
set(key: Any, value: Any) -> None

Set value in cache.

Parameters:

Name Type Description Default
key Any

Cache key

required
value Any

Value to cache

required
Source code in provide/foundation/utils/caching.py
def set(self, key: Any, value: Any) -> None:
    """Set value in cache.

    Args:
        key: Cache key
        value: Value to cache
    """
    with self._lock:
        if key in self._cache:
            # Update existing and move to end
            self._cache.move_to_end(key)
        self._cache[key] = value

        # Evict oldest if over limit
        if len(self._cache) > self.maxsize:
            self._cache.popitem(last=False)
stats
stats() -> dict[str, int | float]

Get cache statistics.

Returns:

Type Description
dict[str, int | float]

Dictionary with hits, misses, size, maxsize, and hit_rate

Source code in provide/foundation/utils/caching.py
def stats(self) -> dict[str, int | float]:
    """Get cache statistics.

    Returns:
        Dictionary with hits, misses, size, maxsize, and hit_rate
    """
    with self._lock:
        total = self._hits + self._misses
        hit_rate = (self._hits / total * 100) if total > 0 else 0.0
        return {
            "hits": self._hits,
            "misses": self._misses,
            "size": len(self._cache),
            "maxsize": self.maxsize,
            "hit_rate": hit_rate,
        }

Functions

cached

cached(
    maxsize: int = 128, enabled: bool | None = None
) -> Callable

Decorator to cache function results with LRU eviction.

Parameters:

Name Type Description Default
maxsize int

Maximum number of cached results

128
enabled bool | None

Whether caching is enabled (defaults to FOUNDATION_CACHE_ENABLED)

None

Returns:

Type Description
Callable

Decorated function with caching

Example

@cached(maxsize=100) ... def expensive_operation(x: int) -> int: ... return x * x

Source code in provide/foundation/utils/caching.py
def cached(maxsize: int = 128, enabled: bool | None = None) -> Callable:
    """Decorator to cache function results with LRU eviction.

    Args:
        maxsize: Maximum number of cached results
        enabled: Whether caching is enabled (defaults to FOUNDATION_CACHE_ENABLED)

    Returns:
        Decorated function with caching

    Example:
        >>> @cached(maxsize=100)
        ... def expensive_operation(x: int) -> int:
        ...     return x * x
    """
    cache_enabled = enabled if enabled is not None else _CACHE_ENABLED

    def decorator(func: Callable[..., T]) -> Callable[..., T]:
        if not cache_enabled:
            # Return original function if caching disabled
            return func

        cache = LRUCache(maxsize=maxsize)

        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> T:
            # Create cache key from args and kwargs
            key = (args, tuple(sorted(kwargs.items())))

            result = cache.get(key)
            if result is None:
                result = func(*args, **kwargs)
                cache.set(key, result)

            return cast(T, result)

        # Attach cache object for testing/inspection
        wrapper.cache = cache  # type: ignore[attr-defined]
        wrapper.cache_clear = cache.clear  # type: ignore[attr-defined]
        wrapper.cache_stats = cache.stats  # type: ignore[attr-defined]

        return wrapper

    return decorator

clear_all_caches

clear_all_caches() -> None

Clear all registered caches.

Useful for testing and cache invalidation.

Source code in provide/foundation/utils/caching.py
def clear_all_caches() -> None:
    """Clear all registered caches.

    Useful for testing and cache invalidation.
    """
    with _registry_lock:
        for cache in _cache_registry.values():
            cache.clear()

get_cache

get_cache(name: str) -> LRUCache | None

Get a registered cache by name.

Parameters:

Name Type Description Default
name str

Cache identifier

required

Returns:

Type Description
LRUCache | None

Cache instance or None if not found

Source code in provide/foundation/utils/caching.py
def get_cache(name: str) -> LRUCache | None:
    """Get a registered cache by name.

    Args:
        name: Cache identifier

    Returns:
        Cache instance or None if not found
    """
    with _registry_lock:
        return _cache_registry.get(name)

get_cache_stats

get_cache_stats() -> dict[str, dict[str, int | float]]

Get statistics for all registered caches.

Returns:

Type Description
dict[str, dict[str, int | float]]

Dictionary mapping cache names to their statistics

Source code in provide/foundation/utils/caching.py
def get_cache_stats() -> dict[str, dict[str, int | float]]:
    """Get statistics for all registered caches.

    Returns:
        Dictionary mapping cache names to their statistics
    """
    with _registry_lock:
        return {name: cache.stats() for name, cache in _cache_registry.items()}

register_cache

register_cache(name: str, cache: LRUCache) -> None

Register a named cache for global management.

Parameters:

Name Type Description Default
name str

Cache identifier

required
cache LRUCache

Cache instance to register

required
Source code in provide/foundation/utils/caching.py
def register_cache(name: str, cache: LRUCache) -> None:
    """Register a named cache for global management.

    Args:
        name: Cache identifier
        cache: Cache instance to register
    """
    with _registry_lock:
        _cache_registry[name] = cache