store: update labels when removing messages
This does make removing a bit slower...
This commit is contained in:
@ -118,6 +118,10 @@ struct Store::Private {
|
|||||||
Result<void> serialize();
|
Result<void> serialize();
|
||||||
|
|
||||||
Option<Message> find_message_unlocked(Store::Id docid) const;
|
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,
|
Store::IdVec find_duplicates_unlocked(const Store& store,
|
||||||
const std::string& message_id) const;
|
const std::string& message_id) const;
|
||||||
|
|
||||||
@ -198,6 +202,23 @@ Store::Private::find_message_unlocked(Store::Id docid) const
|
|||||||
return Some(std::move(*msg));
|
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::IdVec
|
||||||
Store::Private::find_duplicates_unlocked(const Store& store,
|
Store::Private::find_duplicates_unlocked(const Store& store,
|
||||||
const std::string& message_id) const
|
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);
|
return add_message(msg.value(), is_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Store::remove_message(const std::string& path)
|
Store::remove_message(const std::string& path)
|
||||||
{
|
{
|
||||||
const auto term{field_from_id(Field::Id::Path).xapian_term(path)};
|
const auto term{field_from_id(Field::Id::Path).xapian_term(path)};
|
||||||
|
|
||||||
std::lock_guard guard{priv_->lock_};
|
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);
|
xapian_db().delete_document(term);
|
||||||
mu_debug("deleted message @ {} from store", path);
|
mu_debug("deleted message @ {} from store", path);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -436,13 +464,19 @@ Store::remove_messages(const std::vector<Store::Id>& ids)
|
|||||||
|
|
||||||
xapian_db().request_transaction();
|
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().delete_document(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xapian_db().request_commit(true/*force*/);
|
xapian_db().request_commit(true/*force*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Option<Message>
|
Option<Message>
|
||||||
Store::find_message(Store::Id docid) const
|
Store::find_message(Store::Id docid) const
|
||||||
{
|
{
|
||||||
@ -454,20 +488,14 @@ Store::find_message(Store::Id docid) const
|
|||||||
Option<Store::Id>
|
Option<Store::Id>
|
||||||
Store::find_message_id(const std::string& path) const
|
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_};
|
std::lock_guard guard{priv_->lock_};
|
||||||
|
|
||||||
auto enq{xapian_db().enquire()};
|
if (const auto id_doc = priv_->find_document_unlocked(path); !id_doc)
|
||||||
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
|
return Nothing; // message not found
|
||||||
else
|
else
|
||||||
return Some(*mset.begin());
|
return Some(std::move(id_doc->first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Store::IdMessageVec
|
Store::IdMessageVec
|
||||||
Store::find_messages(IdVec ids) const
|
Store::find_messages(IdVec ids) const
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user