summaryrefslogtreecommitdiffstats
path: root/dive.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-12-16 10:55:58 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-12-16 15:46:54 -1000
commit73defa9a52e9c22fa6c87b6c2ff779da213efd1a (patch)
treee0b0cef64e7fed5a0e7a0ffd5b2c51901f39743e /dive.c
parent92c15238b6043c927a1f8bc8fd541086e1d5f306 (diff)
downloadsubsurface-73defa9a52e9c22fa6c87b6c2ff779da213efd1a.tar.gz
Use dive computer model/ID when trying to merge dives
If we havd divecomputer model and dive ID information available, use that to match existing dives when trying to merge them. Otherwise fall back to the fuzzy time-based merging logic. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'dive.c')
-rw-r--r--dive.c76
1 files changed, 64 insertions, 12 deletions
diff --git a/dive.c b/dive.c
index fce6b1a35..2a5b17580 100644
--- a/dive.c
+++ b/dive.c
@@ -1110,19 +1110,64 @@ static int similar(unsigned long a, unsigned long b, unsigned long expected)
return 0;
}
-static int same_dive_computer(struct dive *a, struct dive *b)
+/*
+ * Match two dive computer entries against each other, and
+ * tell if it's the same dive. Return 0 if "don't know",
+ * positive for "same dive" and negative for "definitely
+ * not the same dive"
+ */
+int match_one_dc(struct divecomputer *a, struct divecomputer *b)
{
- /* No model info in one or the other? Assume they're the same */
- if (!a->dc.model || !b->dc.model)
- return 1;
- if (strcasecmp(a->dc.model, b->dc.model))
+ /* Not same model? Don't know if matching.. */
+ if (!a->model || !b->model)
+ return 0;
+ if (strcasecmp(a->model, b->model))
return 0;
- /* No device ID? Assume same.. */
- if (!a->dc.deviceid || !b->dc.deviceid)
- return 1;
+
+ /* Different device ID's? Don't know */
+ if (a->deviceid != b->deviceid)
+ return 0;
+
+ /* Do we have dive IDs? */
+ if (!a->diveid || !b->diveid)
+ return 0;
+
+ /*
+ * If they have different dive ID's on the same
+ * dive computer, that's a definite "same or not"
+ */
+ return a->diveid == b->diveid ? 1 : -1;
+}
+
+/*
+ * Match every dive computer against each other to see if
+ * we have a matching dive.
+ *
+ * Return values:
+ * -1 for "is definitely *NOT* the same dive"
+ * 0 for "don't know"
+ * 1 for "is definitely the same dive"
+ */
+static int match_dc_dive(struct divecomputer *a, struct divecomputer *b)
+{
+ do {
+ struct divecomputer *tmp = b;
+ do {
+ int match = match_one_dc(a, tmp);
+ if (match)
+ return match;
+ tmp = tmp->next;
+ } while (tmp);
+ a = a->next;
+ } while (a);
return 0;
}
+static int max_time(duration_t a, duration_t b)
+{
+ return a.seconds > b.seconds ? a.seconds : b.seconds;
+}
+
/*
* Do we want to automatically try to merge two dives that
* look like they are the same dive?
@@ -1154,7 +1199,7 @@ static int same_dive_computer(struct dive *a, struct dive *b)
*/
static int likely_same_dive(struct dive *a, struct dive *b)
{
- int fuzz;
+ int fuzz, match;
/*
* Do some basic sanity testing of the values we
@@ -1165,11 +1210,18 @@ static int likely_same_dive(struct dive *a, struct dive *b)
!similar(a->duration.seconds, b->duration.seconds, 5*60))
return 0;
+ /* See if we can get an exact match on the dive computer */
+ match = match_dc_dive(&a->dc, &b->dc);
+ if (match)
+ return match > 0;
+
/*
- * Allow a minute difference by default (minute rounding etc),
- * and more if the dive computers are clearly different.
+ * Allow a time difference due to dive computer time
+ * setting etc. Check if they overlap.
*/
- fuzz = same_dive_computer(a, b) ? 60 : 5*60;
+ fuzz = max_time(a->duration, b->duration) / 2;
+ if (fuzz < 60)
+ fuzz = 60;
return ((a->when <= b->when + fuzz) && (a->when >= b->when - fuzz));
}