From e35474549dd657e1c6b5cb9ec440bae3dc457100 Mon Sep 17 00:00:00 2001 From: Paul J Stevens Date: Wed, 11 Aug 2010 11:06:27 +0200 Subject: improve fix for #851 --- src/dbmail-mailbox.c | 37 ++++++++++++++++++++++++------------- src/dm_misc.c | 12 ++++++++---- src/dm_misc.h | 2 +- test/check_dbmail_deliver.c | 34 ++++++++++++++++------------------ test/check_dbmail_mailbox.c | 3 +-- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/dbmail-mailbox.c b/src/dbmail-mailbox.c index 0eb5ff12..f1964338 100644 --- a/src/dbmail-mailbox.c +++ b/src/dbmail-mailbox.c @@ -307,7 +307,10 @@ char * dbmail_mailbox_orderedsubject(DbmailMailbox *self) while (db_result_next(r)) { i++; idnr = db_result_get_u64(r,0); - if (! g_tree_lookup(self->found,(gconstpointer)&idnr)) + + if (g_tree_nnodes(self->found) == 0) + continue; + if ( ! g_tree_lookup(self->found,(gconstpointer)&idnr)) continue; subj = (char *)db_result_get(r,1); g_tree_insert(tree,g_strdup(subj), NULL); @@ -345,6 +348,9 @@ char * dbmail_mailbox_orderedsubject(DbmailMailbox *self) while (db_result_next(r)) { i++; idnr = db_result_get_u64(r,0); + + if (g_tree_nnodes(self->found) == 0) + continue; if (! (msn = g_tree_lookup(self->found, (gconstpointer)&idnr))) continue; subj = (char *)db_result_get(r,1); @@ -1316,7 +1322,7 @@ struct filter_helper { GTree *a; }; -static int filter_range(gpointer key, gpointer value, gpointer data) +static int filter_range_cb(gpointer key, gpointer value, gpointer data) { u64_t *k, *v; struct filter_helper *d = (struct filter_helper *)data; @@ -1338,7 +1344,7 @@ static int filter_range(gpointer key, gpointer value, gpointer data) return FALSE; } -static void find_range(GTree *c, u64_t l, u64_t r, GTree *a, gboolean uid) +static void filter_range(GTree *c, u64_t l, u64_t r, GTree *a, gboolean uid) { struct filter_helper data; @@ -1347,7 +1353,7 @@ static void find_range(GTree *c, u64_t l, u64_t r, GTree *a, gboolean uid) data.max = r; data.a = a; - g_tree_foreach(c, (GTraverseFunc)filter_range, &data); + g_tree_foreach(c, (GTraverseFunc)filter_range_cb, &data); } GTree * dbmail_mailbox_get_set(DbmailMailbox *self, const char *set, gboolean uid) @@ -1356,8 +1362,7 @@ GTree * dbmail_mailbox_get_set(DbmailMailbox *self, const char *set, gboolean ui GString *t; GTree *uids; char *rest; - u64_t i, l, r, lo = 0, hi = 0, maxmsn = 0; - u64_t *k, *v, *w = NULL; + u64_t l, r, lo = 0, hi = 0, maxmsn = 0; GTree *a, *b, *c; gboolean error = FALSE; @@ -1446,13 +1451,17 @@ GTree * dbmail_mailbox_get_set(DbmailMailbox *self, const char *set, gboolean ui else c = MailboxState_getMsn(self->mbstate); - find_range(c, min(l,r), max(l,r), a, uid); + filter_range(c, min(l,r), max(l,r), a, uid); - if (g_tree_merge(b,a,IST_SUBSEARCH_OR)) { + TRACE(TRACE_DEBUG,"a[%d]", g_tree_nnodes(a)); + + if (g_tree_merge(&b,&a,IST_SUBSEARCH_OR)) { error = TRUE; TRACE(TRACE_ERR, "cannot compare null trees"); break; } + + TRACE(TRACE_DEBUG,"b[%d]", g_tree_nnodes(b)); if (! g_list_next(sets)) break; sets = g_list_next(sets); @@ -1466,6 +1475,8 @@ GTree * dbmail_mailbox_get_set(DbmailMailbox *self, const char *set, gboolean ui if (error) { g_tree_destroy(b); b = NULL; + } else { + TRACE(TRACE_DEBUG,"b[%d]", g_tree_nnodes(b)); } return b; @@ -1563,7 +1574,7 @@ static gboolean _merge_search(GNode *node, GTree *found) case IST_SUBSEARCH_NOT: g_tree_foreach(found, (GTraverseFunc)_found_tree_copy, s->found); g_node_children_foreach(node, G_TRAVERSE_ALL, (GNodeForeachFunc)_merge_search, (gpointer) s->found); - g_tree_merge(found, s->found, IST_SUBSEARCH_NOT); + g_tree_merge(&found, &s->found, IST_SUBSEARCH_NOT); s->merged = TRUE; g_tree_destroy(s->found); s->found = NULL; @@ -1586,17 +1597,17 @@ static gboolean _merge_search(GNode *node, GTree *found) g_node_children_foreach(y, G_TRAVERSE_ALL, (GNodeForeachFunc)_merge_search, (gpointer)b->found); } - g_tree_merge(a->found, b->found,IST_SUBSEARCH_OR); + g_tree_merge(&a->found, &b->found,IST_SUBSEARCH_OR); b->merged = TRUE; g_tree_destroy(b->found); b->found = NULL; - g_tree_merge(s->found, a->found,IST_SUBSEARCH_OR); + g_tree_merge(&s->found, &a->found,IST_SUBSEARCH_OR); a->merged = TRUE; g_tree_destroy(a->found); a->found = NULL; - g_tree_merge(found, s->found, IST_SUBSEARCH_AND); + g_tree_merge(&found, &s->found, IST_SUBSEARCH_AND); s->merged = TRUE; g_tree_destroy(s->found); s->found = NULL; @@ -1604,7 +1615,7 @@ static gboolean _merge_search(GNode *node, GTree *found) break; default: - g_tree_merge(found, s->found, IST_SUBSEARCH_AND); + g_tree_merge(&found, &s->found, IST_SUBSEARCH_AND); s->merged = TRUE; g_tree_destroy(s->found); s->found = NULL; diff --git a/src/dm_misc.c b/src/dm_misc.c index 4e83759e..b4dd4b7b 100644 --- a/src/dm_misc.c +++ b/src/dm_misc.c @@ -991,12 +991,15 @@ static gboolean traverse_tree_merger(gpointer key, gpointer value UNUSED, tree_m return FALSE; } -int g_tree_merge(GTree *a, GTree *b, int condition) +int g_tree_merge(GTree **left, GTree **right, int condition) { char *type = NULL; GList *keys = NULL; GTree *c = NULL; int alen = 0, blen=0, klen=0; + GTree *a, *b; + a = *left; + b = *right; gpointer key; gpointer value; @@ -1012,7 +1015,8 @@ int g_tree_merge(GTree *a, GTree *b, int condition) case IST_SUBSEARCH_AND: if (! g_tree_nnodes(b) > 0) { //short-cut: pivot trees - c = a; a = b; b = c; + c = a; *left = *right; *right = c; + a = *left; b = *right; } if (! g_tree_nnodes(a) > 0) @@ -1041,7 +1045,8 @@ int g_tree_merge(GTree *a, GTree *b, int condition) type=g_strdup("OR"); if (! g_tree_nnodes(a) > 0) { //short-cut: pivot trees - c = a; a = b; b = c; + c = a; *left = *right; *right = c; + a = *left; b = *right; } if (! g_tree_nnodes(b) > 0) @@ -1107,7 +1112,6 @@ int g_tree_merge(GTree *a, GTree *b, int condition) merger->list = g_list_first(merger->list); g_list_free(merger->list); - g_free(merger); g_free(type); diff --git a/src/dm_misc.h b/src/dm_misc.h index 4076faad..6395ab19 100644 --- a/src/dm_misc.h +++ b/src/dm_misc.h @@ -111,7 +111,7 @@ gint dm_strcasecmpdata(gconstpointer a, gconstpointer b, gpointer data); GList * g_tree_keys(GTree *tree); GList * g_tree_values(GTree *tree); void tree_dump(GTree *t); -int g_tree_merge(GTree *a, GTree *b, int condition); +int g_tree_merge(GTree **a, GTree **b, int condition); void pack_char(char *in, char c); diff --git a/test/check_dbmail_deliver.c b/test/check_dbmail_deliver.c index 186964fb..99bc5981 100644 --- a/test/check_dbmail_deliver.c +++ b/test/check_dbmail_deliver.c @@ -780,12 +780,12 @@ START_TEST(test_g_tree_merge_not) b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free); tree_add_key(b,1); - for (r=9000000; r<=10000000; r+=2) { + for (r=90000; r<=100000; r+=2) { tree_add_key(b, r); } - g_tree_merge(a,b,IST_SUBSEARCH_NOT); - fail_unless(g_tree_nnodes(a)==500002,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); + g_tree_merge(&a,&b,IST_SUBSEARCH_NOT); + fail_unless(g_tree_nnodes(a)==5002,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); g_tree_destroy(a); g_tree_destroy(b); @@ -794,11 +794,11 @@ START_TEST(test_g_tree_merge_not) b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free); tree_add_key(a, 1); - for (r=9000000; r<=10000000; r+=2) + for (r=90000; r<=100000; r+=2) tree_add_key(a, r); - g_tree_merge(a,b,IST_SUBSEARCH_NOT); - fail_unless(g_tree_nnodes(a)==500002,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); + g_tree_merge(&a,&b,IST_SUBSEARCH_NOT); + fail_unless(g_tree_nnodes(a)==5002,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); g_tree_destroy(a); g_tree_destroy(b); @@ -815,11 +815,11 @@ START_TEST(test_g_tree_merge_or) b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free); tree_add_key(b, 1); - for (r=100000; r<=1000000; r+=2) + for (r=10000; r<=100000; r+=2) tree_add_key(b, r); - g_tree_merge(a,b,IST_SUBSEARCH_OR); - fail_unless(g_tree_nnodes(a)==450002,"g_tree_merge failed. Too many nodes in a. [%ld]", g_tree_nnodes(a)); + g_tree_merge(&a,&b,IST_SUBSEARCH_OR); + fail_unless(g_tree_nnodes(a)==45002,"g_tree_merge failed. Too many nodes in a. [%ld]", g_tree_nnodes(a)); g_tree_destroy(a); g_tree_destroy(b); @@ -836,18 +836,17 @@ START_TEST(test_g_tree_merge_and) b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free); tree_add_key(a, 1); - for (r=10010000; r<100400000; r+=10) { + for (r=10000; r<100000; r+=10) { tree_add_key(a, r); } tree_add_key(b, 1); - for (r=10010000; r<=100100000; r++) { + for (r=10000; r<100000; r++) { tree_add_key(b, r); } - g_tree_merge(a,b,IST_SUBSEARCH_AND); + g_tree_merge(&a,&b,IST_SUBSEARCH_AND); fail_unless(g_tree_nnodes(a)==9001,"g_tree_merge failed. Too few nodes in a.[%ld]", g_tree_nnodes(a)); - fail_unless(g_tree_nnodes(b)==90001,"g_tree_merge failed. Too few nodes in b. [%ld]", g_tree_nnodes(b)); g_tree_destroy(a); g_tree_destroy(b); @@ -856,16 +855,15 @@ START_TEST(test_g_tree_merge_and) b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free); tree_add_key(a, 1); - for (r=10020000; r<=100100000; r+=2) + for (r=10000; r<100000; r+=2) tree_add_key(a, r); tree_add_key(b, 1); - for (r=10010000; r<=100100000; r++) + for (r=10000; r<100000; r++) tree_add_key(b, r); - g_tree_merge(a,b,IST_SUBSEARCH_AND); - fail_unless(g_tree_nnodes(a)==40001,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); - fail_unless(g_tree_nnodes(b)==90001,"g_tree_merge failed. Too few nodes in b. [%ld]", g_tree_nnodes(b)); + g_tree_merge(&a,&b,IST_SUBSEARCH_AND); + fail_unless(g_tree_nnodes(a)==45001,"g_tree_merge failed. Too few nodes in a. [%ld]", g_tree_nnodes(a)); g_tree_destroy(a); g_tree_destroy(b); diff --git a/test/check_dbmail_mailbox.c b/test/check_dbmail_mailbox.c index 0e5c7954..1b446e6d 100644 --- a/test/check_dbmail_mailbox.c +++ b/test/check_dbmail_mailbox.c @@ -517,7 +517,6 @@ Suite *dbmail_mailbox_suite(void) suite_add_tcase(s, tc_mailbox); tcase_add_checked_fixture(tc_mailbox, setup, teardown); tcase_add_test(tc_mailbox, test_dbmail_mailbox_get_set); - /* tcase_add_test(tc_mailbox, test_dbmail_mailbox_new); tcase_add_test(tc_mailbox, test_dbmail_mailbox_free); tcase_add_test(tc_mailbox, test_dbmail_mailbox_dump); @@ -527,7 +526,7 @@ Suite *dbmail_mailbox_suite(void) tcase_add_test(tc_mailbox, test_dbmail_mailbox_search_parsed_1); tcase_add_test(tc_mailbox, test_dbmail_mailbox_search_parsed_2); tcase_add_test(tc_mailbox, test_dbmail_mailbox_orderedsubject); - */ + return s; } -- cgit v1.2.3