首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无队列漏桶算法

无队列漏桶算法
EN

Code Review用户
提问于 2022-03-28 09:28:00
回答 1查看 217关注 0票数 2

一个漏桶的基本实现,它的想法是你叫它说,我将允许,例如,5次登录尝试每60秒。

代码语言:javascript
复制
    //Leaky Bucket algorithm with chrono
    class RateController {
        int n;
        std::chrono::steady_clock::duration interval;

        int cnt;
        std::chrono::time_point<std::chrono::steady_clock> last;

    public:
        RateController(int limit, int seconds) : 
            n(limit), interval(std::chrono::seconds(seconds/limit)), cnt(0) {}

        bool ok() {
            auto t = std::chrono::steady_clock::now();

            if (cnt) {
                cnt -= (t - last) / interval;

                if (cnt < 0) cnt = 0;
                if (cnt >= n) return false;
            }

            ++cnt;
            last = t;
            return true;
        }
    };
EN

回答 1

Code Review用户

回答已采纳

发布于 2022-03-28 21:16:19

为要使用

的时钟创建类型别名

如果您为时钟创建一个类型别名,就会变得更易于维护和编写,如下所示:

代码语言:javascript
复制
using clock = std::chrono::steady_clock;

这样,你就可以写:

代码语言:javascript
复制
clock::duration interval;
clock::time_point last;
...
auto t = clock::now();

对计数器

使用无符号类型。

我建议对计数器使用无符号类型,因为它们不应该是负的。为了避免计数器泄漏,请写:

代码语言:javascript
复制
cnt -= std::min(cnt, (t - last) / interval);

让调用方以std::chrono::duration

的形式传递间隔

不要强迫调用方将持续时间作为描述秒的整数传递,然后必须自己将其转换为std::chrono::duration类型,而是考虑将构造函数的参数seconds更改为clock::duration类型。然后调用方可以传入它喜欢的任何std::chrono::duration

注意整数除法

表达式seconds / limit将计算为0如果limit > seconds。这是有问题的,因为它将导致ok()中的除数为零。我将完全避免除法,并让interval表示对ok()的最多limit调用将返回true的间隔。为了泄密,你只需写:

代码语言:javascript
复制
cnt -= std::min(cnt, (t - last) * n / interval);

命名事物

有些事情是不必要地缩略的。而不是cnt,而是编写count。不要编写n,而是编写max_countlimit,就像在构造函数中那样。而不是t,写nowcurrent_time。这只是需要输入的几个字符,但是当您忘记了实现的细节时,它将使任何阅读它的人(包括您自己)更加清楚。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/275307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档