query: improve thread-date handling

And make it available in query_match, so we can expose it to elisp.
This commit is contained in:
Dirk-Jan C. Binnema 2021-05-02 23:18:16 +03:00
parent bed6058fdc
commit 8c9430a09a
2 changed files with 30 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2021 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
@ -94,8 +94,8 @@ struct QueryMatch {
std::string subject;
std::string thread_subject; /**< the thread subject for this message */
size_t thread_level{}; /**< The thread level */
std::string thread_path; /**< The hex-numerial path in the thread, ie. '00:01:0a' */
std::string thread_date{}; /**< date of newest message in thread */
std::string thread_path; /**< The hex-numerial path in the thread, ie. '00:01:0a' */
std::string thread_date{}; /**< date of newest message in thread */
bool operator<(const QueryMatch& rhs) const {
return date_key < rhs.date_key;

View File

@ -78,8 +78,11 @@ struct Container {
// of this container -- ie.. either the one from the first of its
// children, or from its query-match, if it has no children.
//
// That the sub-root-levels of thtreas are always sorted
// by date, in ascending order.
// Note that the sub-root-levels of threads are always sorted by date,
// in ascending order, regardless of whatever sorting was specified for
// the root-level.
std::string thread_date_key;
@ -136,7 +139,7 @@ handle_duplicates (IdTable& id_table, DupTable& dup_table)
// add duplicates as fake children
char buf[32];
::snprintf(buf, sizeof(buf), "bastard-%zu", ++n);
::snprintf(buf, sizeof(buf), "dup-%zu", ++n);
it->second.add_child(
id_table.emplace(buf, std::move(dup.second)).first->second);
}
@ -180,7 +183,11 @@ determine_id_table (QueryResultsType& qres)
// both. Moreover, even when sorting the top-level in descending
// order, still sort the thread levels below that in ascending
// order.
container.query_match->date_key = mi.date().value_or("");
container.thread_date_key = container.query_match->date_key =
mi.date().value_or("");
// initial guess for the thread-date; might be updated
// later.
// remember the subject, we use it to determine the (sub)thread subject
container.query_match->subject = mi.subject().value_or("");
@ -233,7 +240,6 @@ determine_id_table (QueryResultsType& qres)
return id_table;
}
/// Recursively walk all containers under the root set.
/// For each container:
///
@ -451,15 +457,11 @@ static void
sort_container (Container& container)
{
// 1. childless container.
if (container.children.empty()) {
container.thread_date_key = container.query_match->date_key;
return;
}
if (container.children.empty())
return; // no children; nothing to sort.
// 2. container with children.
// recurse, depth-first: sort the children
for (auto& child: container.children)
sort_container(*child);
@ -469,9 +471,11 @@ sort_container (Container& container)
return c1->thread_date_key < c2->thread_date_key;
});
// and 'bubble up' the date of the *newest* message*. We reasonably
// assume that it's later than its parent.
container.thread_date_key = container.children.back()->thread_date_key;
// and 'bubble up' the date of the *newest* message with a date. We
// reasonably assume that it's later than its parent.
const auto& newest_date = container.children.back()->thread_date_key;
if (!newest_date.empty())
container.thread_date_key = newest_date;
}
@ -484,16 +488,14 @@ sort_siblings (IdTable& id_table, bool descending)
// unsorted vec of root containers. We can
// only sort these _after_ sorting the children.
ContainerVec root_vec;
for (auto&& item: id_table)
for (auto&& item: id_table) {
if (!item.second.parent && !item.second.is_nuked)
root_vec.emplace_back(&item.second);
}
// now sort all threads _under_ the root set (by date/ascending)
for (auto&& c: root_vec) {
for (auto&& c: root_vec)
sort_container(*c);
if (c->query_match) // for debugging, remember
c->query_match->thread_date = c->thread_date_key;
}
// and then sort the root set.
//
@ -553,7 +555,6 @@ calculate_threads_real (Results& qres, bool descending)
if (g_test_verbose())
std::cout << "*** id-table(1):\n" << id_table << "\n";
// // Step 2: get the root set
// // Step 3: discard id_table
// Nope: id-table owns the containers.
@ -569,6 +570,12 @@ calculate_threads_real (Results& qres, bool descending)
// in the thread-path string (so we can lexically compare them.)
sort_siblings(id_table, descending);
// Step 7a:. update querymatches
for (auto&& item: id_table) {
Container& c{item.second};
if (c.query_match)
c.query_match->thread_date = c.thread_date_key;
}
// if (g_test_verbose())
// std::cout << "*** id-table(2):\n" << id_table << "\n";
}