LRU Cache (Least Recently Used) for Racket
1 Overview
This module provides:
make-lru to construct a cache with a max-count, an optional equality/compare function for items, and optional expiration (seconds).
Mutation operations: lru-add!, lru-clear, set-lru-max-count!, set-lru-expire!.
Query operations: lru-has?, lru-count, lru->list, lru-expires?, lru-expire, lru-max-count, lru?.
The cache stores items (values) and uses a comparison function to decide whether an item is already present. Each item is associated with a last-access timestamp that drives recency; on insert or hit, the item is bubbled to the front.
Thread-safety: The implementation is thread-safe, but not reentrant.
2 Data Types
struct
(struct lru* (cache compare max-count expire-in-seconds))
cache : box? compare : procedure? max-count : (and/c integer? (>/c 0)) expire-in-seconds : (or/c #f (and/c integer? (>/c 0)))
3 Construction
max-count — Maximum number of items kept in the cache. When the limit is exceeded, the least recently used item is evicted.
#:cmp compare — Binary comparison function that returns #t when two items are considered equal (default: equal?).
#:expire expire-in-seconds — If a positive integer: items expire automatically after that many seconds of inactivity. #f disables expiration (default).
Returns A new empty LRU cache with the given parameters.
4 Core Operations
5 Parameters and Configuration
6 Examples
(require racket/base) (require lru-cache) (define L (make-lru 3)) ; max 3 items, no expiration (lru-add! L 'a) (lru-add! L 'b) (lru-add! L 'c) (lru->list L) ; '(c b a) (lru-add! L 'b) ; hit: bubble to front (lru->list L) ; '(b c a) (lru-add! L 'd) ; capacity 3 -> evicts LRU ('a) (lru->list L) ; '(d b c) (lru-count L) ; 3 (lru-has? L 'c) ; #t (lru-has? L 'a) ; #f (set-lru-expire! L 1) ; items expire after 1 second (sleep 2) (lru-has? L 'b) ; #f (expired) (lru->list L) ; '() (lru-add! L 'x) (lru->list L #:with-expire #t) ; '((x 0)) – age ~ 0 sec (set-lru-max-count! L 1) (lru-add! L 'y) (lru->list L) ; '(y) (lru-clear L) (lru->list L) ; '()
7 Behavior Details
7.1 Recency and Hits
Any insertion or hit refreshes the access time and moves the item to the front. When capacity is reached, the least recently used item is evicted.
7.2 Expiration
If lru-expire is a positive integer, items become expired when their last access is older than that threshold. Cleanup is performed lazily on calls such as lru-has?, lru-count, and lru->list.
7.3 Comparison Function
The #:cmp function decides item equality (e.g., equal?, = for numbers, or a custom predicate). For predictable behavior, it should be symmetric and transitive.
8 Errors and Contracts
max-count, lru-max-count, and set-lru-max-count! use positive integers.
#:expire and set-lru-expire! accept #f or positive integers.
#:cmp is a two-argument function returning a boolean?.
9 Notes
The implementation is thread-safe but not reentrant.
Expiration cleanup is lazy. If you need stricter guarantees, trigger periodic queries (e.g., lru-count) or add an explicit cleanup function.