summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J Stevens <paul@nfg.nl>2010-08-11 11:06:27 +0200
committerPaul J Stevens <paul@nfg.nl>2010-08-11 11:06:27 +0200
commite35474549dd657e1c6b5cb9ec440bae3dc457100 (patch)
tree93677dbe1d081c4a490a845ce38a58197719d446
parentab4caa44b5c214f2cf37b785036d66b912902885 (diff)
improve fix for #851
-rw-r--r--src/dbmail-mailbox.c37
-rw-r--r--src/dm_misc.c12
-rw-r--r--src/dm_misc.h2
-rw-r--r--test/check_dbmail_deliver.c34
-rw-r--r--test/check_dbmail_mailbox.c3
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;
}