diff --git a/lib/mu-container.c b/lib/mu-container.c index d88ae85f..1f143441 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -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); } diff --git a/mu/test-mu-threads.c b/mu/test-mu-threads.c index 12252df6..d3be37a1 100644 --- a/mu/test-mu-threads.c +++ b/mu/test-mu-threads.c @@ -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"}, };