mu: sort childs of thread based on the sortfield only

Today when we query a find cmd with the `--threads` option, all the
childs of each thread are sorted according to their leader based on
the sortfield.

This patch change the way of how the childs of a thread are sorted.
The threads are still sorted according to their leader but all the
childs of each thread are now sorted based on the sortfield only.

Here is an example of what happened with the previous sorting:

Example with random kernel thread sorted by date:

[PATCH 0/4] drm/panel: jh057n0090: Add regulators and drop magic value in init
  ┣━▶[PATCH 1/4] MAINTAINERS: Add Purism mail alias as reviewer for their devkit's panel
  ┣━▶[PATCH 2/4] drm/panel: jh057n0090: Don't use magic constant
  ┣━▶[PATCH 3/4] dt-bindings: display/panel: jh057n0090: Document power supply properties
  ┗━▶[PATCH 4/4] drm/panel: jh057n0090: Add regulator support

If someone reply to one of these emails in the middle, this email
become the leader and the thread is displayed like this:

[PATCH 0/4] drm/panel: jh057n0090: Add regulators and drop magic value in init
  ┣━▶[PATCH 2/4] drm/panel: jh057n0090: Don't use magic constant
  ┃  ┗━▶ Re: [PATCH 2/4] drm/panel: jh057n0090: Don't use magic constant
  ┣━▶[PATCH 1/4] MAINTAINERS: Add Purism mail alias as reviewer for their devkit's panel
  ┣━▶[PATCH 3/4] dt-bindings: display/panel: jh057n0090: Document power supply properties
  ┗━▶[PATCH 4/4] drm/panel: jh057n0090: Add regulator support

With this patch, we will have the following output:

[PATCH 0/4] drm/panel: jh057n0090: Add regulators and drop magic value in init
  ┣━▶[PATCH 1/4] MAINTAINERS: Add Purism mail alias as reviewer for their devkit's panel
  ┣━▶[PATCH 2/4] drm/panel: jh057n0090: Don't use magic constant
  ┃  ┗━▶ Re: [PATCH 2/4] drm/panel: jh057n0090: Don't use magic constant
  ┣━▶[PATCH 3/4] dt-bindings: display/panel: jh057n0090: Document power supply properties
  ┗━▶[PATCH 4/4] drm/panel: jh057n0090: Add regulator support

The tests cases concerning threads have also been updated.

Signed-off-by: Julien Masson <massonju.eseo@gmail.com>
This commit is contained in:
Julien Masson 2020-02-10 15:34:00 +01:00
parent f50360f94e
commit c4ccaf0fdb
2 changed files with 78 additions and 69 deletions

View File

@ -353,36 +353,8 @@ container_cmp (MuContainer *a, MuContainer *b, MuMsgFieldId mfid)
return mu_msg_cmp (a->msg, b->msg, mfid);
}
static gboolean
container_is_leaf (const MuContainer *c)
{
return c->child == NULL;
}
static MuContainer*
container_max (MuContainer *a, MuContainer *b, MuMsgFieldId mfid)
{
return container_cmp (a, b, mfid) > 0 ? a : b;
}
static MuContainer*
find_sorted_tree_leader (MuContainer *root, SortFuncData *order)
{
MuContainer *last_child;
if (container_is_leaf (root))
return root;
if (!order->descending)
last_child = root->child->last;
else /* reversed order, first is last */
last_child = root->child;
return container_max (root, last_child->leader, order->mfid);
}
static int
sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data)
sort_func_root (MuContainer *a, MuContainer *b, SortFuncData *data)
{
if (data->descending)
return container_cmp (b->leader, a->leader, data->mfid);
@ -390,10 +362,56 @@ sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data)
return container_cmp (a->leader, b->leader, data->mfid);
}
static int
sort_func_child (MuContainer *a, MuContainer *b, SortFuncData *data)
{
if (data->descending)
return container_cmp (a, b, data->mfid);
else
return container_cmp (b, a, data->mfid);
}
static MuContainer*
container_sort_real (MuContainer *c, SortFuncData *sfdata)
container_sort(MuContainer *c, GCompareDataFunc func, SortFuncData *sfdata)
{
GSList *lst;
lst = mu_container_to_list (c);
lst = g_slist_sort_with_data (lst, func, sfdata);
c = mu_container_from_list (lst);
g_slist_free (lst);
return c;
}
static MuContainer*
container_sort_child (MuContainer *c, SortFuncData *sfdata)
{
MuContainer *cur, *leader;
if (!c)
return NULL;
/* find leader */
leader = c->leader;
for (cur = c; cur; cur = cur->next) {
if (cur->child)
cur->child = container_sort_child (cur->child, sfdata);
if (container_cmp (cur->leader, leader, sfdata->mfid) > 0)
leader = cur->leader;
}
c = container_sort(c, (GCompareDataFunc)sort_func_child, sfdata);
/* set parent's leader to the one found */
c->parent->leader = leader;
return c;
}
static MuContainer*
container_sort_root (MuContainer *c, SortFuncData *sfdata)
{
MuContainer *cur;
if (!c)
@ -401,19 +419,10 @@ container_sort_real (MuContainer *c, SortFuncData *sfdata)
for (cur = c; cur; cur = cur->next) {
if (cur->child)
cur->child = container_sort_real (cur->child, sfdata);
cur->leader = find_sorted_tree_leader (cur, sfdata);
cur->child = container_sort_child (cur->child, sfdata);
}
/* sort siblings */
lst = mu_container_to_list (c);
lst = g_slist_sort_with_data(lst,
(GCompareDataFunc)sort_func_wrapper,
sfdata);
c = mu_container_from_list (lst);
g_slist_free (lst);
return c;
return container_sort (c, (GCompareDataFunc)sort_func_root, sfdata);
}
MuContainer*
@ -429,7 +438,7 @@ mu_container_sort (MuContainer *c, MuMsgFieldId mfid, gboolean descending,
g_return_val_if_fail (c, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL);
return container_sort_real (c, &sfdata);
return container_sort_root (c, &sfdata);
}

View File

@ -158,9 +158,9 @@ test_mu_threads_01 (void)
const tinfo items [] = {
{"0", "root0@msg.id", "root0"},
{"0:0", "child0.0@msg.id", "Re: child 0.0"},
{"0:1", "child0.1@msg.id", "Re: child 0.1"},
{"0:1:0", "child0.1.0@msg.id", "Re: child 0.1.0"},
{"0:0", "child0.1@msg.id", "Re: child 0.1"},
{"0:0:0", "child0.1.0@msg.id", "Re: child 0.1.0"},
{"0:1", "child0.0@msg.id", "Re: child 0.0"},
{"1", "root1@msg.id", "root1"},
{"2", "root2@msg.id", "root2"},
/* next one's been promoted 2.0.0 => 2.0 */
@ -169,8 +169,8 @@ test_mu_threads_01 (void)
{"3", "child3.0.0.0.0@msg.id", "Re: child 3.0.0.0"},
/* two children of absent root 4.0 */
{"4:0", "child4.0@msg.id", "Re: child 4.0"},
{"4:1", "child4.1@msg.id", "Re: child 4.1"}
{"4:0", "child4.1@msg.id", "Re: child 4.1"},
{"4:1", "child4.0@msg.id", "Re: child 4.0"}
};
xpath = fill_database (MU_TESTMAILDIR3);
@ -308,13 +308,13 @@ test_mu_threads_sort_2nd_child_promotes_thread (void)
{ "0", "A@msg.id", "A"},
{ "1", "D@msg.id", "D"},
{ "2", "B@msg.id", "B"},
{ "2:0", "C@msg.id", "C"},
{ "2:1", "E@msg.id", "E"},
{ "2:0", "E@msg.id", "E"},
{ "2:1", "C@msg.id", "C"},
};
const tinfo expected_desc [] = {
{ "0", "B@msg.id", "B"},
{ "0:0", "E@msg.id", "E"},
{ "0:1", "C@msg.id", "C"},
{ "0:0", "C@msg.id", "C"},
{ "0:1", "E@msg.id", "E"},
{ "1", "D@msg.id", "D"},
{ "2", "A@msg.id", "A"},
};
@ -334,12 +334,12 @@ test_mu_threads_sort_orphan_promotes_thread (void)
const tinfo expected_asc [] = {
{ "0", "A@msg.id", "A"},
{ "1", "D@msg.id", "D"},
{ "2:0", "C@msg.id", "C"},
{ "2:1", "E@msg.id", "E"},
{ "2:0", "E@msg.id", "E"},
{ "2:1", "C@msg.id", "C"},
};
const tinfo expected_desc [] = {
{ "0:0", "E@msg.id", "E"},
{ "0:1", "C@msg.id", "C"},
{ "0:0", "C@msg.id", "C"},
{ "0:1", "E@msg.id", "E"},
{ "1", "D@msg.id", "D"},
{ "2", "A@msg.id", "A"},
};
@ -357,16 +357,16 @@ test_mu_threads_sort_child_does_not_promote_thread (void)
const char *query = "maildir:/sort/child-does-not-promote-thread";
const tinfo expected_asc [] = {
{ "0", "X@msg.id", "X"},
{ "1", "Y@msg.id", "Y"},
{ "1:0", "A@msg.id", "A"},
{ "0", "Y@msg.id", "Y"},
{ "0:0", "A@msg.id", "A"},
{ "1", "X@msg.id", "X"},
{ "2", "Z@msg.id", "Z"},
};
const tinfo expected_desc [] = {
{ "0", "Z@msg.id", "Z"},
{ "1", "Y@msg.id", "Y"},
{ "1:0", "A@msg.id", "A"},
{ "2", "X@msg.id", "X"},
{ "1", "X@msg.id", "X"},
{ "2", "Y@msg.id", "Y"},
{ "2:0", "A@msg.id", "A"},
};
check_sort_by_subject_asc (query, expected_asc,
@ -409,19 +409,19 @@ test_mu_threads_sort_granchild_promotes_only_subthread (void)
const tinfo expected_asc [] = {
{ "0", "A@msg.id", "A"},
{ "1", "B@msg.id", "B"},
{ "1:0", "C@msg.id", "C"},
{ "1:1", "E@msg.id", "E"},
{ "1:2", "D@msg.id", "D"},
{ "1:2:0", "F@msg.id", "F"},
{ "1:0", "E@msg.id", "E"},
{ "1:1", "D@msg.id", "D"},
{ "1:1:0", "F@msg.id", "F"},
{ "1:2", "C@msg.id", "C"},
{ "2", "G@msg.id", "G"},
};
const tinfo expected_desc [] = {
{ "0", "G@msg.id", "G"},
{ "1", "B@msg.id", "B"},
{ "1:0", "D@msg.id", "D"},
{ "1:0:0", "F@msg.id", "F"},
{ "1:1", "E@msg.id", "E"},
{ "1:2", "C@msg.id", "C"},
{ "1:0", "C@msg.id", "C"},
{ "1:1", "D@msg.id", "D"},
{ "1:1:0", "F@msg.id", "F"},
{ "1:2", "E@msg.id", "E"},
{ "2", "A@msg.id", "A"},
};