mirror of https://github.com/djcb/mu.git
lib/contacts-cache: rework using config
Use the new config class to pass information and serialization.
This commit is contained in:
parent
3791d0c375
commit
2acc1c2271
|
@ -46,23 +46,28 @@ struct EmailEqual {
|
||||||
|
|
||||||
using ContactUMap = std::unordered_map<const std::string, Contact, EmailHash, EmailEqual>;
|
using ContactUMap = std::unordered_map<const std::string, Contact, EmailHash, EmailEqual>;
|
||||||
struct ContactsCache::Private {
|
struct ContactsCache::Private {
|
||||||
Private(const std::string& serialized, const StringVec& personal)
|
Private(Config& config_db)
|
||||||
: contacts_{deserialize(serialized)},
|
:config_db_{config_db},
|
||||||
personal_plain_{make_personal_plain(personal)},
|
contacts_{deserialize(config_db_.get<Config::Id::Contacts>())},
|
||||||
personal_rx_{make_personal_rx(personal)},
|
personal_plain_{make_personal_plain(config_db_.get<Config::Id::PersonalAddresses>())},
|
||||||
dirty_{0}
|
personal_rx_{make_personal_rx(config_db_.get<Config::Id::PersonalAddresses>())},
|
||||||
{}
|
dirty_{0}
|
||||||
|
{}
|
||||||
|
|
||||||
|
~Private() {
|
||||||
|
serialize();
|
||||||
|
}
|
||||||
|
|
||||||
ContactUMap deserialize(const std::string&) const;
|
ContactUMap deserialize(const std::string&) const;
|
||||||
std::string serialize() const;
|
void serialize() const;
|
||||||
|
|
||||||
ContactUMap contacts_;
|
Config& config_db_;
|
||||||
std::mutex mtx_;
|
ContactUMap contacts_;
|
||||||
|
mutable std::mutex mtx_;
|
||||||
|
|
||||||
const StringVec personal_plain_;
|
const StringVec personal_plain_;
|
||||||
const std::vector<Regex> personal_rx_;
|
const std::vector<Regex> personal_rx_;
|
||||||
|
mutable size_t dirty_;
|
||||||
size_t dirty_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -140,19 +145,23 @@ ContactsCache::Private::deserialize(const std::string& serialized) const
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactsCache::ContactsCache(const std::string& serialized, const StringVec& personal)
|
|
||||||
: priv_{std::make_unique<Private>(serialized, personal)}
|
|
||||||
{}
|
|
||||||
|
|
||||||
ContactsCache::~ContactsCache() = default;
|
void
|
||||||
|
ContactsCache::Private::serialize() const
|
||||||
std::string
|
|
||||||
ContactsCache::serialize() const
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l_{priv_->mtx_};
|
if (config_db_.read_only()) {
|
||||||
std::string s;
|
if (dirty_ > 0)
|
||||||
|
g_critical("dirty data in read-only ccache!"); // bug
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& item : priv_->contacts_) {
|
std::string s;
|
||||||
|
std::unique_lock lock(mtx_);
|
||||||
|
|
||||||
|
if (dirty_ == 0)
|
||||||
|
return; // nothing to do.
|
||||||
|
|
||||||
|
for (auto& item : contacts_) {
|
||||||
const auto& ci{item.second};
|
const auto& ci{item.second};
|
||||||
s += Mu::format("%s%s"
|
s += Mu::format("%s%s"
|
||||||
"%s%s"
|
"%s%s"
|
||||||
|
@ -169,16 +178,25 @@ ContactsCache::serialize() const
|
||||||
Separator,
|
Separator,
|
||||||
(gint64)ci.frequency);
|
(gint64)ci.frequency);
|
||||||
}
|
}
|
||||||
|
config_db_.set<Config::Id::Contacts>(s);
|
||||||
priv_->dirty_ = 0;
|
dirty_ = 0;
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ContactsCache::dirty() const
|
|
||||||
|
ContactsCache::ContactsCache(Config& config_db)
|
||||||
|
: priv_{std::make_unique<Private>(config_db)}
|
||||||
|
{}
|
||||||
|
|
||||||
|
ContactsCache::~ContactsCache() = default;
|
||||||
|
|
||||||
|
void
|
||||||
|
ContactsCache::serialize() const
|
||||||
{
|
{
|
||||||
return priv_->dirty_;
|
if (priv_->config_db_.read_only())
|
||||||
|
throw std::runtime_error("cannot serialize read-only contacts-cache");
|
||||||
|
|
||||||
|
priv_->serialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -351,7 +369,9 @@ ContactsCache::is_personal(const std::string& addr) const
|
||||||
static void
|
static void
|
||||||
test_mu_contacts_cache_base()
|
test_mu_contacts_cache_base()
|
||||||
{
|
{
|
||||||
Mu::ContactsCache contacts("");
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache contacts(cdb);
|
||||||
|
|
||||||
g_assert_true(contacts.empty());
|
g_assert_true(contacts.empty());
|
||||||
g_assert_cmpuint(contacts.size(), ==, 0);
|
g_assert_cmpuint(contacts.size(), ==, 0);
|
||||||
|
@ -395,8 +415,11 @@ test_mu_contacts_cache_base()
|
||||||
static void
|
static void
|
||||||
test_mu_contacts_cache_personal()
|
test_mu_contacts_cache_personal()
|
||||||
{
|
{
|
||||||
Mu::StringVec personal = {"foo@example.com", "bar@cuux.org", "/bar-.*@fnorb.f./"};
|
MemDb xdb{};
|
||||||
Mu::ContactsCache contacts{"", personal};
|
Config cdb{xdb};
|
||||||
|
cdb.set<Config::Id::PersonalAddresses>
|
||||||
|
(StringVec{{"foo@example.com", "bar@cuux.org", "/bar-.*@fnorb.f./"}});
|
||||||
|
ContactsCache contacts{cdb};
|
||||||
|
|
||||||
g_assert_true(contacts.is_personal("foo@example.com"));
|
g_assert_true(contacts.is_personal("foo@example.com"));
|
||||||
g_assert_true(contacts.is_personal("Bar@CuuX.orG"));
|
g_assert_true(contacts.is_personal("Bar@CuuX.orG"));
|
||||||
|
@ -413,7 +436,10 @@ test_mu_contacts_cache_personal()
|
||||||
static void
|
static void
|
||||||
test_mu_contacts_cache_foreach()
|
test_mu_contacts_cache_foreach()
|
||||||
{
|
{
|
||||||
Mu::ContactsCache ccache("");
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache ccache(cdb);
|
||||||
|
|
||||||
ccache.add(Mu::Contact{"a@example.com", "a", 123, true, 1000, 0});
|
ccache.add(Mu::Contact{"a@example.com", "a", 123, true, 1000, 0});
|
||||||
ccache.add(Mu::Contact{"b@example.com", "b", 456, true, 1000, 0});
|
ccache.add(Mu::Contact{"b@example.com", "b", 456, true, 1000, 0});
|
||||||
|
|
||||||
|
@ -468,7 +494,10 @@ test_mu_contacts_cache_sort()
|
||||||
|
|
||||||
{ /* recent messages, newer comes first */
|
{ /* recent messages, newer comes first */
|
||||||
|
|
||||||
Mu::ContactsCache ccache("");
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache ccache(cdb);
|
||||||
|
|
||||||
ccache.add(Mu::Contact{"a@example.com", "a", now, true, 1000, 0});
|
ccache.add(Mu::Contact{"a@example.com", "a", now, true, 1000, 0});
|
||||||
ccache.add(Mu::Contact{"b@example.com", "b", now-1, true, 1000, 0});
|
ccache.add(Mu::Contact{"b@example.com", "b", now-1, true, 1000, 0});
|
||||||
assert_equal(result_chars(ccache), "ab");
|
assert_equal(result_chars(ccache), "ab");
|
||||||
|
@ -476,22 +505,30 @@ test_mu_contacts_cache_sort()
|
||||||
|
|
||||||
{ /* non-recent messages, more frequent comes first */
|
{ /* non-recent messages, more frequent comes first */
|
||||||
|
|
||||||
Mu::ContactsCache ccache("");
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache ccache(cdb);
|
||||||
|
|
||||||
ccache.add(Mu::Contact{"a@example.com", "a", now-2*RecentOffset, true, 1000, 0});
|
ccache.add(Mu::Contact{"a@example.com", "a", now-2*RecentOffset, true, 1000, 0});
|
||||||
ccache.add(Mu::Contact{"b@example.com", "b", now-3*RecentOffset, true, 2000, 0});
|
ccache.add(Mu::Contact{"b@example.com", "b", now-3*RecentOffset, true, 2000, 0});
|
||||||
assert_equal(result_chars(ccache), "ba");
|
assert_equal(result_chars(ccache), "ba");
|
||||||
}
|
}
|
||||||
|
|
||||||
{ /* personal comes first */
|
{ /* personal comes first */
|
||||||
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache ccache(cdb);
|
||||||
|
|
||||||
Mu::ContactsCache ccache("");
|
|
||||||
ccache.add(Mu::Contact{"a@example.com", "a", now-5*RecentOffset, true, 1000, 0});
|
ccache.add(Mu::Contact{"a@example.com", "a", now-5*RecentOffset, true, 1000, 0});
|
||||||
ccache.add(Mu::Contact{"b@example.com", "b", now, false, 8000, 0});
|
ccache.add(Mu::Contact{"b@example.com", "b", now, false, 8000, 0});
|
||||||
assert_equal(result_chars(ccache), "ab");
|
assert_equal(result_chars(ccache), "ab");
|
||||||
}
|
}
|
||||||
|
|
||||||
{ /* if all else fails, reverse-alphabetically */
|
{ /* if all else fails, reverse-alphabetically */
|
||||||
Mu::ContactsCache ccache("");
|
MemDb xdb{};
|
||||||
|
Config cdb{xdb};
|
||||||
|
ContactsCache ccache(cdb);
|
||||||
|
|
||||||
ccache.add(Mu::Contact{"a@example.com", "a", now, false, 1000, 0});
|
ccache.add(Mu::Contact{"a@example.com", "a", now, false, 1000, 0});
|
||||||
ccache.add(Mu::Contact{"b@example.com", "b", now, false, 1000, 0});
|
ccache.add(Mu::Contact{"b@example.com", "b", now, false, 1000, 0});
|
||||||
g_assert_cmpuint(ccache.size(),==,2);
|
g_assert_cmpuint(ccache.size(),==,2);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <utils/mu-utils.hh>
|
#include <utils/mu-utils.hh>
|
||||||
|
|
||||||
|
#include "mu-config.hh"
|
||||||
#include <message/mu-message.hh>
|
#include <message/mu-message.hh>
|
||||||
|
|
||||||
namespace Mu {
|
namespace Mu {
|
||||||
|
@ -39,10 +40,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* Construct a new ContactsCache object
|
* Construct a new ContactsCache object
|
||||||
*
|
*
|
||||||
* @param serialized serialized contacts
|
* @param config db configuration database object
|
||||||
* @param personal personal addresses
|
|
||||||
*/
|
*/
|
||||||
ContactsCache(const std::string& serialized = "", const StringVec& personal = {});
|
ContactsCache(Config& config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DTOR
|
* DTOR
|
||||||
|
@ -101,20 +101,10 @@ public:
|
||||||
bool empty() const { return size() == 0; }
|
bool empty() const { return size() == 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the contacts, serialized. This all marks the data as
|
* Serialize contact information. This all marks the data as
|
||||||
* non-dirty (see dirty())
|
* non-dirty
|
||||||
*
|
|
||||||
* @return serialized contacts
|
|
||||||
*/
|
*/
|
||||||
std::string serialize() const;
|
void serialize() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Has the contacts database change since the last
|
|
||||||
* call to serialize()?
|
|
||||||
*
|
|
||||||
* @return true or false
|
|
||||||
*/
|
|
||||||
bool dirty() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this look like a 'personal' address?
|
* Does this look like a 'personal' address?
|
||||||
|
|
Loading…
Reference in New Issue