Build Sessions from Unordered Events (Part 1)
Problem statement
This is Part 1 of Event Log Reconciliation. Continue with Part 2: Match Billing Charges to User Sessions for billing reconciliation.
Background
You receive a stream of user activity events. The events may arrive out of order. In Part 1, reconstruct the user sessions and summarize them for each user.
events is a list of objects. Each object has a user ID, an integer timestamp, and an event type:
{ "user": "u1", "ts": 100, "type": "login" }The type is login, action, or logout. A single user's events have distinct timestamps. Events from different users may have the same timestamp.
How to build sessions
Process the events for each user in timestamp order:
- A
loginopens a session. - The next
logoutfor that user closes the session. Its active time islogout_ts - login_ts. - Missing logout: If another
loginarrives while the session is open, or the user's events end before a logout, close the session at its lastactiontimestamp. If it contains no actions, close it at its login timestamp, giving it an active time of0. A new login then opens another session. - Ignore an
actionorlogoutwhen the user has no open session. For example, an action before the first login belongs to no session.
Session summaries
The result is a mapping from each user to that user's session summary:
{"u1": { "sessions": 2, "active_time": 300 }}sessionsis the number of sessions reconstructed for the user, including sessions with zero active time.active_timeaddsend - startacross that user's sessions.
Leave out users who have no reconstructed sessions.
Walkthrough
Consider these events:
[{ "user": "u1", "ts": 100, "type": "login" },{ "user": "u1", "ts": 250, "type": "logout" },{ "user": "u1", "ts": 180, "type": "action" },{ "user": "u2", "ts": 120, "type": "action" }]The u1 action arrives after its logout in the input. In timestamp order, the events are login at 100, action at 180, and logout at 250. They form one session, [100, 250], with active time 150.
User u2 has an action but no login, so that event is ignored and u2 is omitted. The summary is:
{ "u1": { "sessions": 1, "active_time": 150 } }Practice input and output
In the coding workspace, the event objects are represented by three parallel arrays. At index i, users[i] is user, timestamps[i] is ts, and types[i] is type.
Return the summary mapping as rows of [user, sessionCount, activeTime]. Write the count and active time as decimal strings, and sort the rows by user ID in increasing lexicographic order. For the walkthrough above, return [["u1", "1", "150"]].
Function
buildSessions(users: String[], timestamps: int[], types: String[]) → String[][]Examples
Example 1
users = ["u1","u1","u1","u1","u1","u1"]timestamps = [30,10,20,50,40,60]types = ["logout","login","action","login","action","logout"]return = [["u1","2","30"]]After sorting, u1 has login 10, action 20, and logout 30, for active time 20. The action at 40 is ignored. Login 50 and logout 60 add 10. The result is 2 sessions and active time 30.
Example 2
users = ["u1","u1","u1","u1"]timestamps = [50,30,10,20]types = ["action","login","login","action"]return = [["u1","2","30"]]Login 10 and action 20 form the first session, which the login at 30 closes at 20. The second session ends at its last action, 50. Their durations are 10 and 20, so the total is 30 across 2 sessions.
Example 3
users = ["u1","u2","u1"]timestamps = [5,10,20]types = ["action","login","logout"]return = [["u2","1","0"]]Both u1 events occur without an open session and are ignored. The lone u2 login creates 1 session with active time 0.
Example 4
users = ["u1","u1","u1","u2"]timestamps = [100,250,180,120]types = ["login","logout","action","action"]return = [["u1","1","150"]]This is the source example. Sorting u1's events gives login at 100, action at 180, then logout at 250. Its one session lasts 250 - 100 = 150. The u2 action at 120 occurs without a login and is ignored.
Constraints
- For this exercise, assume
0 <= users.length <= 10000. users.length = timestamps.length = types.length.- For this exercise, assume each user ID has
1to32characters and contains only lowercase ASCII letters and digits. - For this exercise, assume
-2147483648 <= timestamps[i] <= 2147483647. - Every event type is one of
login,action, orlogout. - Events for the same user have distinct timestamps. Different users may share timestamps.