Thread-Safe Request Counts by Attribute
Problem statement
Implement a thread-safe request counter that groups recent requests by a chosen attribute, such as IP address or BrowserAgent. Support any attribute listed in attributes without hard-coding those names.
Process a finite trace operations with a rolling window of window time units. The counter starts empty. Operation fields are strings:
- An add is
["add", time, worker, value0, value1, ...]. It records one request; the values correspond toattributesin order. Worker is"0"or"1". - A count is
["count", time, attributeName, targetValue]. Return the number of requests whose chosen attribute equals the target and whose timestampssatisfiestime - window < s <= time.
At each timestamp, start two real worker threads (or goroutines) for its adds. Each worker records its assigned requests in input order, sharing one synchronized counter. Wait for both workers to finish, then answer that timestamp's counts in input order. With no adds, no worker needs to start. Return one integer for every count.
The workers may interleave in any order. Every recorded request must count exactly once, and results after the join must be independent of that interleaving. Implement the shared storage and counting logic using arrays and strings. Basic thread creation, joining, mutex/monitor locks, and atomic synchronization are allowed; do not use a prebuilt concurrent map, counter, queue, or window library.
Function
countRequests(window: int, attributes: String[], operations: String[][]) → int[]Examples
Example 1
window = 5attributes = ["IP","BrowserAgent"]operations = [["add","0","0","a","Chrome"],["add","0","1","a","Firefox"],["count","0","IP","a"],["add","4","1","b","Chrome"],["count","4","BrowserAgent","Chrome"],["count","5","IP","a"]]return = [2,2,0]At time 0, both workers record IP a, giving count 2. At time 4, the Chrome requests from times 0 and 4 are both in the window. At time 5, the requests at time 0 lie on the excluded lower boundary, so IP a has count 0.
Example 2
window = 2attributes = ["Region"]operations = [["add","1","0","west"],["add","1","1","east"],["count","1","Region","west"]]return = [1]The Region attribute is handled by the same generic grouping logic. Only one request has the value west.
Constraints
1 <= window <= 10^9.1 <= attributes.length <= 8.- Attribute names have between
1and32characters. 0 <= operations.length <= 64.- Each operation has between
4and11string fields. Every field has at most64characters. - Attribute names are distinct. Operations use only the stated add/count shapes, decimal timestamps from 0 through 10^9, worker IDs 0 or 1, and declared attribute names. Timestamps are nondecreasing, there are at most 10 distinct timestamps, and all adds at a timestamp precede its counts.