
Implement a class-based cache that supports get(key, now) and put(key, value, ttl, now) with capacity-limited LRU eviction and expiration. Each entry expires at time now + ttl; expired entries must behave as missing, and when capacity is full, the least recently used non-expired entry should be evicted. Design the cache so operations are thread-safe while keeping lock contention low.
Example 1:
Input:
capacity = 2
put("a", 1, 5, 0)
put("b", 2, 10, 0)
get("a", 3)
put("c", 3, 10, 4)
get("b", 4)
Output:
1
-1
Explanation: `a` is accessed at time 3, so `b` becomes least recently used and is evicted when `c` is inserted.
Example 2:
Input:
capacity = 2
put("x", 7, 2, 0)
get("x", 3)
Output:
-1
Explanation: `x` expired at time 2, so it is treated as absent at time 3.
1 <= capacity <= 10^510^5 calls to get and putkey is hashablevalue is any Python object0 <= now, ttl <= 10^9O(1)