Pass more specific structures to pv_calculate_transfer_rate rather than the whole state (#165).
This commit is contained in:
@@ -490,7 +490,7 @@ typedef struct pvwatchfd_s *pvwatchfd_t;
|
||||
void pv_error(pvstate_t, char *, ...);
|
||||
|
||||
int pv_main_loop(pvstate_t);
|
||||
void pv_calculate_transfer_rate(pvstate_t, bool);
|
||||
void pv_calculate_transfer_rate(pvtransfercalc_t, pvtransferstate_t, pvcontrol_t, pvdisplay_t, bool);
|
||||
|
||||
long pv_bound_long(long, long, long);
|
||||
long pv_seconds_remaining(const off_t, const off_t, const long double);
|
||||
|
||||
+68
-61
@@ -17,23 +17,24 @@
|
||||
* rate, otherwise calulate the average rate from the difference between the
|
||||
* current position + elapsed time pair, and the oldest pair in the buffer.
|
||||
*/
|
||||
static void pv__update_average_rate_history(pvstate_t state, long double rate)
|
||||
static void pv__update_average_rate_history(pvtransfercalc_t calc, pvtransferstate_t transfer,
|
||||
unsigned int history_interval, long double rate)
|
||||
{
|
||||
size_t first = state->calc.history_first;
|
||||
size_t last = state->calc.history_last;
|
||||
size_t first = calc->history_first;
|
||||
size_t last = calc->history_last;
|
||||
long double last_elapsed;
|
||||
|
||||
if (NULL == state->calc.history)
|
||||
if (NULL == calc->history)
|
||||
return;
|
||||
|
||||
last_elapsed = state->calc.history[last].elapsed_sec;
|
||||
last_elapsed = calc->history[last].elapsed_sec;
|
||||
|
||||
/*
|
||||
* Do nothing if this is not the first call but not enough time has
|
||||
* elapsed since the previous call yet.
|
||||
*/
|
||||
if ((last_elapsed > 0.0)
|
||||
&& (state->transfer.elapsed_seconds < (last_elapsed + state->control.history_interval)))
|
||||
&& (transfer->elapsed_seconds < (last_elapsed + history_interval)))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -41,53 +42,59 @@ static void pv__update_average_rate_history(pvstate_t state, long double rate)
|
||||
* buffer.
|
||||
*/
|
||||
if (last_elapsed > 0.0) {
|
||||
size_t len = state->calc.history_len;
|
||||
size_t len = calc->history_len;
|
||||
last = (last + 1) % len;
|
||||
state->calc.history_last = last;
|
||||
calc->history_last = last;
|
||||
if (last == first) {
|
||||
first = (first + 1) % len;
|
||||
state->calc.history_first = first;
|
||||
calc->history_first = first;
|
||||
}
|
||||
}
|
||||
|
||||
state->calc.history[last].elapsed_sec = state->transfer.elapsed_seconds;
|
||||
state->calc.history[last].transferred = state->transfer.transferred;
|
||||
calc->history[last].elapsed_sec = transfer->elapsed_seconds;
|
||||
calc->history[last].transferred = transfer->transferred;
|
||||
|
||||
if (first == last) {
|
||||
state->calc.current_avg_rate = rate;
|
||||
calc->current_avg_rate = rate;
|
||||
} else {
|
||||
off_t bytes = (state->calc.history[last].transferred - state->calc.history[first].transferred);
|
||||
long double sec = (state->calc.history[last].elapsed_sec - state->calc.history[first].elapsed_sec);
|
||||
state->calc.current_avg_rate = (long double) bytes / sec;
|
||||
off_t bytes = (calc->history[last].transferred - calc->history[first].transferred);
|
||||
long double sec = (calc->history[last].elapsed_sec - calc->history[first].elapsed_sec);
|
||||
calc->current_avg_rate = (long double) bytes / sec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update all calculated transfer state (state->calc).
|
||||
* Update all calculated transfer state (usually state->calc).
|
||||
*
|
||||
* If "final" is true, this is the final update, so
|
||||
* state->calc.transfer_rate and state->calc.average_rate are given as an
|
||||
* average over the whole transfer; otherwise they are the current transfer
|
||||
* rate and current average rate.
|
||||
* If "final" is true, this is the final update, so calc->transfer_rate and
|
||||
* calc->average_rate are given as an average over the whole transfer;
|
||||
* otherwise they are the current transfer rate and current average rate.
|
||||
*
|
||||
* The value of state->calc.percentage will reflect the percentage
|
||||
* completion if state->control.size is greater than zero, otherwise it will
|
||||
* increase by 2 each call and wrap at 200.
|
||||
* The value of calc->percentage will reflect the percentage completion if
|
||||
* control->size is greater than zero, otherwise it will increase by 2 each
|
||||
* call and wrap at 200.
|
||||
*/
|
||||
void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
void pv_calculate_transfer_rate(pvtransfercalc_t calc, pvtransferstate_t transfer, pvcontrol_t control,
|
||||
pvdisplay_t display, bool final)
|
||||
{
|
||||
off_t bytes_since_last;
|
||||
long double time_since_last, transfer_rate, average_rate;
|
||||
|
||||
/* Quick safety check - state must exist. */
|
||||
if (NULL == state)
|
||||
/* Quick safety checks for null pointers. */
|
||||
if (NULL == calc)
|
||||
return;
|
||||
if (NULL == transfer)
|
||||
return;
|
||||
if (NULL == control)
|
||||
return;
|
||||
if (NULL == display)
|
||||
return;
|
||||
|
||||
bytes_since_last = 0;
|
||||
if (state->transfer.transferred >= 0) {
|
||||
bytes_since_last = state->transfer.transferred - state->calc.prev_transferred;
|
||||
state->calc.prev_transferred = state->transfer.transferred;
|
||||
if (transfer->transferred >= 0) {
|
||||
bytes_since_last = transfer->transferred - calc->prev_transferred;
|
||||
calc->prev_transferred = transfer->transferred;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -96,37 +103,37 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
* adding to that until a reasonable amount of time has passed to
|
||||
* avoid rate spikes or division by zero.
|
||||
*/
|
||||
time_since_last = state->transfer.elapsed_seconds - state->calc.prev_elapsed_sec;
|
||||
time_since_last = transfer->elapsed_seconds - calc->prev_elapsed_sec;
|
||||
if (time_since_last <= 0.01) {
|
||||
transfer_rate = state->calc.prev_rate;
|
||||
state->calc.prev_trans += bytes_since_last;
|
||||
transfer_rate = calc->prev_rate;
|
||||
calc->prev_trans += bytes_since_last;
|
||||
} else {
|
||||
long double measured_rate;
|
||||
|
||||
transfer_rate = ((long double) bytes_since_last + state->calc.prev_trans) / time_since_last;
|
||||
transfer_rate = ((long double) bytes_since_last + calc->prev_trans) / time_since_last;
|
||||
measured_rate = transfer_rate;
|
||||
|
||||
state->calc.prev_elapsed_sec = state->transfer.elapsed_seconds;
|
||||
state->calc.prev_trans = 0;
|
||||
calc->prev_elapsed_sec = transfer->elapsed_seconds;
|
||||
calc->prev_trans = 0;
|
||||
|
||||
if (state->control.bits)
|
||||
if (control->bits)
|
||||
measured_rate = 8.0 * measured_rate;
|
||||
|
||||
if ((state->calc.measurements_taken < 1) || (measured_rate < state->calc.rate_min)) {
|
||||
state->calc.rate_min = measured_rate;
|
||||
if ((calc->measurements_taken < 1) || (measured_rate < calc->rate_min)) {
|
||||
calc->rate_min = measured_rate;
|
||||
}
|
||||
if (measured_rate > state->calc.rate_max) {
|
||||
state->calc.rate_max = measured_rate;
|
||||
if (measured_rate > calc->rate_max) {
|
||||
calc->rate_max = measured_rate;
|
||||
}
|
||||
state->calc.rate_sum += measured_rate;
|
||||
state->calc.ratesquared_sum += (measured_rate * measured_rate);
|
||||
state->calc.measurements_taken++;
|
||||
calc->rate_sum += measured_rate;
|
||||
calc->ratesquared_sum += (measured_rate * measured_rate);
|
||||
calc->measurements_taken++;
|
||||
}
|
||||
state->calc.prev_rate = transfer_rate;
|
||||
calc->prev_rate = transfer_rate;
|
||||
|
||||
/* Update history and current average rate for ETA. */
|
||||
pv__update_average_rate_history(state, transfer_rate);
|
||||
average_rate = state->calc.current_avg_rate;
|
||||
pv__update_average_rate_history(calc, transfer, control->history_interval, transfer_rate);
|
||||
average_rate = calc->current_avg_rate;
|
||||
|
||||
/*
|
||||
* If this is the final update at the end of the transfer, we
|
||||
@@ -135,18 +142,18 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
*/
|
||||
if (final) {
|
||||
/* Safety check to avoid division by zero. */
|
||||
if (state->transfer.elapsed_seconds < 0.000001)
|
||||
state->transfer.elapsed_seconds = 0.000001;
|
||||
if (transfer->elapsed_seconds < 0.000001)
|
||||
transfer->elapsed_seconds = 0.000001;
|
||||
average_rate =
|
||||
(((long double) (state->transfer.transferred)) -
|
||||
((long double) state->display.initial_offset)) / (long double) (state->transfer.elapsed_seconds);
|
||||
(((long double) (transfer->transferred)) -
|
||||
((long double) display->initial_offset)) / (long double) (transfer->elapsed_seconds);
|
||||
transfer_rate = average_rate;
|
||||
}
|
||||
|
||||
state->calc.transfer_rate = transfer_rate;
|
||||
state->calc.average_rate = average_rate;
|
||||
calc->transfer_rate = transfer_rate;
|
||||
calc->average_rate = average_rate;
|
||||
|
||||
if (state->control.size <= 0) {
|
||||
if (control->size <= 0) {
|
||||
/*
|
||||
* If we don't know the total size of the incoming data,
|
||||
* then for a percentage, we gradually increase the
|
||||
@@ -156,16 +163,16 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
* 0%-100%, 100%-0%, 0%-100%, and so on.
|
||||
*/
|
||||
if (transfer_rate > 0)
|
||||
state->calc.percentage += 2;
|
||||
if (state->calc.percentage > 199)
|
||||
state->calc.percentage = 0;
|
||||
calc->percentage += 2;
|
||||
if (calc->percentage > 199)
|
||||
calc->percentage = 0;
|
||||
} else {
|
||||
state->calc.percentage = pv_percentage(state->transfer.transferred, state->control.size);
|
||||
calc->percentage = pv_percentage(transfer->transferred, control->size);
|
||||
}
|
||||
|
||||
/* Ensure the percentage is never negative or huge. */
|
||||
if (state->calc.percentage < 0.0)
|
||||
state->calc.percentage = 0.0;
|
||||
if (state->calc.percentage > 100000.0)
|
||||
state->calc.percentage = 100000.0;
|
||||
if (calc->percentage < 0.0)
|
||||
calc->percentage = 0.0;
|
||||
if (calc->percentage > 100000.0)
|
||||
calc->percentage = 100000.0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1194,7 +1194,7 @@ void pv_display(pvstate_t state, bool final)
|
||||
|
||||
pv_sig_checkbg();
|
||||
|
||||
pv_calculate_transfer_rate(state, final);
|
||||
pv_calculate_transfer_rate(&(state->calc), &(state->transfer), &(state->control), &(state->display), final);
|
||||
|
||||
/*
|
||||
* Enable colour on the main display, and disable it on the extra
|
||||
|
||||
+2
-1
@@ -506,7 +506,8 @@ int pv_main_loop(pvstate_t state)
|
||||
|
||||
if (state->control.no_display) {
|
||||
/* If there's no display, calculate rate for the statistics. */
|
||||
pv_calculate_transfer_rate(state, final_update);
|
||||
pv_calculate_transfer_rate(&(state->calc), &(state->transfer), &(state->control),
|
||||
&(state->display), final_update);
|
||||
} else {
|
||||
/* Produce the display. */
|
||||
pv_display(state, final_update);
|
||||
|
||||
Reference in New Issue
Block a user