Changeset: 627201dd861d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/627201dd861d
Modified Files:
        sql/common/sql_changeset.c
        sql/common/sql_list.c
        sql/include/sql_catalog.h
        sql/include/sql_list.h
        sql/storage/store.c
Branch: default
Log Message:

Fixed memory leak from temporary table's hash values. Later hash_del and 
hash_delete functions have to be merged


diffs (223 lines):

diff --git a/sql/common/sql_changeset.c b/sql/common/sql_changeset.c
--- a/sql/common/sql_changeset.c
+++ b/sql/common/sql_changeset.c
@@ -10,11 +10,12 @@
 #include "sql_catalog.h"
 
 void
-cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy)
+cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy, fkeyvalue hfunc)
 {
        *cs = (changeset) {
                .sa = sa,
                .destroy = destroy,
+               .fkeyvalue = hfunc,
        };
 }
 
@@ -31,28 +32,49 @@ cs_destroy(changeset * cs, void *data)
        }
 }
 
-void
+changeset *
 cs_add(changeset * cs, void *elm, bool isnew)
 {
-       if (!cs->set)
-               cs->set = list_new(cs->sa, cs->destroy);
-       list_append(cs->set, elm);
+       if (!cs->set && !(cs->set = list_new(cs->sa, cs->destroy)))
+               return NULL;
+
+       int sz = list_length(cs->set);
+       /* re-hash or create hash table before inserting */
+       if ((!cs->set->ht || cs->set->ht->size * 16 < sz) && sz > 
HASH_MIN_SIZE) {
+               hash_destroy(cs->set->ht);
+               if (!(cs->set->ht = hash_new(cs->sa, MAX(sz, 1) * 16, 
cs->fkeyvalue)))
+                       return NULL;
+               for (node *n = cs->set->h; n; n = n->next) {
+                       if (!hash_add(cs->set->ht, cs->set->ht->key(n->data), 
n->data))
+                               return NULL;
+               }
+       }
+       if (!list_append(cs->set, elm))
+               return NULL;
        if (isnew && !cs->nelm)
                cs->nelm = cs->set->t;
+       return cs;
 }
 
-void
-cs_del(changeset * cs, void *gdata, node *elm, bool isnew)
+changeset *
+cs_del(changeset * cs, void *gdata, node *n, bool force)
 {
-       if (cs->nelm == elm)
-               cs->nelm = elm->next;
-       if (isnew) {    /* remove just added */
-               list_remove_node(cs->set, gdata, elm);
+       if (!force && !cs->dset && !(cs->dset = list_new(cs->sa, cs->destroy)))
+               return NULL;
+
+       if (cs->nelm == n) /* update nelm pointer */
+               cs->nelm = n->next;
+       if (cs->set->ht) /* delete hashed value */
+               hash_del(cs->set->ht, cs->set->ht->key(n->data), n->data);
+
+       if (force) { /* remove just added */
+               if (!list_remove_node(cs->set, gdata, n))
+                       return NULL;
        } else {
-               if (!cs->dset)
-                       cs->dset = list_new(cs->sa, cs->destroy);
-               list_move_data(cs->set, cs->dset, elm->data);
+               if (!list_move_data(cs->set, cs->dset, n->data))
+                       return NULL;
        }
+       return cs;
 }
 
 int
diff --git a/sql/common/sql_list.c b/sql/common/sql_list.c
--- a/sql/common/sql_list.c
+++ b/sql/common/sql_list.c
@@ -385,7 +385,7 @@ list_remove_list(list *l, void *gdata, l
                list_remove_data(l, gdata, n->data);
 }
 
-void
+list *
 list_move_data(list *s, list *d, void *data)
 {
        node *n = NULL;
@@ -401,10 +401,10 @@ list_move_data(list *s, list *d, void *d
                }
        }
        if (!n) {
-               list_append(d, data);
+               return list_append(d, data);
        } else {
                n->next = NULL;
-               list_append_node(d, n);
+               return list_append_node(d, n);
        }
 }
 
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -207,6 +207,7 @@ extern void base_init(sql_allocator *sa,
 typedef struct changeset {
        sql_allocator *sa;
        fdestroy destroy;
+       fkeyvalue fkeyvalue;
        struct list *set;
        struct list *dset;
        node *nelm;
@@ -266,10 +267,10 @@ extern node *ol_rehash(objlist *ol, cons
 #define ol_last_node(ol) (ol->l->t)
 #define ol_fetch(ol,nr) (list_fetch(ol->l, nr))
 
-extern void cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy);
+extern void cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy, 
fkeyvalue hfunc);
 extern void cs_destroy(changeset * cs, void *data);
-extern void cs_add(changeset * cs, void *elm, bool isnew);
-extern void cs_del(changeset * cs, void *gdata, node *elm, bool isnew);
+extern changeset *cs_add(changeset * cs, void *elm, bool isnew);
+extern changeset *cs_del(changeset * cs, void *gdata, node *n, bool force);
 extern int cs_size(changeset * cs);
 extern node *cs_find_id(changeset * cs, sqlid id);
 
diff --git a/sql/include/sql_list.h b/sql/include/sql_list.h
--- a/sql/include/sql_list.h
+++ b/sql/include/sql_list.h
@@ -52,7 +52,7 @@ extern list *list_prepend(list *l, void 
 extern node *list_remove_node(list *l, void *gdata, node *n);
 extern void list_remove_data(list *l, void *gdata, void *data);
 extern void list_remove_list(list *l, void *gdata, list *data);
-extern void list_move_data(list *l, list *d, void *data);
+extern list *list_move_data(list *l, list *d, void *data);
 
 
 extern int list_traverse(list *l, traverse_func f, void *clientdata);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3593,7 +3593,7 @@ sql_trans_rollback(sql_trans *tr, bool c
                for(node *n=tr->localtmps.dset->h; n; ) {
                        node *next = n->next;
                        sql_table *tt = n->data;
-                       if (!isNew(tt))
+                       if (!isNew(tt)) /* TODO this is prepending without 
re-hashing? */
                                list_prepend(tr->localtmps.set, 
dup_base(&tt->base));
                        n = next;
                }
@@ -3654,7 +3654,7 @@ sql_trans_rollback(sql_trans *tr, bool c
                if (tr->localtmps.nelm) {
                        for(node *n=tr->localtmps.nelm; n; ) {
                                node *next = n->next;
-                               list_remove_node(tr->localtmps.set, store, n);
+                               cs_del(&tr->localtmps, store, n, true);
                                n = next;
                        }
                        tr->localtmps.nelm = NULL;
@@ -3717,7 +3717,7 @@ sql_trans_create_(sqlstore *store, sql_t
 
        if (!tr)
                return NULL;
-       cs_new(&tr->localtmps, tr->sa, (fdestroy) &table_destroy);
+       cs_new(&tr->localtmps, NULL, (fdestroy) &table_destroy, 
(fkeyvalue)&base_key);
        MT_lock_init(&tr->lock, "trans_lock");
        tr->parent = parent;
        if (name) {
@@ -5537,20 +5537,15 @@ sql_trans_rename_table(sql_trans *tr, sq
                        return res;
        } else {
                node *n = cs_find_id(&tr->localtmps, t->base.id);
-               if (n)
-                       cs_del(&tr->localtmps, tr->store, n, t->base.new);
+               if (n && !cs_del(&tr->localtmps, tr->store, n, t->base.new))
+                       return -1;
        }
 
        if ((res = table_dup(tr, t, t->s, new_name, &dup)))
                return res;
        t = dup;
-       if (!isGlobal(t)) {
-               if (tr->localtmps.set == NULL)
-                       tr->localtmps.set = list_new(tr->localtmps.sa, 
tr->localtmps.destroy);
-               if (tr->localtmps.set->ht == NULL || 
tr->localtmps.set->ht->size * 16 < list_length(tr->localtmps.set))
-                       tr->localtmps.set->ht = hash_new(tr->localtmps.sa, 16, 
(fkeyvalue)&base_key);
-               cs_add(&tr->localtmps, t, true);
-       }
+       if (!isGlobal(t) && !cs_add(&tr->localtmps, t, true))
+               return -1;
        return res;
 }
 
@@ -5633,12 +5628,8 @@ sql_trans_create_table(sql_table **tres,
        if (isGlobal(t)) {
                if ((res = os_add(s->tables, tr, t->base.name, &t->base)))
                        return res;
-       } else {
-               if (tr->localtmps.set == NULL)
-                       tr->localtmps.set = list_new(tr->localtmps.sa, 
tr->localtmps.destroy);
-               if (tr->localtmps.sa && (tr->localtmps.set->ht == NULL || 
tr->localtmps.set->ht->size * 16 < list_length(tr->localtmps.set)))
-                       tr->localtmps.set->ht = hash_new(tr->localtmps.sa, 16, 
(fkeyvalue)&base_key);
-               cs_add(&tr->localtmps, t, true);
+       } else if (!cs_add(&tr->localtmps, t, true)) {
+               return -1;
        }
        if (isRemote(t))
                t->persistence = SQL_REMOTE;
@@ -5866,8 +5857,8 @@ sql_trans_drop_table(sql_trans *tr, sql_
        if (is_global) {
                if ((res = os_del(s->tables, tr, t->base.name, 
dup_base(&t->base))))
                        return res;
-       } else if (n)
-               cs_del(&tr->localtmps, tr->store, n, 0);
+       } else if (n && !cs_del(&tr->localtmps, tr->store, n, 0))
+               return -1;
 
        sqlstore *store = tr->store;
        if (isTable(t) && !isNew(t))
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to