int aeron_feedback_delay_state_init( aeron_feedback_delay_generator_state_t *state, aeron_feedback_delay_generator_func_t delay_generator, int64_t delay_ns, size_t multicast_group_size, bool should_immediate_feedback) { static bool is_seeded = false; double lambda = log((double)multicast_group_size) + 1; double max_backoff_T = (double)delay_ns; state->static_delay.delay_ns = delay_ns; state->optimal_delay.rand_max = lambda / max_backoff_T; state->optimal_delay.base_x = lambda / (max_backoff_T * (exp(lambda) - 1)); state->optimal_delay.constant_t = max_backoff_T / lambda; state->optimal_delay.factor_t = (exp(lambda) - 1) * (max_backoff_T / lambda); if (!is_seeded) { aeron_srand48(aeron_nano_clock()); is_seeded = true; } state->should_immediate_feedback = should_immediate_feedback; state->delay_generator = delay_generator; return 0; }
int64_t aeron_loss_detector_nak_multicast_delay_generator() { static bool initialized = false; static double lambda; static double rand_max; static double base_x; static double constant_t; static double factor_t; if (!initialized) { lambda = log(AERON_LOSS_DETECTOR_NAK_MULTICAST_GROUPSIZE) + 1; rand_max = lambda / AERON_LOSS_DETECTOR_NAK_MULTICAST_MAX_BACKOFF; base_x = lambda / (AERON_LOSS_DETECTOR_NAK_MULTICAST_MAX_BACKOFF * (exp(lambda) - 1)); constant_t = AERON_LOSS_DETECTOR_NAK_MULTICAST_MAX_BACKOFF / lambda; factor_t = (exp(lambda) - 1) * constant_t; srand48(aeron_nano_clock()); initialized = true; } const double x = (drand48() * rand_max) + base_x; return (int64_t)(constant_t * log(x * factor_t)); }