In an API rate-limiting system, each incoming requ...
Создано: 10 марта 2025 г.
Создано: 10 марта 2025 г.
In an API rate-limiting system, each incoming request from a domain must be processed while adhering to certain request limits. There is a given array requests of size n, where requests[i] (0 ≤ i < n) represents the domain receiving a request at the th second.
The gateway allows at most 2 requests from a domain within a 5-second window, and at most 5 requests within a 30-second window.
Implement a function that determines whether each request can be processed. It should return "(status: 200, message: OK)" if the request is allowed, or "{status: 429, message: Too many requests)" if the request exceeds the rate limit.
The function getDomainRequestStatus takes the following input: string requests[n]: the list of domains making requests to the gateway
The function should return a list of strings representing the status of each request.
Example:
Suppose n = 7 and requests = ["www.xyz.com", "www.abc.com", "www.xyz.com", "www.pqr.com", "www.abc.com", "www.xyz.com", "www.xyz.com",]
Time
Request
Status of Request
0
Yes
{status: 200, message: OK)
1
Yes
{status: 200, message: OK}
2
Yes
(status: 200, message: OK)
3
Yes
(status: 200, message: OK}
4
www.abc.com Yes
(status: 200, message: OK}
5
Yes
{status: 200, message: OK}
6
No -> 2 requests from "www.xyz.com" were accepted within 5 seconds.
{status: 429, message: Too many requests}
Hence the answer is ["{status: 200, message: OK)", "{status: 200, message: OK)", "(status: 200, message: OK)", "{status: 200, message: OK)", "{status: 200, message: OK)", "(status: 200, message: OK)", "(status: 429, message: Too many requests)"].
Constraints
1≤ns 104
1 length of requests[i] < 15
• requests[i] consists of lowercase English characters and dot ('.') characters.
▼Input Format For Custom Testing
The first line contains an integer, n, the number of elements in requests.
Each of the next n lines contains a string, requests[i].
▼Sample Case 0
Sample Input For Custom Testing
STDIN
FUNCTION
7
→ requests =
requests[] size n = 7
["www.abc.com",
"www.hd.com",
"www.abc.com", "www.pqr.com", "www.abc.com", "www.pqr.com",
"www.pqr.com"]
Sample Output
{status: 200, message: OK}
{status: 200, message: OK}
{status: 200, message: OK}
{status: 200, message: OK}
{status: 429, message: Too many requests}
{status: 200, message: OK}
{status: 429, message: Too many requests}
Explanation
• The fifth request is dropped because it exceeds the limit of 2 requests from "www.abc.com" within a 5-second window.
• Similarly, the last request is dropped as it exceeds the limit of 2 requests from "www.pqr.com" within a 5-second window.
▼ Sample Case 1
Sample Input For Custom Testing
STDIN
FUNCTION
→ requests[] size n = 4
"www.hr.com"]
requests[] = ["www.hr.com", "www.hr.com", "www.hr.com",
4
Sample Output
[status: 200, message: OK}
{status: 200, message: OK}
[status: 429, message: Too many requests)
[status: 429, message: Too many requests]
Explanation
The first two requests are allowed by the gateway. Requests from "www.hr.com" are blocked for the next 3 seconds due to exceeding the rate limit within the allowed time window.
Give C++ optimised code that runs for all possible test cases .
Below is an example of a concise, optimized C++ solution. The main idea is:
Track requests per domain using two deques (or queues) for each domain:
For each incoming request at time :
This ensures amortized checks for each domain, since each request time is pushed and popped at most once from each deque. The solution easily handles up to requests.
cpp#include <bits/stdc++.h> using namespace std; /* We define a function getDomainRequestStatus that takes: - n: number of requests - requests: vector of domain strings (each i-th request arrives at second i) Returns a vector of status messages corresponding to each request. Rate-limits: - At most 2 requests from the same domain in any rolling 5-second window - At most 5 requests from the same domain in any rolling 30-second window */ vector<string> getDomainRequestStatus(int n, const vector<string>& requests) { // We use an unordered_map (hash map) from domain -> pair of deques // first deque (fiveSec) to track timestamps within the last 5 seconds // second deque (thirtySec) to track timestamps within the last 30 seconds unordered_map<string, pair<deque<int>, deque<int>>> domainMap; domainMap.reserve(n); vector<string> result(n); for(int t = 0; t < n; t++){ const string& domain = requests[t]; // Retrieve (or create) the deques for this domain auto& dqPair = domainMap[domain]; auto& fiveSec = dqPair.first; // holds times in [t-4, t] auto& thirtySec = dqPair.second; // holds times in [t-29, t] // 1) Clean out old entries from the 30-second deque // Remove all timestamps <= t-30 while(!thirtySec.empty() && thirtySec.front() <= t - 30) { thirtySec.pop_front(); } // 2) After cleaning, if size >= 5 => block (429) if(thirtySec.size() >= 5) { result[t] = "{status: 429, message: Too many requests}"; continue; // do not record this request (do not push into deques) } // 3) Clean out old entries from the 5-second deque // Remove all timestamps < t-4 while(!fiveSec.empty() && fiveSec.front() < t - 4) { fiveSec.pop_front(); } // 4) After cleaning, if size >= 2 => block (429) if(fiveSec.size() >= 2) { result[t] = "{status: 429, message: Too many requests}"; continue; // do not push the new request into the deques } // If neither limit is exceeded, accept the request fiveSec.push_back(t); thirtySec.push_back(t); result[t] = "{status: 200, message: OK}"; } return result; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; // number of requests vector<string> requests(n); for(int i = 0; i < n; i++){ cin >> requests[i]; // read each domain request } // Compute the statuses vector<string> statuses = getDomainRequestStatus(n, requests); // Output the result for(const auto &s : statuses){ cout << s << "\n"; } return 0; }
unordered_map<string, pair<deque<int>, deque<int>>> domainMap;
We keep for each domain two separate deques:
fiveSec tracks the timestamps of requests within the last 5 seconds.thirtySec tracks the timestamps of requests within the last 30 seconds.Rolling Window Updates
For a new request at time :
thirtySec any timestamps . This ensures only requests in the last 30 seconds remain.thirtySec.size() , block this request (rate limit reached).fiveSec any timestamps . This ensures only requests in remain.fiveSec.size() , block this request (rate limit reached).Complexities
unordered_map to look up the deques for a given domain in average time.This satisfies the constraints and ensures a clean, efficient rate-limiting mechanism for the 5-second and 30-second windows.