summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--dive.c76
-rw-r--r--dive.h3
2 files changed, 67 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));
}
diff --git a/dive.h b/dive.h
index d504790ae..3d8fa6add 100644
--- a/dive.h
+++ b/dive.h
@@ -448,6 +448,9 @@ static inline struct dive *get_dive_by_diveid(int diveid, int deviceid)
return NULL;
}
+/* Check if two dive computer entries are the exact same dive (-1=no/0=maybe/1=yes) */
+extern int match_one_dc(struct divecomputer *a, struct divecomputer *b);
+
/*
* Iterate over each dive, with the first parameter being the index
* iterator variable, and the second one being the dive one.