store: implement serialize method, use it
For triggering saving the contacts / labels caches.
This commit is contained in:
@ -889,6 +889,7 @@ Server::Private::index_handler(const Command& cmd)
|
||||
throw Error{Error::Code::Xapian, "indexer is already running"};
|
||||
|
||||
do_index(conf);
|
||||
store().serialize();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MU_LABELS_CACHE_HH
|
||||
#define MU_LABELS_CACHE_HH
|
||||
|
||||
@ -59,6 +58,7 @@ public:
|
||||
label_map_.insert({label, 1});
|
||||
else
|
||||
++it->second;
|
||||
dirty_ = true;
|
||||
}
|
||||
/**
|
||||
* Remove a label occurrence from the cache
|
||||
@ -73,6 +73,7 @@ public:
|
||||
label_map_.erase(it);
|
||||
else
|
||||
--it->second;
|
||||
dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,13 +108,15 @@ public:
|
||||
/**
|
||||
* Serialize the cache into a string.
|
||||
*
|
||||
* Note: this also marks the cache a _non_ dirty;
|
||||
*
|
||||
* @return serialized cache
|
||||
*/
|
||||
std::string serialize() const {
|
||||
[[nodiscard]] std::string serialize() const {
|
||||
std::string s;
|
||||
for (const auto&[label, n]: label_map_)
|
||||
s += mu_format("{}{}{}\n", label, SepaChar2, n);
|
||||
|
||||
dirty_ = false;
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -140,8 +143,20 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the cache "dirty"?
|
||||
*
|
||||
* I.e. have there been changes since "serialize()" was called?
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool dirty() const {
|
||||
return dirty_;
|
||||
}
|
||||
|
||||
private:
|
||||
Map label_map_;
|
||||
mutable bool dirty_{};
|
||||
};
|
||||
|
||||
class Store;
|
||||
|
||||
@ -85,11 +85,11 @@ struct Store::Private {
|
||||
}
|
||||
|
||||
~Private() try {
|
||||
mu_debug("closing store @ {}", xapian_db_.path());
|
||||
if (!xapian_db_.read_only()) {
|
||||
contacts_cache_.serialize();
|
||||
config_.set<Config::Id::Labels>(labels_cache_.serialize());
|
||||
if (const auto res = serialize(); !res)
|
||||
mu_critical("failed to serialize: {}", res.error().what());
|
||||
}
|
||||
mu_debug("closing store @ {}", xapian_db_.path());
|
||||
} catch (...) {
|
||||
mu_critical("caught exception in store dtor");
|
||||
}
|
||||
@ -119,6 +119,8 @@ struct Store::Private {
|
||||
return Message::Options::None;
|
||||
}
|
||||
|
||||
Result<void> serialize();
|
||||
|
||||
Option<Message> find_message_unlocked(Store::Id docid) const;
|
||||
Store::IdVec find_duplicates_unlocked(const Store& store,
|
||||
const std::string& message_id) const;
|
||||
@ -145,6 +147,23 @@ struct Store::Private {
|
||||
};
|
||||
|
||||
|
||||
Result<void>
|
||||
Store::Private::serialize()
|
||||
{
|
||||
if (xapian_db_.read_only())
|
||||
return Err(Error::Code::Store, "store must be writable");
|
||||
|
||||
mu_debug("serialize data into store @ {}", xapian_db_.path());
|
||||
|
||||
contacts_cache_.serialize(); // does the 'dirty' check internally.
|
||||
|
||||
if (labels_cache_.dirty())
|
||||
config_.set<Config::Id::Labels>(labels_cache_.serialize());
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
Result<Store::Id>
|
||||
Store::Private::add_message_unlocked(Message& msg)
|
||||
{
|
||||
@ -335,6 +354,13 @@ Store::contacts_cache() const
|
||||
return priv_->contacts_cache_;
|
||||
}
|
||||
|
||||
Result<void>
|
||||
Store::serialize()
|
||||
{
|
||||
std::lock_guard guard{priv_->lock_};
|
||||
return priv_->serialize();
|
||||
}
|
||||
|
||||
Indexer&
|
||||
Store::indexer()
|
||||
{
|
||||
|
||||
@ -140,6 +140,17 @@ public:
|
||||
*/
|
||||
const ContactsCache& contacts_cache() const;
|
||||
|
||||
|
||||
/**
|
||||
* Serialize ephemeral information such as contacts, labels,
|
||||
* in the database.
|
||||
*
|
||||
* Only available when using a writable database.
|
||||
*
|
||||
* @return Ok() or some error.
|
||||
*/
|
||||
Result<void> serialize();
|
||||
|
||||
/**
|
||||
* Get the Indexer associated with this store. It is an error to call
|
||||
* this on a read-only store.
|
||||
|
||||
Reference in New Issue
Block a user