[RFC Patch 2/3] CLI/address: sort output by frequency with deduplicate=address

Subject: [RFC Patch 2/3] CLI/address: sort output by frequency with deduplicate=address

Date: Sun, 19 Dec 2021 14:18:53 -0400

To: notmuch@notmuchmail.org

Cc:

From: David Bremner


Since the current output is not in any guaranteed order, changing the
output ordering should not break anything.

This is one of the easy cases, since we are already making a complete
pass of the matches and storing them in a hash table.
---
 notmuch-search.c     | 19 +++++++++++++++----
 test/T095-address.sh | 28 ++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/notmuch-search.c b/notmuch-search.c
index 47eec601..ff3967fd 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -64,6 +64,7 @@ typedef struct {
     int limit;
     int dupe;
     GHashTable *addresses;
+    GList *output_mailboxes;
     int dedup;
 } search_context_t;
 
@@ -507,14 +508,20 @@ print_list_value (void *mailbox, void *context)
     print_mailbox (context, mailbox);
 }
 
+static gint
+compare_count (gconstpointer a, gconstpointer b)
+{
+    return ((mailbox_t *) b)->count - ((mailbox_t *) a)->count;
+}
+
 static void
-print_hash_value (unused (void *key), void *list, void *context)
+process_hash_value (unused (void *key), void *list, void *context)
 {
-    const search_context_t *ctx = context;
+    search_context_t *ctx = context;
 
     if (ctx->dedup == DEDUP_ADDRESS) {
 	mailbox_t *mailbox = summarize_mailboxes (list);
-	print_mailbox (ctx, mailbox);
+	ctx->output_mailboxes = g_list_prepend (ctx->output_mailboxes, mailbox);
     } else
 	g_list_foreach (list, print_list_value, context);
 }
@@ -621,7 +628,10 @@ do_search_messages (search_context_t *ctx)
 
     if (ctx->addresses &&
 	(ctx->output & OUTPUT_COUNT || ctx->dedup == DEDUP_ADDRESS)) {
-	g_hash_table_foreach (ctx->addresses, print_hash_value, ctx);
+	g_hash_table_foreach (ctx->addresses, process_hash_value, ctx);
+	ctx->output_mailboxes = g_list_sort (ctx->output_mailboxes, compare_count);
+	if (ctx->dedup == DEDUP_ADDRESS)
+	    g_list_foreach (ctx->output_mailboxes, print_list_value, ctx);
     }
     notmuch_messages_destroy (messages);
 
@@ -910,6 +920,7 @@ notmuch_address_command (notmuch_database_t *notmuch, int argc, char *argv[])
     ctx->addresses = g_hash_table_new_full (strcase_hash, strcase_equal,
 					    _talloc_free_for_g_hash,
 					    _list_free_for_g_hash);
+    ctx->output_mailboxes = NULL; /* empty list, according to glib */
 
     /* The order is not guaranteed if a full pass is required, so go
      * for fastest. */
diff --git a/test/T095-address.sh b/test/T095-address.sh
index 8bb3627a..53886591 100755
--- a/test/T095-address.sh
+++ b/test/T095-address.sh
@@ -276,6 +276,26 @@ notmuch@notmuchmail.org
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "--deduplicate=address --output=sender --output=recipients --output=count (sort by frequency)"
+notmuch address --deduplicate=address --output=sender --output=recipients --output=count '*' | head -n 4 >OUTPUT
+cat <<EOF >EXPECTED
+50	notmuch@notmuchmail.org
+12	Carl Worth <cworth@cworth.org>
+8	Keith Packard <keithp@keithp.com>
+6	Alexander Botero-Lowry <alex.boterolowry@gmail.com>
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "--deduplicate=address --output=sender --output=recipients --output=count (sort by frequency)"
+notmuch address --deduplicate=address --output=sender --output=recipients '*' | head -n 4 >OUTPUT
+cat <<EOF >EXPECTED
+notmuch@notmuchmail.org
+Carl Worth <cworth@cworth.org>
+Keith Packard <keithp@keithp.com>
+Alexander Botero-Lowry <alex.boterolowry@gmail.com>
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 generate_message '[from]="Foo Bar <foo.bar@example.com>"'
 generate_message '[from]="Foo Bar <Foo.Bar@Example.Com>"'
 generate_message '[from]="Foo Bar <foo.bar@example.com>"'
@@ -325,6 +345,14 @@ cat <<EOF >EXPECTED
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "--deduplicate=address --output=sender --output=count (sort by frequency)"
+notmuch address --deduplicate=address --output=sender --output=count from:example.com >OUTPUT
+cat <<EOF >EXPECTED
+7	Foo Bar <foo.bar@example.com>
+3	Baz <foo.bar+baz@example.com>
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 if [[ NOTMUCH_HAVE_SFSEXP = 1 ]]; then
     test_begin_subtest "sexpr query: all messages"
     notmuch address '*' > EXPECTED
-- 
2.34.1

_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-leave@notmuchmail.org

Thread: