diff --git a/core/dive.cpp b/core/dive.cpp index 711640c98..e02d3fe34 100644 --- a/core/dive.cpp +++ b/core/dive.cpp @@ -49,13 +49,9 @@ dive::dive() : dcs(1) id = dive_getUniqID(); } -dive::~dive() -{ - fulltext_unregister(this); // TODO: this is a layering violation. Remove. -} - dive::dive(dive &&) = default; dive &dive::operator=(const dive &) = default; +dive::~dive() = default; /* * The legacy format for sample pressures has a single pressure @@ -180,9 +176,7 @@ void clear_dive(struct dive *d) void copy_dive(const struct dive *s, struct dive *d) { /* simply copy things over, but then clear fulltext cache and dive cache. */ - fulltext_unregister(d); *d = *s; - d->full_text = NULL; invalidate_dive_cache(d); } diff --git a/core/dive.h b/core/dive.h index d268271ef..5255bee9e 100644 --- a/core/dive.h +++ b/core/dive.h @@ -10,6 +10,7 @@ #include "picture.h" // TODO: remove #include "tag.h" +#include #include #include @@ -25,6 +26,19 @@ struct full_text_cache; struct event; struct trip_table; +/* A unique_ptr that will not be copied if the parent class is copied. + * This is used to keep a pointer to the fulltext cache and avoid + * having it copied when the dive is copied, since the new dive is + * not (yet) registered in the fulltext system. Quite hackish. + */ +template +struct non_copying_unique_ptr : public std::unique_ptr { + using std::unique_ptr::unique_ptr; + using std::unique_ptr::operator=; + non_copying_unique_ptr(const non_copying_unique_ptr &) { } + void operator=(const non_copying_unique_ptr &) { } +}; + struct dive { struct dive_trip *divetrip = nullptr; timestamp_t when = 0; @@ -55,7 +69,7 @@ struct dive { bool notrip = false; /* Don't autogroup this dive to a trip */ bool selected = false; bool hidden_by_filter = false; - struct full_text_cache *full_text = nullptr; /* word cache for full text search */ + non_copying_unique_ptr full_text; /* word cache for full text search */ bool invalid = false; dive(); diff --git a/core/fulltext.cpp b/core/fulltext.cpp index ca0e14f34..a8dd45bc1 100644 --- a/core/fulltext.cpp +++ b/core/fulltext.cpp @@ -10,11 +10,6 @@ #include #include -// This class caches each dives words, so that we can unregister a dive from the full text search -struct full_text_cache { - std::vector words; -}; - // The FullText-search class class FullText { std::map> words; // Dives that belong to each word @@ -160,7 +155,7 @@ void FullText::registerDive(struct dive *d) if (d->full_text) unregisterWords(d, d->full_text->words); else - d->full_text = new full_text_cache; + d->full_text = std::make_unique(); d->full_text->words = getWords(d); registerWords(d, d->full_text->words); } @@ -170,18 +165,15 @@ void FullText::unregisterDive(struct dive *d) if (!d->full_text) return; unregisterWords(d, d->full_text->words); - delete d->full_text; - d->full_text = nullptr; + d->full_text.reset(); } void FullText::unregisterAll() { int i; dive *d; - for_each_dive(i, d) { - delete d->full_text; - d->full_text = nullptr; - } + for_each_dive(i, d) + d->full_text.reset(); words.clear(); } diff --git a/core/fulltext.h b/core/fulltext.h index 52fb77f69..0775e5e8a 100644 --- a/core/fulltext.h +++ b/core/fulltext.h @@ -5,11 +5,6 @@ // issues such as COW semantics and UTF-16 encoding, it provides // platform independence and reasonable performance. Therefore, // this is based in QString instead of std::string. -// -// To make this accessible from C, this does manual memory management: -// Every dive is associated with a cache of words. Thus, when deleting -// a dive, a function freeing that data has to be called. -// TODO: remove this complexity. #ifndef FULLTEXT_H #define FULLTEXT_H @@ -17,7 +12,6 @@ #include #include -struct full_text_cache; struct dive; void fulltext_register(struct dive *d); // Note: can be called repeatedly void fulltext_unregister(struct dive *d); // Note: can be called repeatedly @@ -30,6 +24,11 @@ enum class StringFilterMode { EXACT = 2 }; +// This class caches each dives words, so that we can unregister a dive from the full text search +struct full_text_cache { + std::vector words; +}; + // A fulltext query. Basically a list of normalized words we search for struct FullTextQuery { std::vector words;