From ce1fd99c3e4f85d7955a4ca40fb73b7abd36cbe9 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sat, 23 Mar 2024 12:27:41 -0400 Subject: [PATCH] snapshot v2/p6; update --- examples/slm.c | 2 +- include/sl.h | 49 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/examples/slm.c b/examples/slm.c index b2dcceb..a6e9dae 100644 --- a/examples/slm.c +++ b/examples/slm.c @@ -53,7 +53,7 @@ SKIPLIST_DECL( new->key = node->key; char *nv = calloc(strlen(node->value) + 1, sizeof(char)); if (nv == NULL) - return NULL; // leaks some memory... TODO + rc = ENOMEM; // leaks some memory... TODO new->value = strncpy(nv, node->value, strlen(node->value)); }, /* size in bytes of the content stored in an entry by you */ diff --git a/include/sl.h b/include/sl.h index 72d512e..79c41aa 100644 --- a/include/sl.h +++ b/include/sl.h @@ -776,21 +776,48 @@ * Locates a node in the list that equals the `new` node and then \ * uses the `update_node_blk` to update the contents. \ * \ - * \ * WARNING: Do not update the portion of the node used for ordering \ * (e.g. `key`) unless you really know what you're doing. \ */ \ - int prefix##skip_update_##decl(decl##_t *slist, decl##_node_t *new) \ + int prefix##skip_update_##decl(decl##_t *slist, decl##_node_t *n) \ { \ - decl##_node_t *node; \ + static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \ + int np, rc = 0; \ + size_t len; \ + decl##_node_t *node, *new, **path = (decl##_node_t **)&apath; \ \ - if (slist == NULL || new == NULL) \ + if (slist == NULL || n == NULL) \ return -1; \ \ - node = prefix##skip_position_eq_##decl(slist, new); \ + /* Allocate a buffer */ \ + if (SKIPLIST_MAX_HEIGHT == 1) { \ + path = malloc(sizeof(decl##_node_t *) * slist->max + 1); \ + if (path == NULL) \ + return ENOMEM; \ + } \ + \ + len = __skip_locate_##decl(slist, n, path); \ + node = path[0]; \ + \ + if (SKIPLIST_MAX_HEIGHT == 1) \ + free(path); \ + \ if (node) { \ + np = __skip_preserve_##decl(slist, path, len); \ + if (np > 0) \ + return np; \ + if (np < 0 && node->field.sle.gen < slist->gen) { \ + /* find the new node which was path[0], so the np'th in the \ + slh_pres linked list */ \ + new = slist->slh_pres; \ + while (np++ < 0) \ + new = new->field.sle.next[0]; \ + new->field.sle.prev = (decl##_node_t *)0x1; \ + archive_node_blk; \ + } \ + new = n; \ update_node_blk; \ - return 0; \ + return rc; \ } \ return -1; \ } \ @@ -892,7 +919,9 @@ node = slist->slh_pres; \ while (node) { \ next = node->field.sle.next[0]; \ - prefix##skip_free_node_##decl(node); \ + if (next->field.sle.prev) \ + free_node_blk; \ + free(node); \ } \ \ free(slist->slh_head); \ @@ -964,6 +993,7 @@ prefix##skip_free_node_##decl(node); \ } \ if (node->field.sle.gen == gen) { \ + node->field.sle.prev = NULL; \ if (node->field.sle.next[1] != 0) { \ node->field.sle.next[1] = NULL; \ prefix##skip_insert_dup_##decl(slist, node); \ @@ -1022,12 +1052,13 @@ */ \ decl##_archive_t *prefix##skip_to_bytes_##decl(decl##_t *slist) \ { \ + int rc = 0; \ size_t size, bytes, i; \ decl##_archive_t *archive; \ decl##_node_t *node, *new; \ \ if (slist == NULL) \ - return 0; \ + return NULL; \ \ bytes = sizeof(decl##_archive_t) + (slist->length * sizeof(decl##_node_t)); \ node = prefix##skip_head_##decl(slist); \ @@ -1052,6 +1083,8 @@ decl##_node_t *n = (decl##_node_t *)archive->nodes + (i++ * sizeof(decl##_node_t)); \ new = (decl##_node_t *)&n; \ archive_node_blk; \ + if (rc) \ + return NULL; \ node = prefix##skip_next_node_##decl(slist, node); \ } \ return archive; \