store: update labels when removing messages

This does make removing a bit slower...
This commit is contained in:
Dirk-Jan C. Binnema
2025-09-02 22:52:51 +03:00
committed by Seth Ladygo
parent 3a12c69b10
commit 33ab0acc8d

View File

@ -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);
return true;
}
}
void
@ -436,13 +464,19 @@ Store::remove_messages(const std::vector<Store::Id>& ids)
xapian_db().request_transaction();
for (auto&& id : ids)
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
{