skip to content
==> src/rate.c <==
1/* jobs.rs's Rate and lease_time. */
2#include "mesh/jobs/rate.h"
3
4void mj_rate_count(mj_rate *r, uint64_t n, uint64_t now) {
5    if (r->t0 == 0) r->t0 = now;
6    r->k += n;
7    uint64_t dt = now > r->t0 ? now - r->t0 : 0;
8    if (dt >= 400) {
9        double inst = (double)r->k * 1000.0 / (double)dt;
10        r->ips = r->ips == 0.0 ? inst : 0.5 * r->ips + 0.5 * inst;
11        r->t0 = now;
12        r->k = 0;
13    }
14}
15
16void mj_rate_busy(mj_rate *r, uint64_t now) {
17    if (r->idle_at > 0 && (now > r->idle_at ? now - r->idle_at : 0) > MESH_JOBS_IDLE_MS) {
18        r->t0 = now;
19        r->k = 0;
20    }
21    r->idle_at = 0;
22}
23
24void mj_rate_lease_done(mj_rate *r, uint64_t n, uint64_t issued, uint64_t now, bool last) {
25    if (r->ips == 0.0 && now > issued) r->ips = (double)n * 1000.0 / (double)(now - issued);
26    /* Slow start: a lease done in under half LEASE_MS (end to end) doubles the next (if it was of the
27     * full size: a lease cut short by the job's tail says nothing); one over 3 x LEASE_MS halves it. */
28    uint64_t t = now > issued ? now - issued : 0;
29    if (t * 2 < MESH_JOBS_LEASE_MS && n * 2 >= r->target) {
30        uint64_t m = r->target > n ? r->target : n;
31        r->target = m * 2 < MESH_JOBS_LEASE_MAX ? m * 2 : MESH_JOBS_LEASE_MAX;
32    } else if (t > 3 * MESH_JOBS_LEASE_MS) r->target = n / 2 > 1 ? n / 2 : 1;
33    if (last) r->idle_at = now > 1 ? now : 1;
34}
35
36uint64_t mj_lease_time(uint64_t n, double rate) {
37    if (rate > 0.0) {
38        double t = (double)n * 1000.0 / rate;
39        /* Rust's `as u64` saturates (and a NaN is 0). */
40        uint64_t ms = t != t ? 0 : t >= 18446744073709551615.0 ? UINT64_MAX : (uint64_t)t;
41        return ms + 1;
42    }
43    return 10000;
44}