Changeset: 278df79adbde for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=278df79adbde
Modified Files:
        sql/storage/objectset.c
Branch: nospare
Log Message:

Separate objet_node into name and id based version chain types.


diffs (truncated from 903 to 300 lines):

diff --git a/sql/storage/objectset.c b/sql/storage/objectset.c
--- a/sql/storage/objectset.c
+++ b/sql/storage/objectset.c
@@ -18,15 +18,23 @@
  * keep hash/map of names -> objectversion
  */
 
-struct object_node;
+struct object_node;// TODO: rename to object_version_chain
+
+#define id_based_rollbacked 1
+#define name_based_rollbacked (1<<1)
 
 typedef struct objectversion {
        bool deleted;
        ulng ts;
+       bte rollbacked;
        sql_base *obj;
-       struct objectversion *older;
-       struct objectversion *newer;
-       struct object_node *on;
+       struct objectversion    *name_based_older;
+       struct objectversion    *name_based_newer; // TODO: must become atomic 
pointer
+       struct object_node              *name_based_chain;
+
+       struct objectversion    *id_based_older;
+       struct objectversion    *id_based_newer;
+       struct object_node              *id_based_chain;
 } objectversion;
 
 typedef struct object_node {
@@ -41,9 +49,12 @@ typedef struct objectset {
        sql_allocator *sa;
        destroy_fptr destroy;
        MT_Lock ht_lock;        /* latch protecting ht */
-       object_node *h;
-       object_node *t;
-       int cnt;
+       object_node *name_based_h;
+       object_node *name_based_t;
+       object_node *id_based_h;
+       object_node *id_based_t;
+       int name_based_cnt;
+       int id_based_cnt;
        struct sql_hash *name_map;
        struct sql_hash *id_map;
        bool temporary;
@@ -61,15 +72,15 @@ find_id(objectset *os, sqlid id)
 {
        if (os) {
                MT_lock_set(&os->ht_lock);
-               if ((!os->id_map || os->id_map->size*16 < os->cnt) && os->cnt > 
HASH_MIN_SIZE && os->sa) {
+               if ((!os->id_map || os->id_map->size*16 < os->id_based_cnt) && 
os->id_based_cnt > HASH_MIN_SIZE && os->sa) {
                        // TODO: This leaks the old map
-                       os->id_map = hash_new(os->sa, os->cnt, 
(fkeyvalue)&os_id_key);
+                       os->id_map = hash_new(os->sa, os->id_based_cnt, 
(fkeyvalue)&os_id_key);
                        if (os->id_map == NULL) {
                                MT_lock_unset(&os->ht_lock);
                                return NULL;
                        }
 
-                       for (object_node *n = os->h; n; n = n->next ) {
+                       for (object_node *n = os->id_based_h; n; n = n->next ) {
                                int key = os_id_key(n);
 
                                if (hash_add(os->id_map, key, n) == NULL) {
@@ -95,7 +106,7 @@ find_id(objectset *os, sqlid id)
                }
                MT_lock_unset(&os->ht_lock);
                // TODO: can we actually reach this point?
-               for (object_node *n = os->h; n; n = n->next) {
+               for (object_node *n = os->id_based_h; n; n = n->next) {
                        objectversion *ov = n->data;
 
                        /* check if ids match */
@@ -128,47 +139,70 @@ hash_delete(sql_hash *h, void *data)
 static void
 node_destroy(objectset *os, object_node *n)
 {
-       if (n->data && os->destroy) {
-               os->destroy(n->data, NULL);
-               n->data = NULL;
-       }
        if (!os->sa)
                _DELETE(n);
 }
 
 static object_node *
-os_remove_node(objectset *os, object_node *n)
+os_remove_name_based_chain(objectset *os, object_node *n)
 {
        assert(n);
-       object_node *p = os->h;
+       object_node *p = os->name_based_h;
 
        if (p != n)
                while (p && p->next != n)
                        p = p->next;
        assert(p==n||(p && p->next == n));
        if (p == n) {
-               os->h = n->next;
-               if (os->h) // i.e. non-empty os
-                       os->h->prev = NULL;
+               os->name_based_h = n->next;
+               if (os->name_based_h) // i.e. non-empty os
+                       os->name_based_h->prev = NULL;
                p = NULL;
        } else if ( p != NULL)  {
                p->next = n->next;
                if (p->next) // node in the middle
                        p->next->prev = p;
        }
-       if (n == os->t)
-               os->t = p;
+       if (n == os->name_based_t)
+               os->name_based_t = p;
+
+       MT_lock_set(&os->ht_lock);
+       if (os->name_map && n)
+               hash_delete(os->name_map, n);
+       MT_lock_unset(&os->ht_lock);
+
+       node_destroy(os, n);
+       return p;
+}
+
+static object_node *
+os_remove_id_based_chain(objectset *os, object_node *n)
+{
+       assert(n);
+       object_node *p = os->id_based_h;
+
+       if (p != n)
+               while (p && p->next != n)
+                       p = p->next;
+       assert(p==n||(p && p->next == n));
+       if (p == n) {
+               os->id_based_h = n->next;
+               if (os->id_based_h) // i.e. non-empty os
+                       os->id_based_h->prev = NULL;
+               p = NULL;
+       } else if ( p != NULL)  {
+               p->next = n->next;
+               if (p->next) // node in the middle
+                       p->next->prev = p;
+       }
+       if (n == os->id_based_t)
+               os->id_based_t = p;
 
        MT_lock_set(&os->ht_lock);
        if (os->id_map && n)
                hash_delete(os->id_map, n);
-       if (os->name_map && n)
-               hash_delete(os->name_map, n);
        MT_lock_unset(&os->ht_lock);
 
-       os->cnt--;
-       assert(os->cnt > 0 || os->h == NULL);
-
        node_destroy(os, n);
        return p;
 }
@@ -183,22 +217,20 @@ node_create(sql_allocator *sa, objectver
        *n = (object_node) {
                .data = ov,
        };
-       ov->on = n;
        return n;
 }
 
 static objectset *
-os_append_node(objectset *os, object_node *n)
+os_append_node_name(objectset *os, object_node *n)
 {
-       if (os->cnt) {
-               os->t->next = n;
+       if (os->name_based_t) {
+               os->name_based_t->next = n;
        } else {
-               os->h = n;
+               os->name_based_h = n;
        }
        n->os = os;
-       n->prev = os->t; // aka the double linked list.
-       os->t = n;
-       os->cnt++;
+       n->prev = os->name_based_t; // aka the double linked list.
+       os->name_based_t = n;
        if (n->data) {
                MT_lock_set(&os->ht_lock);
                if (os->name_map) {
@@ -209,6 +241,37 @@ os_append_node(objectset *os, object_nod
                                return NULL;
                        }
                }
+               MT_lock_unset(&os->ht_lock);
+       }
+       os->name_based_cnt++;
+       return os;
+}
+
+static objectset *
+os_append_name(objectset *os, objectversion *ov)
+{
+       object_node *n = node_create(os->sa, ov);
+
+       if (n == NULL)
+               return NULL;
+
+       ov->name_based_chain = n;
+       return os_append_node_name(os, n);
+}
+
+static objectset *
+os_append_node_id(objectset *os, object_node *n)
+{
+       if (os->id_based_t) {
+               os->id_based_t->next = n;
+       } else {
+               os->id_based_h = n;
+       }
+       n->os = os;
+       n->prev = os->id_based_t; // aka the double linked list.
+       os->id_based_t = n;
+       if (n->data) {
+               MT_lock_set(&os->ht_lock);
                if (os->id_map) {
                        int key = os->id_map->key(n);
 
@@ -219,17 +282,19 @@ os_append_node(objectset *os, object_nod
                }
                MT_lock_unset(&os->ht_lock);
        }
+       os->id_based_cnt++;
        return os;
 }
 
 static objectset *
-os_append(objectset *os, objectversion *ov)
+os_append_id(objectset *os, objectversion *ov)
 {
        object_node *n = node_create(os->sa, ov);
 
        if (n == NULL)
                return NULL;
-       return os_append_node(os, n);
+       ov->id_based_chain = n;
+       return os_append_node_id(os, n);
 }
 
 static object_node* find_name(objectset *os, const char *name);
@@ -237,24 +302,26 @@ static object_node* find_name(objectset 
 static void
 objectversion_destroy(sqlstore *store, objectversion *ov, ulng commit_ts, ulng 
oldest)
 {
-       objectversion *older = ov->older;
-       objectversion *newer = ov->newer;
+       // TODO: clean this up once the add and del functions are working
+       // TODO: handle name_based_cnt s and id_based_cnt s
+       objectversion *name_based_older = ov->name_based_older;
+       objectversion *name_based_newer = ov->name_based_newer;
 
-       if (older && commit_ts) {
-               objectversion_destroy(store, older, commit_ts, oldest);
-               older = NULL;
-       } else if (older) {
-               older->newer = newer;
+       if (name_based_older && commit_ts) {
+               objectversion_destroy(store, name_based_older, commit_ts, 
oldest);
+               name_based_older = NULL;
+       } else if (name_based_older) {
+               name_based_older->name_based_newer = name_based_newer;
        }
-       ov->older = NULL;
+       ov->name_based_older = NULL;
 
-       if (newer && commit_ts)
-               newer->older = NULL;
-       else if (newer && older)
-               newer->older = older;
+       if (name_based_newer && commit_ts)
+               name_based_newer->name_based_older = NULL;
+       else if (name_based_newer && name_based_older)
+               name_based_newer->name_based_older = name_based_older;
 
-       objectset* os = ov->on->os;
-       if (!newer) {
+       objectset* os = ov->name_based_chain->os;
+       if (!name_based_newer) {
                object_node *on = NULL;
                if (os->unique)
                        on = find_name(os, ov->obj->name);
@@ -262,41 +329,158 @@ objectversion_destroy(sqlstore *store, o
                        on = find_id(os, ov->obj->id);
                assert(on->data == ov);
                if (on)
-                       os_remove_node(os, on);
-               if (older)
-                       os_append(os, older);
+                       os_remove_name_based_chain(os, on);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to