Design Log Storage System - Problem

You are given several logs, where each log contains a unique ID and timestamp. Timestamp is a string that has the following format: Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59. All domains are zero-padded decimal numbers.

Implement the LogSystem class:

  • LogSystem() Initializes the LogSystem object.
  • void put(int id, string timestamp) Stores the given log (id, timestamp) in your storage system.
  • int[] retrieve(string start, string end, string granularity) Returns the IDs of the logs whose timestamps are within the range from start to end inclusive. start and end all have the same format as timestamp, and granularity means how precise the range should be (i.e. to the exact Day, Minute, etc.).

For example, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", and granularity = "Day" means that we need to find the logs within the inclusive range from Jan. 1st 2017 to Jan. 2nd 2017, and the Hour, Minute, and Second for each log entry can be ignored.

Input & Output

Example 1 — Basic Log System Operations
$ Input: [["LogSystem"], ["put", 1, "2017:01:01:23:59:59"], ["put", 2, "2017:01:01:22:59:59"], ["put", 3, "2016:01:01:00:00:00"], ["retrieve", "2016:01:01:01:01:01", "2017:01:01:23:00:00", "Year"], ["retrieve", "2016:01:01:01:01:01", "2017:01:01:23:00:00", "Hour"]]
Output: [null, null, null, null, [3,2,1], [2,1]]
💡 Note: LogSystem created, logs stored, then retrieved by Year granularity (ignores month/day/hour details) and Hour granularity (more precise filtering)
Example 2 — Day Granularity Filter
$ Input: [["LogSystem"], ["put", 1, "2017:01:01:23:59:59"], ["put", 2, "2017:01:02:23:59:59"], ["put", 3, "2017:01:03:23:59:59"], ["retrieve", "2017:01:01:00:00:00", "2017:01:02:23:59:59", "Day"]]
Output: [null, null, null, null, [1,2]]
💡 Note: Day granularity means compare only YYYY:MM:DD parts, so logs from Jan 1st and Jan 2nd match the range, Jan 3rd is excluded
Example 3 — Month Granularity
$ Input: [["LogSystem"], ["put", 1, "2017:01:15:10:30:45"], ["put", 2, "2017:02:20:12:45:30"], ["retrieve", "2017:01:01:00:00:00", "2017:01:31:23:59:59", "Month"]]
Output: [null, null, null, [1]]
💡 Note: Month granularity compares YYYY:MM only, so only log from January 2017 matches

Constraints

  • 1 ≤ id ≤ 106
  • 2000 ≤ Year ≤ 2017
  • 1 ≤ Month ≤ 12
  • 1 ≤ Day ≤ 31
  • 0 ≤ Hour ≤ 23
  • 0 ≤ Minute, Second ≤ 59
  • granularity is one of ["Year", "Month", "Day", "Hour", "Minute", "Second"]

Visualization

Tap to expand
Design Log Storage System INPUT LogSystem Storage ID:1 | 2017:01:01:23:59:59 ID:2 | 2017:01:01:22:59:59 ID:3 | 2016:01:01:00:00:00 Timestamp Format: Year:Mon:Day:Hr:Min:Sec Granularity Levels: Year Month Day Hour Retrieve Queries: Q1: "Year" granularity Q2: "Hour" granularity Range: 2016-2017 ALGORITHM STEPS 1 Store Logs Sorted Keep logs in sorted order by timestamp string 2 Parse Granularity Determine cutoff index for comparison length Index Mapping Year --> idx 4 Month --> idx 7 Day --> idx 10 Hour --> idx 13 Minute --> idx 16 Second--> idx 19 3 Truncate Timestamps Cut start/end/log times to granularity length 4 Compare & Collect Find logs where truncated time is in [start, end] FINAL RESULT Query 1: Granularity = "Year" Compare first 4 chars only: Start: "2016" End: "2017" ID:3 "2016" in range - OK ID:1,2 "2017" in range - OK [3, 2, 1] Query 2: Granularity = "Hour" Compare first 13 chars: Start: "2016:01:01:01" End: "2017:01:01:23" ID:3 "2016:...:00" < start ID:1,2 in range - OK [2, 1] Key Insight: String comparison works perfectly for timestamps in "YYYY:MM:DD:HH:MM:SS" format because lexicographic order matches chronological order. By truncating strings to the granularity index, we can efficiently filter logs without parsing into separate time components. O(n) per retrieve. TutorialsPoint - Design Log Storage System | Optimized with Sorted Storage
Asked in
Google 35 Amazon 28 Microsoft 22 Facebook 18
28.5K Views
Medium Frequency
~25 min Avg. Time
890 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen