diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-22 16:57:07 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-01-22 20:15:06 -0800 |
commit | acd6dff4a8ed7d309e81acb86ee8e1d46bf2767e (patch) | |
tree | a8dae67bd777ff2ab64c3072885bc9fd9b7bdc35 | |
parent | 20ad07d4ac82dbef90b3184a5eed9eec3cb8775f (diff) | |
download | subsurface-acd6dff4a8ed7d309e81acb86ee8e1d46bf2767e.tar.gz |
Improve on the "prefer downloaded" dive computer model
It used to be that when you checked the "Prefer downloaded" checkmark,
we'd throw away *any* old dive computer data. That was good, because it
allowed us to start from a clean slate when you had some old subsurface
data with questionable dive computer data.
However, it was a bit extreme, and it's really not what you want if you
already have (good) dive computer data from other dive computers.
So this modifies the logic a bit. Instead of throwing away all old dive
computer data, the "Prefer downloaded" checkmark now means:
- the newly downloaded data becomes the "primary" dive computer data
(ie the first in the list)
- if there was old dive computer data that *could* have been from this
new dive computer (ie it didn't have model information, or it had a
matching model but no device ID data), we throw that away
- but any existing dive computer data from other dive computers is left.
This seems to be much closer to what we really would want for a new
"preferred" download.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | dive.c | 60 |
1 files changed, 32 insertions, 28 deletions
@@ -1323,7 +1323,24 @@ static int same_dc(struct divecomputer *a, struct divecomputer *b) return eva == evb; } -static void remove_redundant_dc(struct divecomputer *dc) +static int might_be_same_device(struct divecomputer *a, struct divecomputer *b) +{ + /* No dive computer model? That matches anything */ + if (!a->model || !b->model) + return 1; + + /* Otherwise at least the model names have to match */ + if (strcasecmp(a->model, b->model)) + return 0; + + /* No device ID? Match */ + if (!a->deviceid || !b->deviceid) + return 1; + + return a->deviceid == b->deviceid; +} + +static void remove_redundant_dc(struct divecomputer *dc, int prefer_downloaded) { do { struct divecomputer **p = &dc->next; @@ -1331,7 +1348,7 @@ static void remove_redundant_dc(struct divecomputer *dc) /* Check this dc against all the following ones.. */ while (*p) { struct divecomputer *check = *p; - if (same_dc(dc, check)) { + if (same_dc(dc, check) || (prefer_downloaded && might_be_same_device(dc, check))) { *p = check->next; check->next = NULL; free_dc(check); @@ -1340,7 +1357,8 @@ static void remove_redundant_dc(struct divecomputer *dc) p = &check->next; } - /* .. and then continue down the chain */ + /* .. and then continue down the chain, but we */ + prefer_downloaded = 0; dc = dc->next; } while (dc); } @@ -1357,19 +1375,7 @@ static struct divecomputer *find_matching_computer(struct divecomputer *match, s while ((p = list) != NULL) { list = list->next; - /* No dive computer model? That matches anything */ - if (!match->model || !p->model) - break; - - /* Otherwise at least the model names have to match */ - if (strcasecmp(match->model, p->model)) - continue; - - /* No device ID? Match */ - if (!match->deviceid || !p->deviceid) - break; - - if (match->deviceid == p->deviceid) + if (might_be_same_device(match, p)) break; } return p; @@ -1422,9 +1428,13 @@ static void interleave_dive_computers(struct divecomputer *res, * name etc), we will prefer a new-style one and just throw * away the old. We're assuming it's a re-download. * - * Otherwise, we'll just try to keep all the information. + * Otherwise, we'll just try to keep all the information, + * unless the user has specified that they prefer the + * downloaded computer, in which case we'll aggressively + * try to throw out old information that *might* be from + * that one. */ -static void join_dive_computers(struct divecomputer *res, struct divecomputer *a, struct divecomputer *b) +static void join_dive_computers(struct divecomputer *res, struct divecomputer *a, struct divecomputer *b, int prefer_downloaded) { struct divecomputer *tmp; @@ -1449,7 +1459,7 @@ static void join_dive_computers(struct divecomputer *res, struct divecomputer *a *tmp->next = *b; clear_dc(b); - remove_redundant_dc(res); + remove_redundant_dc(res, prefer_downloaded); } struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded) @@ -1490,18 +1500,12 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr MERGE_MIN_PREFDL(res, dl, a, b, watertemp.mkelvin); merge_equipment(res, a, b); if (dl) { - res->dc = dl->dc; - /* - * Since we copied the events and samples, - * we can't free them from the source when - * we free it - so make sure the source - * dive computer data is cleared out. - */ - clear_dc(&dl->dc); + /* If we prefer downloaded, do those first, and get rid of "might be same" computers */ + join_dive_computers(&res->dc, &dl->dc, &a->dc, 1); } else if (offset) interleave_dive_computers(&res->dc, &a->dc, &b->dc, offset); else - join_dive_computers(&res->dc, &a->dc, &b->dc); + join_dive_computers(&res->dc, &a->dc, &b->dc, 0); fixup_dive(res); return res; |