mu-contacts: add dirty()

Maintain a "dirtiness" number, which increases with changes, and resets after
serialize().
This commit is contained in:
Dirk-Jan C. Binnema 2022-01-15 15:11:26 +02:00
parent be4fc67584
commit ca4651a891
2 changed files with 35 additions and 12 deletions

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2019 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2019-2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -80,7 +80,8 @@ struct ContactInfoEqual {
constexpr auto RecentOffset{15 * 24 * 3600};
struct ContactInfoLessThan {
ContactInfoLessThan() : recently_{::time({}) - RecentOffset} {}
ContactInfoLessThan()
: recently_{::time({}) - RecentOffset} {}
bool operator()(const Mu::ContactInfo& ci1, const Mu::ContactInfo& ci2) const
{
@ -106,7 +107,7 @@ using ContactSet = std::set<std::reference_wrapper<const ContactInfo>, ContactIn
struct Contacts::Private {
Private(const std::string& serialized, const StringVec& personal)
: contacts_{deserialize(serialized)}
: contacts_{deserialize(serialized)}, dirty_{0}
{
make_personal(personal);
}
@ -120,6 +121,8 @@ struct Contacts::Private {
StringVec personal_plain_;
std::vector<std::regex> personal_rx_;
size_t dirty_;
};
constexpr auto Separator = "\xff"; // Invalid in UTF-8
@ -164,11 +167,11 @@ Contacts::Private::deserialize(const std::string& serialized) const
continue;
}
ContactInfo ci(std::move(parts[0]), // full address
parts[1], // email
std::move(parts[2]), // name
parts[3][0] == '1' ? true : false, // personal
(time_t)g_ascii_strtoll(parts[4].c_str(), NULL, 10), // last_seen
ContactInfo ci(std::move(parts[0]), // full address
parts[1], // email
std::move(parts[2]), // name
parts[3][0] == '1' ? true : false, // personal
(time_t)g_ascii_strtoll(parts[4].c_str(), NULL, 10), // last_seen
(std::size_t)g_ascii_strtoll(parts[5].c_str(), NULL, 10)); // freq
contacts.emplace(std::move(parts[1]), std::move(ci));
@ -183,7 +186,6 @@ Contacts::Contacts(const std::string& serialized, const StringVec& personal)
}
Contacts::~Contacts() = default;
std::string
Contacts::serialize() const
{
@ -211,14 +213,24 @@ Contacts::serialize() const
(gint64)ci.freq);
}
priv_->dirty_ = 0;
return s;
}
bool
Contacts::dirty() const
{
return priv_->dirty_;
}
const ContactInfo
Contacts::add(ContactInfo&& ci)
{
std::lock_guard<std::mutex> l_{priv_->mtx_};
++priv_->dirty_;
auto it = priv_->contacts_.find(ci.email);
if (it == priv_->contacts_.end()) { // completely new contact
@ -265,6 +277,8 @@ Contacts::clear()
{
std::lock_guard<std::mutex> l_{priv_->mtx_};
++priv_->dirty_;
priv_->contacts_.clear();
}

View File

@ -64,7 +64,7 @@ struct ContactInfo {
/// All contacts
class Contacts {
public:
public:
/**
* Construct a new contacts objects
*
@ -111,12 +111,21 @@ class Contacts {
bool empty() const { return size() == 0; }
/**
* Get the contacts, serialized.
* Get the contacts, serialized. This all marks the data as
* non-dirty (see dirty())
*
* @return serialized contacts
*/
std::string 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?
*
@ -150,7 +159,7 @@ class Contacts {
*/
void for_each(const EachContactFunc& each_contact) const;
private:
private:
struct Private;
std::unique_ptr<Private> priv_;
};