diff options
-rw-r--r-- | core/divesite.c | 67 | ||||
-rw-r--r-- | core/divesite.h | 3 | ||||
-rw-r--r-- | core/save-xml.c | 2 |
3 files changed, 25 insertions, 47 deletions
diff --git a/core/divesite.c b/core/divesite.c index fe4e23808..47a4852f3 100644 --- a/core/divesite.c +++ b/core/divesite.c @@ -5,6 +5,7 @@ #include "subsurface-string.h" #include "divelist.h" #include "membuffer.h" +#include "table.h" #include <math.h> @@ -108,12 +109,26 @@ void register_dive_site(struct dive_site *ds) add_dive_site_to_table(ds, &dive_site_table); } -void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table) +static int compare_sites(const struct dive_site *a, const struct dive_site *b) +{ + return a->uuid > b->uuid ? 1 : a->uuid == b->uuid ? 0 : -1; +} + +static int site_less_than(const struct dive_site *a, const struct dive_site *b) { - int nr = ds_table->nr; - int allocated = ds_table->allocated; - struct dive_site **sites = ds_table->dive_sites; + return compare_sites(a, b) < 0; +} +static MAKE_GROW_TABLE(dive_site_table, struct dive_site *, dive_sites) +static MAKE_GET_INSERTION_INDEX(dive_site_table, struct dive_site *, dive_sites, site_less_than) +static MAKE_ADD_TO(dive_site_table, struct dive_site *, dive_sites) +static MAKE_REMOVE_FROM(dive_site_table, dive_sites) +static MAKE_GET_IDX(dive_site_table, struct dive_site *, dive_sites) +MAKE_SORT(dive_site_table, struct dive_site *, dive_sites, compare_sites) +static MAKE_REMOVE(dive_site_table, struct dive_site *, dive_site) + +void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table) +{ /* Take care to never have the same uuid twice. This could happen on * reimport of a log where the dive sites have diverged */ while (ds->uuid == 0 || get_dive_site_by_uuid(ds->uuid, ds_table) != NULL) { @@ -123,16 +138,8 @@ void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_tab ds->uuid |= (rand() & 0xff) << 24; } - if (nr >= allocated) { - allocated = (nr + 32) * 3 / 2; - sites = realloc(sites, allocated * sizeof(struct dive_site *)); - if (!sites) - exit(1); - ds_table->dive_sites = sites; - ds_table->allocated = allocated; - } - sites[nr] = ds; - ds_table->nr = nr + 1; + int idx = dive_site_table_get_insertion_index(ds_table, ds); + add_to_dive_site_table(ds_table, idx, ds); } struct dive_site *alloc_dive_site() @@ -192,29 +199,14 @@ void free_dive_site(struct dive_site *ds) void unregister_dive_site(struct dive_site *ds) { - remove_dive_site_from_table(ds, &dive_site_table); -} - -void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table) -{ - int nr = ds_table->nr; - for (int i = 0; i < nr; i++) { - if (ds == get_dive_site(i, ds_table)) { - if (nr - 1 > i) - memmove(&ds_table->dive_sites[i], - &ds_table->dive_sites[i+1], - (nr - 1 - i) * sizeof(ds_table->dive_sites[0])); - ds_table->nr = nr - 1; - break; - } - } + remove_dive_site(ds, &dive_site_table); } void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table) { if (!ds) return; - remove_dive_site_from_table(ds, ds_table); + remove_dive_site(ds, ds_table); free_dive_site(ds); } @@ -395,16 +387,3 @@ struct dive_site *unregister_dive_from_dive_site(struct dive *d) d->dive_site = NULL; return ds; } - -/* Assign arbitrary UUIDs to dive sites. This is called by before writing the dive log to XML or git. */ -static int compare_sites(const void *_a, const void *_b) -{ - const struct dive_site *a = (const struct dive_site *)*(void **)_a; - const struct dive_site *b = (const struct dive_site *)*(void **)_b; - return a->uuid > b->uuid ? 1 : a->uuid == b->uuid ? 0 : -1; -} - -void dive_site_table_sort(struct dive_site_table *ds_table) -{ - qsort(ds_table->dive_sites, ds_table->nr, sizeof(struct dive_site *), compare_sites); -} diff --git a/core/divesite.h b/core/divesite.h index 087b5f2b7..49e6edea5 100644 --- a/core/divesite.h +++ b/core/divesite.h @@ -46,9 +46,8 @@ static inline struct dive_site *get_dive_site(int nr, struct dive_site_table *ds int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table); -void dive_site_table_sort(struct dive_site_table *ds_table); +void sort_dive_site_table(struct dive_site_table *ds_table); void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table); -void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table); void register_dive_site(struct dive_site *ds); void unregister_dive_site(struct dive_site *ds); struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table); diff --git a/core/save-xml.c b/core/save-xml.c index 93dfc7f85..cd97a6ee9 100644 --- a/core/save-xml.c +++ b/core/save-xml.c @@ -591,7 +591,7 @@ void save_dives_buffer(struct membuffer *b, const bool select_only, bool anonymi put_format(b, "</settings>\n"); /* save the dive sites - to make the output consistent let's sort the table, first */ - dive_site_table_sort(&dive_site_table); + sort_dive_site_table(&dive_site_table); purge_empty_dive_sites(&dive_site_table); put_format(b, "<divesites>\n"); for (i = 0; i < dive_site_table.nr; i++) { |