Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8f85437
docs: add rrr Rust DSL migration plan
shuaimu May 27, 2026
d49079a
rrr/basetypes: pilot inline Rust DSL — SparseInt::val_size
shuaimu May 27, 2026
5a3d290
rrr/basetypes: inline Rust DSL — SparseInt::buf_size
shuaimu May 28, 2026
6a9e938
rrr/errors: inline Rust DSL — get_error_category
shuaimu May 28, 2026
25e6eed
rrr/errors: inline Rust DSL — is_retryable_error
shuaimu May 28, 2026
c0b2d6f
rrr/errors: inline Rust DSL — is_connection_error + is_timeout_error
shuaimu May 28, 2026
cbd8629
rrr/errors: consolidate is_connection/is_timeout helpers into one block
shuaimu May 28, 2026
a62fdb5
rrr/reconnect_policy: inline Rust DSL — should_retry + retries_exhausted
shuaimu May 28, 2026
ddc582b
rrr/reconnect_policy: inline Rust DSL — peek_delay_ms + next_delay_ms…
shuaimu May 28, 2026
b733078
rrr/circuit_breaker: inline Rust DSL — circuit_should_probe
shuaimu May 28, 2026
1ab57e7
rrr/request_options: inline Rust DSL — 3 predicate/arithmetic helpers
shuaimu May 28, 2026
13050fb
rrr/connection_state: inline Rust DSL — 4 state classifiers + transit…
shuaimu May 28, 2026
9bb81e0
rrr/heartbeat: inline Rust DSL — 3 timing-arithmetic helpers
shuaimu May 28, 2026
02f3b69
rrr/connection_metrics: inline Rust DSL — 4 derived-stat helpers
shuaimu May 28, 2026
1b9dd93
rrr/internal_protocol: inline Rust DSL — 3 bit-twiddling helpers
shuaimu May 28, 2026
a330634
rrr/idempotency: inline Rust DSL — 3 predicate/statistic helpers
shuaimu May 28, 2026
703ed13
rrr/completion_tracker: inline Rust DSL — 3 predicate/statistic helpers
shuaimu May 28, 2026
dff9df6
rrr/load_balancer: inline Rust DSL — 2 pure-arithmetic helpers
shuaimu May 28, 2026
2ce7add
rrr/rand: inline Rust DSL — 3 pure-arithmetic scaling helpers
shuaimu May 28, 2026
12c3f26
rrr/request_queue: inline Rust DSL — 3 pure-arithmetic helpers
shuaimu May 28, 2026
30ac826
rrr/basetypes: inline Rust DSL — Timer::elapsed seconds helpers
shuaimu May 28, 2026
ec68891
rrr/request_options: inline Rust DSL — calculate_delay_ms backoff
shuaimu May 28, 2026
6c159e3
rrr/frame_codec: inline Rust DSL — 3 size/threshold helpers
shuaimu May 28, 2026
d86b289
rrr/misc: inline Rust DSL — FrequentJob period-elapsed predicate
shuaimu May 28, 2026
bc1340a
rrr/server: inline Rust DSL — instance-id XOR-mix helper
shuaimu May 28, 2026
925bef1
rrr/connection_metrics: inline Rust DSL — min/max latency helpers
shuaimu May 28, 2026
078f618
rrr/stat: inline Rust DSL — AvgStat::sample arithmetic helpers
shuaimu May 28, 2026
8fd8338
rrr/basetypes: inline Rust DSL — Rand::next(int, int) scaling helper
shuaimu May 28, 2026
0c5258f
rrr/idempotency: inline Rust DSL — hash combiner helper
shuaimu May 28, 2026
9534757
rrr/circuit_breaker: inline Rust DSL — timespec→us helper
shuaimu May 28, 2026
4bdc50b
rrr/heartbeat: inline Rust DSL — timespec→us helper
shuaimu May 28, 2026
6e75883
rrr/basetypes: inline Rust DSL — Timer::start/stop split helpers
shuaimu May 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 419 additions & 0 deletions docs/dev/rrr_rust_dsl_migration_plan.md

Large diffs are not rendered by default.

199 changes: 172 additions & 27 deletions src/rrr/base/basetypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ class Timer {
struct timeval end_;
};

// Free helper backing the scaling step of `Rand::next(int, int)`.
// Mirrors the C++ semantics: `lower + r % (upper - lower)` with all
// arithmetic in `u32` (`lower` cast at the boundary; for the typical
// non-negative `lower` this is a noop). `rand_()` returns `u32`
// (mt19937::result_type); we hand that in as `r`. Authored as inline
// Rust DSL.
#if RUSTYCPP_RUST
fn rand_next_in_range(r: u32, lower: i32, upper: i32) -> u32 {
(lower as u32) + r % ((upper - lower) as u32)
}
#endif
/*RUSTYCPP:GEN-BEGIN id=basetypes.1 version=1 rust_sha256=a26f2e98a47135212cbd04b373e24ea7f2ad4d057122d829166df62049f17180*/
uint32_t rand_next_in_range(uint32_t r, int32_t lower, int32_t upper);

uint32_t rand_next_in_range(uint32_t r, int32_t lower, int32_t upper) {
return ((static_cast<uint32_t>(lower))) + (rusty::detail::deref_if_pointer_like(r) % ((static_cast<uint32_t>((rusty::detail::deref_if_pointer_like(upper) - rusty::detail::deref_if_pointer_like(lower))))));
}
/*RUSTYCPP:GEN-END id=basetypes.1*/

class Rand: public NoCopy {
std::mt19937 rand_;
public:
Expand All @@ -141,7 +160,7 @@ class Rand: public NoCopy {
return rand_();
}
std::mt19937::result_type next(int lower, int upper) {
return lower + rand_() % (upper - lower);
return rand_next_in_range(rand_(), lower, upper);
}
std::mt19937::result_type operator() () {
return rand_();
Expand Down Expand Up @@ -217,49 +236,119 @@ class MergedEnumerator: public Enumerator<T> {
// `// @unsafe`.
namespace rrr {

size_t SparseInt::buf_size(char byte0) {
if ((byte0 & 0x80) == 0) {
// Free helper backing `SparseInt::buf_size`. Authored as inline Rust
// DSL (see plan doc). `byte0` is taken as i32 here so the comparison
// literals are signed-positive; the caller masks to 8 bits.
#if RUSTYCPP_RUST
fn sparse_int_buf_size_impl(byte0: i32) -> u64 {
if (byte0 & 0x80) == 0 {
return 1;
} else if ((byte0 & 0xC0) == 0x80) {
} else if (byte0 & 0xC0) == 0x80 {
return 2;
} else if ((byte0 & 0xE0) == 0xC0) {
} else if (byte0 & 0xE0) == 0xC0 {
return 3;
} else if ((byte0 & 0xF0) == 0xE0) {
} else if (byte0 & 0xF0) == 0xE0 {
return 4;
} else if ((byte0 & 0xF8) == 0xF0) {
} else if (byte0 & 0xF8) == 0xF0 {
return 5;
} else if ((byte0 & 0xFC) == 0xF8) {
} else if (byte0 & 0xFC) == 0xF8 {
return 6;
} else if ((byte0 & 0xFE) == 0xFC) {
} else if (byte0 & 0xFE) == 0xFC {
return 7;
} else if ((byte0 & 0xFF) == 0xFE) {
} else if (byte0 & 0xFF) == 0xFE {
return 8;
} else {
return 9;
9
}
}
#endif
/*RUSTYCPP:GEN-BEGIN id=basetypes.2 version=1 rust_sha256=31569640ef4bafbff3f49ae55731162cc8754c42d9107ed3c43edc8fbc3594b8*/
uint64_t sparse_int_buf_size_impl(int32_t byte0);

uint64_t sparse_int_buf_size_impl(int32_t byte0) {
if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(128))) == static_cast<int32_t>(0)) {
return static_cast<uint64_t>(1);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(192))) == static_cast<int32_t>(128)) {
return static_cast<uint64_t>(2);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(224))) == static_cast<int32_t>(192)) {
return static_cast<uint64_t>(3);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(240))) == static_cast<int32_t>(224)) {
return static_cast<uint64_t>(4);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(248))) == static_cast<int32_t>(240)) {
return static_cast<uint64_t>(5);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(252))) == static_cast<int32_t>(248)) {
return static_cast<uint64_t>(6);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(254))) == static_cast<int32_t>(252)) {
return static_cast<uint64_t>(7);
} else if (((rusty::detail::deref_if_pointer_like(byte0) & static_cast<int32_t>(255))) == static_cast<int32_t>(254)) {
return static_cast<uint64_t>(8);
} else {
return static_cast<uint64_t>(9);
}
}
/*RUSTYCPP:GEN-END id=basetypes.2*/

size_t SparseInt::val_size(i64 val) {
if (-64 <= val && val <= 63) {
size_t SparseInt::buf_size(char byte0) {
return static_cast<size_t>(
sparse_int_buf_size_impl(static_cast<int32_t>(byte0) & 0xFF));
}

// Free helper backing `SparseInt::val_size`. Authored as inline Rust
// DSL: the `#if RUSTYCPP_RUST` block is the source of truth; the
// transpiler regenerates the matching `/*RUSTYCPP:GEN-BEGIN ... END*/`
// block immediately below. See docs/dev/rrr_rust_dsl_migration_plan.md.
#if RUSTYCPP_RUST
fn sparse_int_val_size_impl(val: i64) -> u64 {
if val >= -64 && val <= 63 {
return 1;
} else if (-8192 <= val && val <= 8191) {
} else if val >= -8192 && val <= 8191 {
return 2;
} else if (-1048576 <= val && val <= 1048575) {
} else if val >= -1048576 && val <= 1048575 {
return 3;
} else if (-134217728 <= val && val <= 134217727) {
} else if val >= -134217728 && val <= 134217727 {
return 4;
} else if (-17179869184LL <= val && val <= 17179869183LL) {
} else if val >= -17179869184 && val <= 17179869183 {
return 5;
} else if (-2199023255552LL <= val && val <= 2199023255551LL) {
} else if val >= -2199023255552 && val <= 2199023255551 {
return 6;
} else if (-281474976710656LL <= val && val <= 281474976710655LL) {
} else if val >= -281474976710656 && val <= 281474976710655 {
return 7;
} else if (-36028797018963968LL <= val && val <= 36028797018963967LL) {
} else if val >= -36028797018963968 && val <= 36028797018963967 {
return 8;
} else {
return 9;
9
}
}
#endif
/*RUSTYCPP:GEN-BEGIN id=basetypes.3 version=1 rust_sha256=5e0232658d8bb791e952ff50617cc358eff1c2e8847a09b73d303ca99bb153d3*/
uint64_t sparse_int_val_size_impl(int64_t val);

uint64_t sparse_int_val_size_impl(int64_t val) {
if ((rusty::detail::deref_if_pointer_like(val) >= -64) && (rusty::detail::deref_if_pointer_like(val) <= 63)) {
return static_cast<uint64_t>(1);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -8192) && (rusty::detail::deref_if_pointer_like(val) <= 8191)) {
return static_cast<uint64_t>(2);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -1048576) && (rusty::detail::deref_if_pointer_like(val) <= 1048575)) {
return static_cast<uint64_t>(3);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -134217728) && (rusty::detail::deref_if_pointer_like(val) <= 134217727)) {
return static_cast<uint64_t>(4);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -17179869184) && (rusty::detail::deref_if_pointer_like(val) <= 17179869183)) {
return static_cast<uint64_t>(5);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -2199023255552) && (rusty::detail::deref_if_pointer_like(val) <= 2199023255551)) {
return static_cast<uint64_t>(6);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -281474976710656) && (rusty::detail::deref_if_pointer_like(val) <= 281474976710655)) {
return static_cast<uint64_t>(7);
} else if ((rusty::detail::deref_if_pointer_like(val) >= -36028797018963968) && (rusty::detail::deref_if_pointer_like(val) <= 36028797018963967)) {
return static_cast<uint64_t>(8);
} else {
return static_cast<uint64_t>(9);
}
}
/*RUSTYCPP:GEN-END id=basetypes.3*/

size_t SparseInt::val_size(i64 val) {
return static_cast<size_t>(sparse_int_val_size_impl(val));
}

// @unsafe - reinterpret_cast<char*> + raw `char*` byte indexing.
size_t SparseInt::dump(i32 val, char* buf) {
Expand Down Expand Up @@ -434,6 +523,32 @@ i64 SparseInt::load_i64(const char* buf) {
return val;
}

// Free helpers backing the µs→(sec, usec) split used by
// `Timer::start` and `Timer::stop`. Pure u64 arithmetic; the C++
// wrapper owns the `gettimeofday_us()` call and casts each result to
// the platform `time_t`/`suseconds_t`. Authored as inline Rust DSL.
#if RUSTYCPP_RUST
fn timer_us_to_sec(now_us: u64) -> i64 {
(now_us / 1000000) as i64
}

fn timer_us_to_usec_remainder(now_us: u64) -> i64 {
(now_us % 1000000) as i64
}
#endif
/*RUSTYCPP:GEN-BEGIN id=basetypes.4 version=1 rust_sha256=98381e86d68026eefd3e00fd7861f8872ef1a52504193ff4c7cda8181159b66e*/
int64_t timer_us_to_sec(uint64_t now_us);
int64_t timer_us_to_usec_remainder(uint64_t now_us);

int64_t timer_us_to_sec(uint64_t now_us) {
return static_cast<int64_t>((rusty::detail::deref_if_pointer_like(now_us) / 1000000));
}

int64_t timer_us_to_usec_remainder(uint64_t now_us) {
return static_cast<int64_t>((rusty::detail::deref_if_pointer_like(now_us) % 1000000));
}
/*RUSTYCPP:GEN-END id=basetypes.4*/

Timer::Timer() : begin_(), end_() {
reset();
}
Expand All @@ -443,15 +558,15 @@ Timer::Timer() : begin_(), end_() {
void Timer::start() {
reset();
const std::uint64_t now = rusty::sys::time::gettimeofday_us();
begin_.tv_sec = static_cast<time_t>(now / 1000000);
begin_.tv_usec = static_cast<suseconds_t>(now % 1000000);
begin_.tv_sec = static_cast<time_t>(timer_us_to_sec(now));
begin_.tv_usec = static_cast<suseconds_t>(timer_us_to_usec_remainder(now));
}

// @safe - delegates to rusty::sys::time::gettimeofday_us.
void Timer::stop() {
const std::uint64_t now = rusty::sys::time::gettimeofday_us();
end_.tv_sec = static_cast<time_t>(now / 1000000);
end_.tv_usec = static_cast<suseconds_t>(now % 1000000);
end_.tv_sec = static_cast<time_t>(timer_us_to_sec(now));
end_.tv_usec = static_cast<suseconds_t>(timer_us_to_usec_remainder(now));
}

void Timer::reset() {
Expand All @@ -461,16 +576,46 @@ void Timer::reset() {
end_.tv_usec = 0;
}

// Free helpers backing the two arithmetic branches of `Timer::elapsed`.
// The "live" branch (no stop() yet) divides the `now_us - begin_us`
// delta by 1e6; the "stopped" branch combines `(sec, usec)` pairs into
// seconds. Authored as inline Rust DSL.
#if RUSTYCPP_RUST
fn timer_elapsed_live_seconds(now_us: u64, begin_us: u64) -> f64 {
((now_us - begin_us) as f64) / 1000000.0
}

fn timer_elapsed_stopped_seconds(begin_sec: i64, begin_usec: i64, end_sec: i64, end_usec: i64) -> f64 {
((end_sec - begin_sec) as f64) + ((end_usec - begin_usec) as f64) / 1000000.0
}
#endif
/*RUSTYCPP:GEN-BEGIN id=basetypes.5 version=1 rust_sha256=1e6f6fe57720959ad168d9fa8de32b0aa0ad784365f26b89d2151ff53f69f0c9*/
double timer_elapsed_live_seconds(uint64_t now_us, uint64_t begin_us);
double timer_elapsed_stopped_seconds(int64_t begin_sec, int64_t begin_usec, int64_t end_sec, int64_t end_usec);

double timer_elapsed_live_seconds(uint64_t now_us, uint64_t begin_us) {
return ((static_cast<double>((rusty::detail::deref_if_pointer_like(now_us) - rusty::detail::deref_if_pointer_like(begin_us))))) / 1000000.0;
}

double timer_elapsed_stopped_seconds(int64_t begin_sec, int64_t begin_usec, int64_t end_sec, int64_t end_usec) {
return ((static_cast<double>((rusty::detail::deref_if_pointer_like(end_sec) - rusty::detail::deref_if_pointer_like(begin_sec))))) + (((static_cast<double>((rusty::detail::deref_if_pointer_like(end_usec) - rusty::detail::deref_if_pointer_like(begin_usec))))) / 1000000.0);
}
/*RUSTYCPP:GEN-END id=basetypes.5*/

// @safe - live-elapsed branch delegates to rusty::sys::time::gettimeofday_us.
double Timer::elapsed() const {
if (begin_.tv_sec == 0 && begin_.tv_usec == 0) std::abort();
if (end_.tv_sec == 0 && end_.tv_usec == 0) {
const std::uint64_t now_us = rusty::sys::time::gettimeofday_us();
const std::uint64_t begin_us =
static_cast<std::uint64_t>(begin_.tv_sec) * 1000000 + begin_.tv_usec;
return static_cast<double>(now_us - begin_us) / 1000000.0;
return timer_elapsed_live_seconds(now_us, begin_us);
}
return end_.tv_sec - begin_.tv_sec + (end_.tv_usec - begin_.tv_usec) / 1000000.0;
return timer_elapsed_stopped_seconds(
static_cast<int64_t>(begin_.tv_sec),
static_cast<int64_t>(begin_.tv_usec),
static_cast<int64_t>(end_.tv_sec),
static_cast<int64_t>(end_.tv_usec));
}

// @safe - all three seed contributors flow through @safe wrappers:
Expand Down
22 changes: 20 additions & 2 deletions src/rrr/base/misc.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module;

#include <stdint.h>
#include <rusty/fn.hpp>
#include <rusty/function.hpp>
#include <rusty/rusty.hpp>
#include <rusty/sys/process.hpp>
#include <rusty/sys/time.hpp>

Expand Down Expand Up @@ -98,6 +100,23 @@ class OneTimeJob : public Job {
}
};

// Free helper backing the period-elapsed predicate in
// `FrequentJob::Ready`. Pure u64 arithmetic; the C++ wrapper owns the
// `rrr::Time::now()` call and the `tm_last_` mutation. Authored as
// inline Rust DSL.
#if RUSTYCPP_RUST
fn frequent_job_period_elapsed(now_us: u64, last_us: u64, period_us: u64) -> bool {
(now_us - last_us) > period_us
}
#endif
/*RUSTYCPP:GEN-BEGIN id=misc.1 version=1 rust_sha256=43bf2a5a69df6acff4e54d8c0c0b8d43bc5d55cee8f5979271d3017dc5dd3280*/
bool frequent_job_period_elapsed(uint64_t now_us, uint64_t last_us, uint64_t period_us);

bool frequent_job_period_elapsed(uint64_t now_us, uint64_t last_us, uint64_t period_us) {
return ((rusty::detail::deref_if_pointer_like(now_us) - rusty::detail::deref_if_pointer_like(last_us))) > rusty::detail::deref_if_pointer_like(period_us);
}
/*RUSTYCPP:GEN-END id=misc.1*/

class FrequentJob : public Job {
public:
uint64_t tm_last_ = 0;
Expand All @@ -107,8 +126,7 @@ class FrequentJob : public Job {
// @safe - rrr::Time::now() flows through rusty::sys::time::clock_*_us.
virtual bool Ready() override {
uint64_t tm_now = rrr::Time::now();
uint64_t s = tm_now - tm_last_;
if (s > period_) {
if (frequent_job_period_elapsed(tm_now, tm_last_, period_)) {
tm_last_ = tm_now;
return true;
}
Expand Down
42 changes: 39 additions & 3 deletions src/rrr/misc/rand.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module;

#include <stdint.h>
#include <rusty/rusty.hpp>
#include <pthread.h>
#include <time.h>
Expand All @@ -20,6 +21,41 @@ import rrr.debugging;
// inline asm, malloc, and pthread C-API calls.
export namespace rrr {

// Free helpers backing the pure-arithmetic scaling portions of
// `RandomGenerator::rand`, `rand_double`, and `nu_rand`. Each takes
// the raw `rand_r` output (i32) plus the user-supplied bounds and
// returns the scaled value. Authored as inline Rust DSL.
#if RUSTYCPP_RUST
fn rand_scale_to_range(r: i32, min: i32, max: i32) -> i32 {
(r % (max - min + 1)) + min
}

fn rand_double_scale_to_range(r: i32, rand_max: i32, min: f64, max: f64) -> f64 {
(r as f64) / ((rand_max as f64) / (max - min)) + min
}

fn nu_rand_combine(r1: i32, r2: i32, nu_constant: i32, x: i32, y: i32) -> i32 {
((r1 | r2) + nu_constant) % (y - x + 1) + x
}
#endif
/*RUSTYCPP:GEN-BEGIN id=rand.1 version=1 rust_sha256=ceb6d63902c32008701f441b7ce7aceff0fa03473b7b6d6f7d77bb7aaea80035*/
int32_t rand_scale_to_range(int32_t r, int32_t min, int32_t max);
double rand_double_scale_to_range(int32_t r, int32_t rand_max, double min, double max);
int32_t nu_rand_combine(int32_t r1, int32_t r2, int32_t nu_constant, int32_t x, int32_t y);

int32_t rand_scale_to_range(int32_t r, int32_t min, int32_t max) {
return ((rusty::detail::deref_if_pointer_like(r) % (((rusty::detail::deref_if_pointer_like(max) - rusty::detail::deref_if_pointer_like(min)) + static_cast<int32_t>(1))))) + rusty::detail::deref_if_pointer_like(min);
}

double rand_double_scale_to_range(int32_t r, int32_t rand_max, double min, double max) {
return (((static_cast<double>(r))) / ((((static_cast<double>(rand_max))) / ((rusty::detail::deref_if_pointer_like(max) - rusty::detail::deref_if_pointer_like(min)))))) + rusty::detail::deref_if_pointer_like(min);
}

int32_t nu_rand_combine(int32_t r1, int32_t r2, int32_t nu_constant, int32_t x, int32_t y) {
return (((((rusty::detail::deref_if_pointer_like(r1) | rusty::detail::deref_if_pointer_like(r2))) + rusty::detail::deref_if_pointer_like(nu_constant))) % (((rusty::detail::deref_if_pointer_like(y) - rusty::detail::deref_if_pointer_like(x)) + static_cast<int32_t>(1)))) + rusty::detail::deref_if_pointer_like(x);
}
/*RUSTYCPP:GEN-END id=rand.1*/

// @safe - see file header.
class RandomGenerator {
private:
Expand Down Expand Up @@ -110,7 +146,7 @@ int RandomGenerator::rand(int min, int max) {
r = rand_r(&seed_);
#endif
}
return (r % (max - min + 1)) + min;
return rand_scale_to_range(r, min, max);
}

double RandomGenerator::rand_double(double min, double max) {
Expand All @@ -127,7 +163,7 @@ double RandomGenerator::rand_double(double min, double max) {
r = rand_r(&seed_);
#endif
}
return (static_cast<double>(r)) / (static_cast<double>(RAND_MAX) / (max - min)) + min;
return rand_double_scale_to_range(r, RAND_MAX, min, max);
}

std::string RandomGenerator::rand_str(int length) {
Expand Down Expand Up @@ -178,7 +214,7 @@ bool RandomGenerator::percentage_true(int p) {
int RandomGenerator::nu_rand(int a, int x, int y) {
int r1 = rand(0, a);
int r2 = rand(x, y);
return ((r1 | r2) + nu_constant) % (y - x + 1) + x;
return nu_rand_combine(r1, r2, nu_constant, x, y);
}

// @unsafe - inline `rdtsc` asm + clock_gettime syscall.
Expand Down
Loading
Loading