pressure interpolation: incrementally update interpolation data

Instead of re-calculating all the interpolation data for each plot entry
(which means that we have a quadratic algorithm that walks over all the
plot-info points for each plot-info point), we can just update it
incrementally within any particular interpolation segment.

The previous cleanups made the code sane enough to understand, and makes
it trivial to see how you don't have to recalculate the full thing.

This gets rid of the O(n**2) algorithm, and it instead becomes O(n*m)
where 'n' is the number of plot entries, and 'm' is the number of gas
segments (which is usually a much smaller numer, typically "1").

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Linus Torvalds 2016-02-21 15:34:04 -08:00 committed by Dirk Hohndel
parent b71fc7ffb2
commit 10ae00db3c

View file

@ -200,6 +200,8 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
{
int cyl, i;
struct plot_data *entry;
pr_interpolate_t interpolate = { 0 };
pr_track_t *last_segment = NULL;
int cur_pr[MAX_CYLINDERS]; // cur_pr[MAX_CYLINDERS] is the CCR diluent cylinder
for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
@ -235,7 +237,6 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
for (i = 1; i < pi->nr; i++) { // For each point on the profile:
double magic;
pr_track_t *segment;
pr_interpolate_t interpolate;
int pressure;
int *save_pressure, *save_interpolated;
@ -257,6 +258,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
}
if (pressure) { // If there is a valid pressure value,
last_segment = NULL; // get rid of interpolation data,
cur_pr[cyl] = pressure; // set current pressure
continue; // and skip to next point.
}
@ -272,7 +274,14 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
}
// If there is a valid segment but no tank pressure ..
interpolate = get_pr_interpolate_data(segment, pi, i); // Set up an interpolation structure
if (segment == last_segment) {
interpolate.acc_pressure_time += entry->pressure_time;
} else {
// Set up an interpolation structure
interpolate = get_pr_interpolate_data(segment, pi, i);
last_segment = segment;
}
if(dive->cylinder[cyl].cylinder_use == OC_GAS) {
/* if this segment has pressure_time, then calculate a new interpolated pressure */