Changeset: 4dfdb7782e4c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4dfdb7782e4c
Modified Files:
sql/storage/objectset.c
Branch: nospare
Log Message:
Start transforming objectset into a double linked list.
diffs (truncated from 480 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
@@ -25,20 +25,31 @@ typedef struct objectversion {
struct objectset *os;
} objectversion;
+typedef struct object_node {
+ struct object_node* prev;
+ struct object_node* next;
+ void* data;
+} object_node;
+
typedef struct objectset {
int refcnt;
sql_allocator *sa;
destroy_fptr destroy;
- struct list *objs;
+ MT_Lock ht_lock; /* latch protecting ht */
+ object_node *h;
+ object_node *t;
+ int cnt;
+ struct sql_hash *name_map;
+ struct sql_hash *id_map;
bool temporary;
bool unique; /* names are unique */
} objectset;
-static node *
-find_id(list *l, sqlid id)
+static object_node *
+find_id(objectset *os, sqlid id)
{
- if (l) {
- for (node *n = l->h; n; n = n->next) {
+ if (os) {
+ for (object_node *n = os->h; n; n = n->next) {
objectversion *ov = n->data;
/* check if ids match */
@@ -50,6 +61,132 @@ find_id(list *l, sqlid id)
return NULL;
}
+// TODO copy of static function from sql_list.c. Needs to be made external
+static void
+hash_delete(sql_hash *h, void *data)
+{
+ int key = h->key(data);
+ sql_hash_e *e, *p = h->buckets[key&(h->size-1)];
+
+ e = p;
+ for (; p && p->value != data ; p = p->chain)
+ e = p;
+ if (p && p->value == data) {
+ if (p == e)
+ h->buckets[key&(h->size-1)] = p->chain;
+ else
+ e->chain = p->chain;
+ }
+}
+
+// TODO: check double hash_delete and fix prev pointer
+static object_node *
+os_remove_node_(objectset *os, object_node *n)
+{
+ void *data = n->data;
+ object_node *p = os->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;
+ p = NULL;
+ } else if ( p != NULL) {
+ p->next = n->next;
+ }
+ if (n == os->t)
+ os->t = p;
+ if (data) {
+ MT_lock_set(&os->ht_lock);
+ if (os->id_map && data)
+ hash_delete(os->id_map, data);
+ if (os->name_map && data)
+ hash_delete(os->name_map, data);
+ MT_lock_unset(&os->ht_lock);
+ }
+ os->cnt--;
+ assert(os->cnt > 0 || os->h == NULL);
+ return p;
+}
+
+static void
+node_destroy(objectset *os, object_node *n)
+{
+ if (n->data && os->destroy) {
+ os->destroy(NULL, n->data);
+ n->data = NULL;
+ }
+ if (!os->sa)
+ _DELETE(n);
+}
+
+static object_node *
+os_remove_node(objectset *l, object_node *n)
+{
+ object_node *p = os_remove_node_(l, n);
+
+ node_destroy(l, n);
+ return p;
+}
+
+static object_node *
+node_create(sql_allocator *sa, void *data)
+{
+ object_node *n = (sa)?SA_NEW(sa, object_node):MNEW(object_node);
+
+ if (n == NULL)
+ return NULL;
+ *n = (object_node) {
+ .data = data,
+ };
+ return n;
+}
+
+static objectset *
+os_append_node(objectset *os, object_node *n)
+{
+ if (os->cnt) {
+ os->t->next = n;
+ } else {
+ os->h = n;
+ }
+ os->t = n;
+ os->cnt++;
+ if (n->data) {
+ MT_lock_set(&os->ht_lock);
+ if (os->name_map) {
+ int key = os->name_map->key(n->data);
+
+ if (hash_add(os->name_map, key, n->data) == NULL) {
+ MT_lock_unset(&os->ht_lock);
+ return NULL;
+ }
+ }
+ if (os->id_map) {
+ int key = os->id_map->key(n->data);
+
+ if (hash_add(os->id_map, key, n->data) == NULL) {
+ MT_lock_unset(&os->ht_lock);
+ return NULL;
+ }
+ }
+ MT_lock_unset(&os->ht_lock);
+ }
+ return os;
+}
+
+static objectset *
+os_append(objectset *os, void *data)
+{
+ object_node *n = node_create(os->sa, data);
+
+ if (n == NULL)
+ return NULL;
+ return os_append_node(os, n);
+}
+
static void
objectversion_destroy(sqlstore *store, objectversion *ov, ulng commit_ts, ulng
oldest)
{
@@ -70,12 +207,12 @@ objectversion_destroy(sqlstore *store, o
newer->older = older;
if (!newer && ov->os) {
- node *on = find_id(ov->os->objs, ov->obj->id);
+ object_node *on = find_id(ov->os, ov->obj->id);
assert(on->data == ov);
if (on)
- list_remove_node(ov->os->objs, on);
+ os_remove_node(ov->os, on);
if (older)
- list_append(ov->os->objs, older);
+ os_append(ov->os, older);
}
if (ov && ov->os && ov->os->destroy)
ov->os->destroy(store, ov->obj);
@@ -117,7 +254,7 @@ os_new(sql_allocator *sa, destroy_fptr d
os->refcnt = 1;
os->sa = sa;
os->destroy = destroy;
- os->objs = list_new(sa, NULL);
+ MT_lock_init(&os->ht_lock, "sa_ht_lock");
os->temporary = temporary;
os->unique = unique;
return os;
@@ -130,17 +267,38 @@ os_dup(objectset *os)
return os;
}
+// TODO: Look into cohesion between os_destroy, os->destroy and and
node_destroy
void
os_destroy(objectset *os, sql_store store)
{
if (--os->refcnt > 0)
return;
if (os->destroy) {
- for(node *n=os->objs->h; n; n=n->next) {
+ for(object_node *n=os->h; n; n=n->next) {
os->destroy(store, n->data);
}
}
- list_destroy(os->objs);
+ object_node *n = os->h;
+
+ MT_lock_destroy(&os->ht_lock);
+ os->h = NULL;
+ if (os->destroy || os->sa == NULL) {
+ while (n) {
+ object_node *t = n;
+
+ n = t->next;
+ node_destroy(os, t);
+ }
+ }
+
+ if (os->name_map && !os->name_map->sa)
+ hash_destroy(os->name_map);
+
+ if (os->id_map && !os->id_map->sa)
+ hash_destroy(os->id_map);
+
+ if (!os->sa)
+ _DELETE(os);
}
static int
@@ -149,46 +307,68 @@ ov_key(objectversion *ov)
return base_key(ov->obj);
}
-static node *
-find_name(list *l, const char *name)
+static object_node *
+os_find(objectset *os, void *key, fcmp cmp)
{
- node *n;
+ object_node *n = NULL;
- if (l) {
- MT_lock_set(&l->ht_lock);
- if ((!l->ht || l->ht->size*16 < list_length(l)) &&
list_length(l) > HASH_MIN_SIZE && l->sa) {
- l->ht = hash_new(l->sa, list_length(l),
(fkeyvalue)&ov_key);
- if (l->ht == NULL) {
- MT_lock_unset(&l->ht_lock);
+ if (key) {
+ if (cmp) {
+ for (n = os->h; n; n = n->next) {
+ if (cmp(n->data, key) == 0) {
+ return n;
+ }
+ }
+ } else {
+ for (n = os->h; n; n = n->next) {
+ if (n->data == key)
+ return n;
+ }
+ }
+ }
+ return NULL;
+}
+
+static object_node *
+find_name(objectset *os, const char *name)
+{
+ object_node *n;
+
+ if (os) {
+ MT_lock_set(&os->ht_lock);
+ if ((!os->name_map || os->name_map->size*16 < os->cnt) &&
os->cnt > HASH_MIN_SIZE && os->sa) {
+ os->name_map = hash_new(os->sa, os->cnt,
(fkeyvalue)&ov_key);
+ if (os->name_map == NULL) {
+ MT_lock_unset(&os->ht_lock);
return NULL;
}
- for (n = l->h; n; n = n->next ) {
+ for (n = os->h; n; n = n->next ) {
int key = ov_key(n->data);
- if (hash_add(l->ht, key, n->data) == NULL) {
- MT_lock_unset(&l->ht_lock);
+ if (hash_add(os->name_map, key, n->data) ==
NULL) {
+ MT_lock_unset(&os->ht_lock);
return NULL;
}
}
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list