clang-format: update c/cc coding style
Update all cc code using .clang-format; please do so as well for future PRs etc.; emacs has a handy 'clang-format' mode to make this automatic. For comparing old changes with git blame, we can disregard this one using --ignore-rev (see https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame )
This commit is contained in:
@ -35,72 +35,70 @@ using namespace Mu;
|
||||
// We use the MatchDecider to gather information and use it for both queries.
|
||||
|
||||
struct MatchDecider : public Xapian::MatchDecider {
|
||||
MatchDecider (QueryFlags qflags, DeciderInfo &info) : qflags_{qflags}, decider_info_{info}
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Update the match structure with unreadable/duplicate flags
|
||||
*
|
||||
* @param doc a Xapian document.
|
||||
*
|
||||
* @return a new QueryMatch object
|
||||
*/
|
||||
QueryMatch make_query_match (const Xapian::Document &doc) const
|
||||
{
|
||||
QueryMatch qm{};
|
||||
MatchDecider(QueryFlags qflags, DeciderInfo& info) : qflags_{qflags}, decider_info_{info} {}
|
||||
/**
|
||||
* Update the match structure with unreadable/duplicate flags
|
||||
*
|
||||
* @param doc a Xapian document.
|
||||
*
|
||||
* @return a new QueryMatch object
|
||||
*/
|
||||
QueryMatch make_query_match(const Xapian::Document& doc) const
|
||||
{
|
||||
QueryMatch qm{};
|
||||
|
||||
auto msgid{opt_string (doc, MU_MSG_FIELD_ID_MSGID)
|
||||
.value_or (*opt_string (doc, MU_MSG_FIELD_ID_PATH))};
|
||||
if (!decider_info_.message_ids.emplace (std::move (msgid)).second)
|
||||
qm.flags |= QueryMatch::Flags::Duplicate;
|
||||
auto msgid{opt_string(doc, MU_MSG_FIELD_ID_MSGID)
|
||||
.value_or(*opt_string(doc, MU_MSG_FIELD_ID_PATH))};
|
||||
if (!decider_info_.message_ids.emplace(std::move(msgid)).second)
|
||||
qm.flags |= QueryMatch::Flags::Duplicate;
|
||||
|
||||
const auto path{opt_string (doc, MU_MSG_FIELD_ID_PATH)};
|
||||
if (!path || ::access (path->c_str(), R_OK) != 0)
|
||||
qm.flags |= QueryMatch::Flags::Unreadable;
|
||||
const auto path{opt_string(doc, MU_MSG_FIELD_ID_PATH)};
|
||||
if (!path || ::access(path->c_str(), R_OK) != 0)
|
||||
qm.flags |= QueryMatch::Flags::Unreadable;
|
||||
|
||||
return qm;
|
||||
}
|
||||
return qm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this message be included in the results?
|
||||
*
|
||||
* @param qm a query match
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool should_include (const QueryMatch &qm) const
|
||||
{
|
||||
if (any_of (qflags_ & QueryFlags::SkipDuplicates) &&
|
||||
any_of (qm.flags & QueryMatch::Flags::Duplicate))
|
||||
return false;
|
||||
/**
|
||||
* Should this message be included in the results?
|
||||
*
|
||||
* @param qm a query match
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool should_include(const QueryMatch& qm) const
|
||||
{
|
||||
if (any_of(qflags_ & QueryFlags::SkipDuplicates) &&
|
||||
any_of(qm.flags & QueryMatch::Flags::Duplicate))
|
||||
return false;
|
||||
|
||||
if (any_of (qflags_ & QueryFlags::SkipUnreadable) &&
|
||||
any_of (qm.flags & QueryMatch::Flags::Unreadable))
|
||||
return false;
|
||||
if (any_of(qflags_ & QueryFlags::SkipUnreadable) &&
|
||||
any_of(qm.flags & QueryMatch::Flags::Unreadable))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Gather thread ids from this match.
|
||||
*
|
||||
* @param doc the document (message)
|
||||
*
|
||||
*/
|
||||
void gather_thread_ids (const Xapian::Document &doc) const
|
||||
{
|
||||
auto thread_id{opt_string (doc, MU_MSG_FIELD_ID_THREAD_ID)};
|
||||
if (thread_id)
|
||||
decider_info_.thread_ids.emplace (std::move (*thread_id));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Gather thread ids from this match.
|
||||
*
|
||||
* @param doc the document (message)
|
||||
*
|
||||
*/
|
||||
void gather_thread_ids(const Xapian::Document& doc) const
|
||||
{
|
||||
auto thread_id{opt_string(doc, MU_MSG_FIELD_ID_THREAD_ID)};
|
||||
if (thread_id)
|
||||
decider_info_.thread_ids.emplace(std::move(*thread_id));
|
||||
}
|
||||
|
||||
protected:
|
||||
const QueryFlags qflags_;
|
||||
DeciderInfo & decider_info_;
|
||||
protected:
|
||||
const QueryFlags qflags_;
|
||||
DeciderInfo& decider_info_;
|
||||
|
||||
private:
|
||||
Option<std::string> opt_string (const Xapian::Document &doc, MuMsgFieldId id)
|
||||
const noexcept {
|
||||
std::string val = xapian_try([&]{ return doc.get_value (id);}, std::string{""});
|
||||
private:
|
||||
Option<std::string> opt_string(const Xapian::Document& doc, MuMsgFieldId id) const noexcept
|
||||
{
|
||||
std::string val = xapian_try([&] { return doc.get_value(id); }, std::string{""});
|
||||
if (val.empty())
|
||||
return Nothing;
|
||||
else
|
||||
@ -109,119 +107,119 @@ struct MatchDecider : public Xapian::MatchDecider {
|
||||
};
|
||||
|
||||
struct MatchDeciderLeader final : public MatchDecider {
|
||||
MatchDeciderLeader (QueryFlags qflags, DeciderInfo &info) : MatchDecider (qflags, info) {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* We use this to potentiallly avoid certain messages (documents):
|
||||
* - with QueryFlags::SkipUnreadable this will return false for message
|
||||
* that are not readable in the file-system
|
||||
* - with QueryFlags::SkipDuplicates this will return false for messages
|
||||
* whose message-id was seen before.
|
||||
*
|
||||
* Even if we do not skip these messages entirely, we remember whether
|
||||
* they were unreadable/duplicate (in the QueryMatch::Flags), so we can
|
||||
* quickly find that info when doing the second 'related' query.
|
||||
*
|
||||
* The "leader" query. Matches here get the Leader flag unless their
|
||||
* duplicates / unreadable. We check the duplicate/readable status
|
||||
* regardless of whether SkipDuplicates/SkipUnreadable was passed
|
||||
* (to gather that information); however those flags
|
||||
* affect our true/false verdict.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator() (const Xapian::Document &doc) const override
|
||||
{
|
||||
// by definition, we haven't seen the docid before,
|
||||
// so no need to search
|
||||
auto it = decider_info_.matches.emplace (doc.get_docid(), make_query_match (doc));
|
||||
it.first->second.flags |= QueryMatch::Flags::Leader;
|
||||
MatchDeciderLeader(QueryFlags qflags, DeciderInfo& info) : MatchDecider(qflags, info) {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* We use this to potentiallly avoid certain messages (documents):
|
||||
* - with QueryFlags::SkipUnreadable this will return false for message
|
||||
* that are not readable in the file-system
|
||||
* - with QueryFlags::SkipDuplicates this will return false for messages
|
||||
* whose message-id was seen before.
|
||||
*
|
||||
* Even if we do not skip these messages entirely, we remember whether
|
||||
* they were unreadable/duplicate (in the QueryMatch::Flags), so we can
|
||||
* quickly find that info when doing the second 'related' query.
|
||||
*
|
||||
* The "leader" query. Matches here get the Leader flag unless their
|
||||
* duplicates / unreadable. We check the duplicate/readable status
|
||||
* regardless of whether SkipDuplicates/SkipUnreadable was passed
|
||||
* (to gather that information); however those flags
|
||||
* affect our true/false verdict.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator()(const Xapian::Document& doc) const override
|
||||
{
|
||||
// by definition, we haven't seen the docid before,
|
||||
// so no need to search
|
||||
auto it = decider_info_.matches.emplace(doc.get_docid(), make_query_match(doc));
|
||||
it.first->second.flags |= QueryMatch::Flags::Leader;
|
||||
|
||||
return should_include (it.first->second);
|
||||
}
|
||||
return should_include(it.first->second);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Xapian::MatchDecider>
|
||||
Mu::make_leader_decider (QueryFlags qflags, DeciderInfo &info)
|
||||
Mu::make_leader_decider(QueryFlags qflags, DeciderInfo& info)
|
||||
{
|
||||
return std::make_unique<MatchDeciderLeader> (qflags, info);
|
||||
return std::make_unique<MatchDeciderLeader>(qflags, info);
|
||||
}
|
||||
|
||||
struct MatchDeciderRelated final : public MatchDecider {
|
||||
MatchDeciderRelated (QueryFlags qflags, DeciderInfo &info) : MatchDecider (qflags, info) {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* We use this to potentially avoid certain messages (documents):
|
||||
* - with QueryFlags::SkipUnreadable this will return false for message
|
||||
* that are not readable in the file-system
|
||||
* - with QueryFlags::SkipDuplicates this will return false for messages
|
||||
* whose message-id was seen before.
|
||||
*
|
||||
* Unlike in the "leader" decider (scroll up), we don't need to remember
|
||||
* messages we won't include.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator() (const Xapian::Document &doc) const override
|
||||
{
|
||||
// we may have seen this match in the "Leader" query.
|
||||
const auto it = decider_info_.matches.find (doc.get_docid());
|
||||
if (it != decider_info_.matches.end())
|
||||
return should_include (it->second);
|
||||
MatchDeciderRelated(QueryFlags qflags, DeciderInfo& info) : MatchDecider(qflags, info) {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* We use this to potentially avoid certain messages (documents):
|
||||
* - with QueryFlags::SkipUnreadable this will return false for message
|
||||
* that are not readable in the file-system
|
||||
* - with QueryFlags::SkipDuplicates this will return false for messages
|
||||
* whose message-id was seen before.
|
||||
*
|
||||
* Unlike in the "leader" decider (scroll up), we don't need to remember
|
||||
* messages we won't include.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator()(const Xapian::Document& doc) const override
|
||||
{
|
||||
// we may have seen this match in the "Leader" query.
|
||||
const auto it = decider_info_.matches.find(doc.get_docid());
|
||||
if (it != decider_info_.matches.end())
|
||||
return should_include(it->second);
|
||||
|
||||
auto qm{make_query_match (doc)};
|
||||
if (should_include (qm)) {
|
||||
qm.flags = QueryMatch::Flags::Related;
|
||||
decider_info_.matches.emplace (doc.get_docid(), std::move (qm));
|
||||
return true;
|
||||
} else
|
||||
return false; // nope.
|
||||
}
|
||||
auto qm{make_query_match(doc)};
|
||||
if (should_include(qm)) {
|
||||
qm.flags = QueryMatch::Flags::Related;
|
||||
decider_info_.matches.emplace(doc.get_docid(), std::move(qm));
|
||||
return true;
|
||||
} else
|
||||
return false; // nope.
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Xapian::MatchDecider>
|
||||
Mu::make_related_decider (QueryFlags qflags, DeciderInfo &info)
|
||||
Mu::make_related_decider(QueryFlags qflags, DeciderInfo& info)
|
||||
{
|
||||
return std::make_unique<MatchDeciderRelated> (qflags, info);
|
||||
return std::make_unique<MatchDeciderRelated>(qflags, info);
|
||||
}
|
||||
|
||||
struct MatchDeciderThread final : public MatchDecider {
|
||||
MatchDeciderThread (QueryFlags qflags, DeciderInfo &info) : MatchDecider{qflags, info} {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* Only include documents that earlier checks have decided to include.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator() (const Xapian::Document &doc) const override
|
||||
{
|
||||
// we may have seen this match in the "Leader" query,
|
||||
// or in the second (unbuounded) related query;
|
||||
const auto it{decider_info_.matches.find (doc.get_docid())};
|
||||
return it != decider_info_.matches.end() && !it->second.thread_path.empty();
|
||||
}
|
||||
MatchDeciderThread(QueryFlags qflags, DeciderInfo& info) : MatchDecider{qflags, info} {}
|
||||
/**
|
||||
* operator()
|
||||
*
|
||||
* This receives the documents considered during a Xapian query, and
|
||||
* is to return either true (keep) or false (ignore)
|
||||
*
|
||||
* Only include documents that earlier checks have decided to include.
|
||||
*
|
||||
* @param doc xapian document
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
bool operator()(const Xapian::Document& doc) const override
|
||||
{
|
||||
// we may have seen this match in the "Leader" query,
|
||||
// or in the second (unbuounded) related query;
|
||||
const auto it{decider_info_.matches.find(doc.get_docid())};
|
||||
return it != decider_info_.matches.end() && !it->second.thread_path.empty();
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Xapian::MatchDecider>
|
||||
Mu::make_thread_decider (QueryFlags qflags, DeciderInfo &info)
|
||||
Mu::make_thread_decider(QueryFlags qflags, DeciderInfo& info)
|
||||
{
|
||||
return std::make_unique<MatchDeciderThread> (qflags, info);
|
||||
return std::make_unique<MatchDeciderThread>(qflags, info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user