Design a token manager with lazy expiration
CitadelSoftware Engineer · Technical ScreenLast updated
This problem tests your ability to design a token management system that supports efficient retrieval, updates, and lazy removal of expired tokens using a combination of a hash map and a priority queue.
Token Manager Design
Design a TokenManager class that handles session tokens with a Time-To-Live (TTL). Each token is associated with a specific expiration timestamp. The system should be able to handle millions of tokens efficiently.
Your class needs to support the following operations:
upsert(token_id, ttl_seconds): Adds a new token or updates the expiration of an existing token. The new expiration time is the current time plusttl_seconds.get(token_id): Returns the token's expiration timestamp if it exists and hasn't expired. If the token has expired or does not exist, return -1. This operation must perform lazy deletion—if you encounter an expired token during a lookup, remove it immediately.count_active(): Returns the number of tokens that have not yet expired. You must provide an efficient way to track this, but you are not required to actively purge all expired tokens in the background; only purge them when accessed or when requested.
Constraints
token_id: String (unique identifier)ttl_seconds: Integer (positive)- The current time can be simulated using
time.time().
Example
# Assume current time = 1000
tm = TokenManager()
tm.upsert("user_a", 10) # Expires at 1010
tm.upsert("user_b", 5) # Expires at 1005
print(tm.get("user_b")) # Returns 1005
# Time moves to 1007
print(tm.get("user_b")) # Returns -1, lazily removes "user_b"
print(tm.count_active()) # Returns 1
Edge Cases
- Accessing a token exactly at its expiration time.
- Repeatedly updating the same token ID.
- Calling
count_activewhen many tokens are expired but haven't been accessed.
Hints
Hint 1
Use a hash map to store the mapping between token IDs and their absolute expiration timestamps.
Hint 2
Consider using a min-heap to keep track of tokens ordered by their expiration time, allowing you to identify expired tokens quickly.
Hint 3
For count_active, keep a running counter that decrements only when a token is explicitly proven to be expired during a 'get' or 'upsert' operation.
Follow-up questions
- How would you modify this design if you needed to support an 'evict all expired tokens' operation that runs in O(k log n) where k is the number of expired tokens?
- If the system experiences a massive burst of upserts, how could you prevent the heap from becoming a bottleneck?
- How would this design change if you needed to support distributed access across multiple server nodes?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.