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