[LintCode][System Design] Rate Limiter

Problem

Implement a rate limiter, provide one method:
is_ratelimited(timestamp, event, rate, increment).

timestamp: The current timestamp, which is an integer and in second unit.

event: The string to distinct different event. for example, "login" or "signup".

rate: The rate of the limit. 1/s (1 time per second), 2/m (2 times per minute), 10/h (10 times per hour), 100/d (100 times per day). The format is [integer]/[s/m/h/d].

increment: Whether we should increase the counter. (or take this call as a hit of the given event)

The method should return true or false to indicate the event is limited or not.

Example

is_ratelimited(1, "login", "3/m", true), return false.
is_ratelimited(11, "login", "3/m", true), return false.
is_ratelimited(21, "login", "3/m", true), return false.
is_ratelimited(30, "login", "3/m", true), return true.
is_ratelimited(65, "login", "3/m", true), return false.
is_ratelimited(300, "login", "3/m", true), return false.

Challenge

How many different algorithms you can come up with?

Solution

用hash保存每個(gè)事件在timestamp發(fā)生的次數(shù)。之后去掃描某個(gè)事件是否達(dá)到了limit

class RateLimiter {
private:
    map<string, map<int, int>> count;
public:
    /**
     * @param timestamp the current timestamp
     * @param event the string to distinct different event
     * @param rate the format is [integer]/[s/m/h/d]
     * @param increment whether we should increase the counter
     * @return true or false to indicate the event is limited or not
     */
    bool isRatelimited(int timestamp, string& event, string& rate, bool increment) {
        int pos = rate.find("/");
        int times = stoi(rate.substr(0, pos));
        string per = rate.substr(pos+1, rate.size());
        int delta = 0;
        if (per == "s") {
            delta = 1;
        } else if (per == "m") {
            delta = 60;
        } else if (per == "h") {
            delta = 60 * 60;
        } else {
            delta = 60 * 60 * 24;
        }
        
        int total = 0;
        // 只從大于等于 timestamp - delta + 1 的 key 開始掃描
        for(map<int, int>::iterator iter = count[event].lower_bound(timestamp-delta+1); 
        iter != count[event].end(); 
        iter++) {
            total += iter->second;
        }

        bool result = total >= times;
        if (increment && !result) {
            count[event][timestamp]++;
        }
        return result;
    }
};```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容