From ca4651a8916aacb41f28134f9304b86beb181d83 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sat, 15 Jan 2022 15:11:26 +0200 Subject: [PATCH] mu-contacts: add dirty() Maintain a "dirtiness" number, which increases with changes, and resets after serialize(). --- lib/mu-contacts.cc | 32 +++++++++++++++++++++++--------- lib/mu-contacts.hh | 15 ++++++++++++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/mu-contacts.cc b/lib/mu-contacts.cc index 85d719ed..a76be29b 100644 --- a/lib/mu-contacts.cc +++ b/lib/mu-contacts.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2019 Dirk-Jan C. Binnema +** Copyright (C) 2019-2022 Dirk-Jan C. Binnema ** ** 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, 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 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 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 l_{priv_->mtx_}; + ++priv_->dirty_; + priv_->contacts_.clear(); } diff --git a/lib/mu-contacts.hh b/lib/mu-contacts.hh index f80b2cd2..807abf67 100644 --- a/lib/mu-contacts.hh +++ b/lib/mu-contacts.hh @@ -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 priv_; };