Per-user chat event counts in a sliding window
A chat service runs for months without restarting. It sends you a stream of message events. Each event has a user_id, a chat_id and an integer timestamp in seconds. You must answer, for any user, how many of their events fall in the last m seconds.
Implement ChatEventAggregator:
-
ChatEventAggregator(m: int):m > 0is the window length in seconds. -
record(user_id: str, chat_id: str, timestamp: int) -> None: store one event. -
get_count(user_id: str, timestamp: int) -> int: return the number of events byuser_idwith timestamp in the inclusive window[timestamp - m + 1, timestamp]. Return 0 for a user with no events.
Guarantees
- For one user,
recordtimestamps strictly increase. - Time never goes backwards: every call (record or query) has a timestamp greater than or equal to the largest timestamp of any earlier call.
Memory requirement
The process runs indefinitely and sees millions of users. Memory must stay proportional to the events in the most recent m seconds. Discard any data that no future query can use, including all data about users who have gone quiet.
Example
agg = ChatEventAggregator(10)
agg.record("ana", "c1", 1)
agg.record("ana", "c2", 5)
agg.record("bo", "c1", 6)
agg.record("ana", "c1", 9)
agg.get_count("ana", 10) # 3, window [1, 10]
agg.get_count("ana", 11) # 2, window [2, 11]: t=1 is out
agg.get_count("bo", 16) # 0, window [7, 16]
After get_count("ana", 19) returns 0, the aggregator should hold no data for either user.
Constraints
1 <= m <= 10^60 <= timestamp <= 10^9- Up to
10^6calls in total.
State the time and space cost of each operation.
Sign in to see the worked answer
The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.
