summaryrefslogtreecommitdiffstats
path: root/core/divelist.c
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-11-24 12:31:35 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-01-09 20:58:04 -0800
commit517fb7a462c207e32cc7c5ed50e1e9b1f359dbd8 (patch)
tree2ce9dd590f60743f5f565af320ea77c474c2e1c4 /core/divelist.c
parent54fcda4c32029c1afd9eb02fb0c4a5e1949da175 (diff)
downloadsubsurface-517fb7a462c207e32cc7c5ed50e1e9b1f359dbd8.tar.gz
Core: keep trips in table(s)
Currently, all trips are kept in a linked list. Replace the list by a table in analogy to dive_table. Use this to keep the trip_table sorted as suggested by dump_trip_list(). When inserting a trip into the table do that after adding the dives, to avoid warnings coming out of dump_trip_list(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/divelist.c')
-rw-r--r--core/divelist.c134
1 files changed, 67 insertions, 67 deletions
diff --git a/core/divelist.c b/core/divelist.c
index 100266eb1..fbad84981 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -3,10 +3,10 @@
/* core logic for the dive list -
* accessed through the following interfaces:
*
- * void process_loaded_dives();
- * void process_imported_dives(bool prefer_imported);
- * dive_trip_t *dive_trip_list;
- * unsigned int amount_selected;
+ * struct trip_table trip_table
+ * void process_loaded_dives()
+ * void process_imported_dives(bool prefer_imported)
+ * unsigned int amount_selected
* void dump_selection(void)
* void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2low_p)
* char *get_dive_gas_string(const struct dive *dive)
@@ -38,6 +38,7 @@
* bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b)
* bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b)
* void sort_dive_table(struct dive_table *table)
+ * void sort_trip_table(struct trip_table *table)
* bool is_trip_before_after(const struct dive *dive, bool before)
* void delete_dive_from_table(struct dive_table *table, int idx)
* int find_next_visible_dive(timestamp_t when);
@@ -69,7 +70,7 @@ static bool dive_list_changed = false;
bool autogroup = false;
-dive_trip_t *dive_trip_list;
+struct trip_table trip_table;
unsigned int amount_selected;
@@ -748,14 +749,15 @@ void dump_trip_list(void)
int i = 0;
timestamp_t last_time = 0;
- for (trip = dive_trip_list; trip; trip = trip->next) {
+ for (i = 0; i < trip_table.nr; ++i) {
struct tm tm;
+ trip = trip_table.trips[i];
utc_mkdate(trip_date(trip), &tm);
if (trip_date(trip) < last_time)
- printf("\n\ndive_trip_list OUT OF ORDER!!!\n\n\n");
+ printf("\n\ntrip_table OUT OF ORDER!!!\n\n\n");
printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n",
trip->autogen ? "autogen " : "",
- ++i, trip->location,
+ i + 1, trip->location,
tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
trip->dives.nr, trip);
last_time = trip_date(trip);
@@ -764,23 +766,6 @@ void dump_trip_list(void)
}
#endif
-/* insert the trip into the dive_trip_list */
-void insert_trip(dive_trip_t *dive_trip)
-{
- dive_trip_t **p = &dive_trip_list;
- dive_trip_t *trip;
-
- /* Walk the dive trip list looking for the right location.. */
- while ((trip = *p) != NULL && trip_less_than(trip, dive_trip))
- p = &trip->next;
-
- dive_trip->next = trip;
- *p = dive_trip;
-#ifdef DEBUG_TRIP
- dump_trip_list();
-#endif
-}
-
/* free resources associated with a trip structure */
void free_trip(dive_trip_t *trip)
{
@@ -791,32 +776,6 @@ void free_trip(dive_trip_t *trip)
}
}
-/* remove trip from the trip-list, but don't free its memory.
- * caller takes ownership of the trip. */
-void unregister_trip(dive_trip_t *trip)
-{
- dive_trip_t **p, *tmp;
-
- assert(!trip->dives.nr);
-
- /* Remove the trip from the list of trips */
- p = &dive_trip_list;
- while ((tmp = *p) != NULL) {
- if (tmp == trip) {
- *p = trip->next;
- break;
- }
- p = &tmp->next;
- }
-}
-
-static void delete_trip(dive_trip_t *trip)
-{
- unregister_trip(trip);
- free_trip(trip);
-}
-
-
timestamp_t trip_date(const struct dive_trip *trip)
{
if (!trip || trip->dives.nr == 0)
@@ -902,6 +861,18 @@ static int comp_dives(const struct dive *a, const struct dive *b)
return 0; /* this should not happen for a != b */
}
+/* Trips are compared according to the first dive in the trip. */
+static int comp_trips(const struct dive_trip *a, const struct dive_trip *b)
+{
+ /* This should never happen, nevertheless don't crash on trips
+ * with no (or worse a negative number of) dives. */
+ if (a->dives.nr <= 0)
+ return b->dives.nr <= 0 ? 0 : -1;
+ if (b->dives.nr <= 0)
+ return 1;
+ return comp_dives(a->dives.dives[0], b->dives.dives[0]);
+}
+
#define MAKE_GROW_TABLE(table_type, item_type, array_name) \
item_type *grow_##table_type(struct table_type *table) \
{ \
@@ -920,6 +891,7 @@ static int comp_dives(const struct dive *a, const struct dive *b)
}
MAKE_GROW_TABLE(dive_table, struct dive *, dives)
+static MAKE_GROW_TABLE(trip_table, struct dive_trip *, trips)
/* get the index where we want to insert an object so that everything stays
* ordered according to a comparison function() */
@@ -935,6 +907,7 @@ MAKE_GROW_TABLE(dive_table, struct dive *, dives)
}
MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than)
+static MAKE_GET_INSERTION_INDEX(trip_table, struct dive_trip *, trips, trip_less_than)
/* add object at the given index to a table. */
#define MAKE_ADD_TO(table_type, item_type, array_name) \
@@ -952,6 +925,7 @@ MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than)
}
static MAKE_ADD_TO(dive_table, struct dive *, dives)
+static MAKE_ADD_TO(trip_table, struct dive_trip *, trips)
#define MAKE_REMOVE_FROM(table_type, array_name) \
void remove_from_##table_type(struct table_type *table, int idx) \
@@ -963,6 +937,7 @@ static MAKE_ADD_TO(dive_table, struct dive *, dives)
}
static MAKE_REMOVE_FROM(dive_table, dives)
+static MAKE_REMOVE_FROM(trip_table, trips)
#define MAKE_GET_IDX(table_type, item_type, array_name) \
int get_idx_in_##table_type(const struct table_type *table, const item_type item) \
@@ -975,6 +950,7 @@ static MAKE_REMOVE_FROM(dive_table, dives)
}
static MAKE_GET_IDX(dive_table, struct dive *, dives)
+static MAKE_GET_IDX(trip_table, struct dive_trip *, trips)
#define MAKE_SORT(table_type, item_type, array_name, fun) \
static int sortfn_##table_type(const void *_a, const void *_b) \
@@ -990,6 +966,7 @@ static MAKE_GET_IDX(dive_table, struct dive *, dives)
}
MAKE_SORT(dive_table, struct dive *, dives, comp_dives)
+MAKE_SORT(trip_table, struct dive_trip *, trips, comp_trips)
/* remove a dive from the trip it's associated to, but don't delete the
* trip if this was the last dive in the trip. the caller is responsible
@@ -1010,6 +987,12 @@ struct dive_trip *unregister_dive_from_trip(struct dive *dive)
return trip;
}
+static void delete_trip(dive_trip_t *trip)
+{
+ unregister_trip(trip);
+ free_trip(trip);
+}
+
void remove_dive_from_trip(struct dive *dive)
{
struct dive_trip *trip = unregister_dive_from_trip(dive);
@@ -1036,6 +1019,16 @@ dive_trip_t *alloc_trip(void)
return calloc(1, sizeof(dive_trip_t));
}
+/* insert the trip into the trip table */
+void insert_trip(dive_trip_t *dive_trip)
+{
+ int idx = trip_table_get_insertion_index(&trip_table, dive_trip);
+ add_to_trip_table(&trip_table, idx, dive_trip);
+#ifdef DEBUG_TRIP
+ dump_trip_list();
+#endif
+}
+
dive_trip_t *create_trip_from_dive(struct dive *dive)
{
dive_trip_t *trip;
@@ -1051,12 +1044,22 @@ dive_trip_t *create_and_hookup_trip_from_dive(struct dive *dive)
dive_trip_t *dive_trip = alloc_trip();
dive_trip = create_trip_from_dive(dive);
- insert_trip(dive_trip);
add_dive_to_trip(dive, dive_trip);
+ insert_trip(dive_trip);
return dive_trip;
}
+/* remove trip from the trip-list, but don't free its memory.
+ * caller takes ownership of the trip. */
+void unregister_trip(dive_trip_t *trip)
+{
+ int idx = get_idx_in_trip_table(&trip_table, trip);
+ assert(!trip->dives.nr);
+ if (idx >= 0)
+ remove_from_trip_table(&trip_table, idx);
+}
+
/*
* Find a trip a new dive should be autogrouped with. If no such trips
* exist, allocate a new trip. The bool "*allocated" is set to true
@@ -1153,7 +1156,7 @@ dive_trip_t *get_dives_to_autogroup(struct dive_table *table, int start, int *fr
}
/*
- * Walk the dives from the oldest dive in the given tabe, and see if we
+ * Walk the dives from the oldest dive in the given table, and see if we
* can autogroup them. But only do this when the user selected autogrouping.
*/
static void autogroup_dives(struct dive_table *table)
@@ -1167,12 +1170,13 @@ static void autogroup_dives(struct dive_table *table)
return;
for (i = 0; (trip = get_dives_to_autogroup(&dive_table, i, &from, &to, &alloc)) != NULL; i = to) {
+ for (j = from; j < to; ++j)
+ add_dive_to_trip(get_dive(j), trip);
/* If this was newly allocated, add trip to list */
if (alloc)
insert_trip(trip);
- for (j = from; j < to; ++j)
- add_dive_to_trip(get_dive(j), trip);
}
+ sort_trip_table(&trip_table);
#ifdef DEBUG_TRIP
dump_trip_list();
#endif
@@ -1423,6 +1427,7 @@ void process_loaded_dives()
set_dc_nickname(dive);
sort_dive_table(&dive_table);
+ sort_trip_table(&trip_table);
/* Autogroup dives if desired by user. */
autogroup_dives(&dive_table);
@@ -1577,6 +1582,9 @@ void process_imported_dives(struct dive_table *import_table, bool prefer_importe
/* Autogroup dives if desired by user. */
autogroup_dives(&dive_table);
+ /* Trips may have changed - make sure that they are still ordered */
+ sort_trip_table(&trip_table);
+
/* We might have deleted the old selected dive.
* Choose the newest dive as selected (if any) */
current_dive = dive_table.nr > 0 ? dive_table.dives[dive_table.nr - 1] : NULL;
@@ -1660,6 +1668,10 @@ void clear_dive_file_data()
delete_single_dive(0);
while (dive_site_table.nr)
delete_dive_site(get_dive_site(0));
+ if (trip_table.nr != 0) {
+ fprintf(stderr, "Warning: trip table not empty in clear_dive_file_data()!\n");
+ trip_table.nr = 0;
+ }
clear_dive(&displayed_dive);
@@ -1682,18 +1694,6 @@ bool dive_less_than(const struct dive *a, const struct dive *b)
return comp_dives(a, b) < 0;
}
-/* Trips are compared according to the first dive in the trip. */
-static int comp_trips(const struct dive_trip *a, const struct dive_trip *b)
-{
- /* This should never happen, nevertheless don't crash on trips
- * with no (or worse a negative number of) dives. */
- if (a->dives.nr <= 0)
- return b->dives.nr <= 0 ? 0 : -1;
- if (b->dives.nr <= 0)
- return 1;
- return comp_dives(a->dives.dives[0], b->dives.dives[0]);
-}
-
bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b)
{
return comp_trips(a, b) < 0;