summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2025-09-02 22:52:51 +0300
committerDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2025-09-02 22:52:51 +0300
commite64a48a08575fb9c456f9fe5717ef42770aafbcb (patch)
tree332ee34421e0ae8eda246543b016d5e70347e425
parentda69dd6815d75e3bc046ac74f5dc04f2babb5bd3 (diff)
store: update labels when removing messages
This does make removing a bit slower...
-rw-r--r--lib/mu-store.cc58
1 files changed, 43 insertions, 15 deletions
diff --git a/lib/mu-store.cc b/lib/mu-store.cc
index e5ba902..b7608a4 100644
--- a/lib/mu-store.cc
+++ b/lib/mu-store.cc
@@ -118,6 +118,10 @@ struct Store::Private {
Result<void> serialize();
Option<Message> find_message_unlocked(Store::Id docid) const;
+
+ using IdDocument = std::pair<Store::Id, Xapian::Document>;
+ Option<IdDocument> find_document_unlocked(const std::string& path) const;
+
Store::IdVec find_duplicates_unlocked(const Store& store,
const std::string& message_id) const;
@@ -198,6 +202,23 @@ Store::Private::find_message_unlocked(Store::Id docid) const
return Some(std::move(*msg));
}
+
+Option<Store::Private::IdDocument>
+Store::Private::find_document_unlocked(const std::string& path) const
+{
+ constexpr auto path_field{field_from_id(Field::Id::Path)};
+
+ auto enq{xapian_db_.enquire()};
+ enq.set_query(Xapian::Query{path_field.xapian_term(path)});
+
+ if (auto mset{enq.get_mset(0, 1)}; mset.empty())
+ return Nothing; // message not found
+ else
+ return Some(IdDocument{*mset.begin(), mset.begin().get_document()});
+}
+
+
+
Store::IdVec
Store::Private::find_duplicates_unlocked(const Store& store,
const std::string& message_id) const
@@ -416,17 +437,24 @@ Store::add_message(const std::string& path, bool is_new)
return add_message(msg.value(), is_new);
}
-
bool
Store::remove_message(const std::string& path)
{
const auto term{field_from_id(Field::Id::Path).xapian_term(path)};
std::lock_guard guard{priv_->lock_};
+ if (const auto& id_doc = priv_->find_document_unlocked(path); !id_doc)
+ return false;
+ else {
+ const Document doc{id_doc->second};
+ for (auto&& label : doc.string_vec_value(Field::Id::Labels))
+ priv_->labels_cache_.decrease(label);
+
+ xapian_db().delete_document(term);
+ mu_debug("deleted message @ {} from store", path);
- xapian_db().delete_document(term);
- mu_debug("deleted message @ {} from store", path);
- return true;
+ return true;
+ }
}
void
@@ -436,13 +464,19 @@ Store::remove_messages(const std::vector<Store::Id>& ids)
xapian_db().request_transaction();
- for (auto&& id : ids)
- xapian_db().delete_document(id);
+ for (auto&& id : ids) {
+ if (const auto msg = priv_->find_message_unlocked(id); !msg) {
+ mu_warning("cannot find document {} for deletion", id);
+ } else {
+ for (auto&& label: msg->labels())
+ priv_->labels_cache_.decrease(label);
+ xapian_db().delete_document(id);
+ }
+ }
xapian_db().request_commit(true/*force*/);
}
-
Option<Message>
Store::find_message(Store::Id docid) const
{
@@ -454,20 +488,14 @@ Store::find_message(Store::Id docid) const
Option<Store::Id>
Store::find_message_id(const std::string& path) const
{
- constexpr auto path_field{field_from_id(Field::Id::Path)};
-
std::lock_guard guard{priv_->lock_};
- auto enq{xapian_db().enquire()};
- enq.set_query(Xapian::Query{path_field.xapian_term(path)});
-
- if (auto mset{enq.get_mset(0, 1)}; mset.empty())
+ if (const auto id_doc = priv_->find_document_unlocked(path); !id_doc)
return Nothing; // message not found
else
- return Some(*mset.begin());
+ return Some(std::move(id_doc->first));
}
-
Store::IdMessageVec
Store::find_messages(IdVec ids) const
{