fulltext: replace plain pointer by std::unique_ptr<>

This was a plain pointer owing to C compatibility.

Replacing it by a unique_ptr<> allows us to make it
'self-desctruct' in the constructor. However, we do this
with a special twist: the data is _not_ copied when copying
the dive, since the copied dive is not registered in the fulltext
system. Hackish, but it should(!) work.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-06-03 19:09:43 +02:00 committed by bstoeger
parent 5c7cfb1057
commit c9d4ce0c15
4 changed files with 25 additions and 26 deletions

View file

@ -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);
}

View file

@ -10,6 +10,7 @@
#include "picture.h" // TODO: remove
#include "tag.h"
#include <memory>
#include <string>
#include <vector>
@ -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<typename T>
struct non_copying_unique_ptr : public std::unique_ptr<T> {
using std::unique_ptr<T>::unique_ptr;
using std::unique_ptr<T>::operator=;
non_copying_unique_ptr(const non_copying_unique_ptr<T> &) { }
void operator=(const non_copying_unique_ptr<T> &) { }
};
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_cache> full_text; /* word cache for full text search */
bool invalid = false;
dive();

View file

@ -10,11 +10,6 @@
#include <QLocale>
#include <map>
// This class caches each dives words, so that we can unregister a dive from the full text search
struct full_text_cache {
std::vector<QString> words;
};
// The FullText-search class
class FullText {
std::map<QString, std::vector<dive *>> 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<full_text_cache>();
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();
}

View file

@ -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 <QString>
#include <vector>
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<QString> words;
};
// A fulltext query. Basically a list of normalized words we search for
struct FullTextQuery {
std::vector<QString> words;