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 checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list