fix impl of gte/lte

This commit is contained in:
Gregory Burd 2024-03-19 14:24:33 -04:00
parent d304eaf407
commit 6e97787aa3
2 changed files with 36 additions and 43 deletions

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -125,6 +126,18 @@ main()
q.key = 0; q.key = 0;
api_skip_remove_slex(list, &q); api_skip_remove_slex(list, &q);
assert(api_skip_gte_slex(list, -3) == -20);
assert(api_skip_gte_slex(list, -2) == -20);
assert(api_skip_gte_slex(list, 0) == 10);
assert(api_skip_gte_slex(list, 2) == 20);
assert(api_skip_gte_slex(list, 3) == 0);
assert(api_skip_lte_slex(list, -3) == 0);
assert(api_skip_lte_slex(list, -2) == -20);
assert(api_skip_lte_slex(list, 0) == -10);
assert(api_skip_lte_slex(list, 2) == 20);
assert(api_skip_lte_slex(list, 3) == 20);
FILE *of = fopen("/tmp/slm.dot", "w"); FILE *of = fopen("/tmp/slm.dot", "w");
if (!of) { if (!of) {
perror("Failed to open file /tmp/slm.dot"); perror("Failed to open file /tmp/slm.dot");
@ -135,33 +148,6 @@ main()
api_skip_destroy_slex(list); api_skip_destroy_slex(list);
#if 0
/* Delete a specific element in the list. */
struct slex_node query;
query.key = 4;
struct slex_node *removed = SKIP_REMOVE(list, q, entries);
free(removed);
/* Forward traversal. */
SKIP_FOREACH(np, &head, entries)
np-> ...
/* Reverse traversal. */
SKIP_FOREACH_REVERSE(np, &head, skiphead, entries)
np-> ...
/* Skiplist Deletion. */
while (!SKIP_EMPTY(&head)) {
n1 = SKIP_FIRST(&head);
SKIP_REMOVE(&head, n1, entries);
free(n1);
}
/* Faster Skiplist Deletion. */
n1 = SKIP_FIRST(&head);
while (n1 != NULL) {
n2 = SKIP_NEXT(n1, entries);
free(n1);
n1 = n2;
}
SKIP_INIT(&head);
#endif
fail:; fail:;
return rc; return rc;
} }

View file

@ -249,7 +249,7 @@
decl##_node_t **path; \ decl##_node_t **path; \
decl##_node_t *elm = slist->slh_head; \ decl##_node_t *elm = slist->slh_head; \
\ \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
\ \
i = slist->max + 1; \ i = slist->max + 1; \
@ -349,10 +349,9 @@
unsigned int i; \ unsigned int i; \
decl##_node_t *elm = slist->slh_head; \ decl##_node_t *elm = slist->slh_head; \
\ \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
\ \
i = slist->max + 1; \
i = slist->level; \ i = slist->level; \
\ \
do { \ do { \
@ -374,13 +373,13 @@
decl##_node_t *prefix##skip_find_gte_##decl(decl##_t *slist, \ decl##_node_t *prefix##skip_find_gte_##decl(decl##_t *slist, \
decl##_node_t *n) \ decl##_node_t *n) \
{ \ { \
int cmp; \
unsigned int i; \ unsigned int i; \
decl##_node_t *elm = slist->slh_head; \ decl##_node_t *elm = slist->slh_head; \
\ \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
\ \
i = slist->max + 1; \
i = slist->level; \ i = slist->level; \
\ \
do { \ do { \
@ -389,7 +388,10 @@
slist->aux) < 0) \ slist->aux) < 0) \
elm = elm->field.sle_next[i]; \ elm = elm->field.sle_next[i]; \
} while (i--); \ } while (i--); \
elm = elm->field.sle_next[0]; \ do { \
elm = elm->field.sle_next[0]; \
cmp = __skip_key_compare_##decl(slist, elm, n, slist->aux); \
} while (cmp < 0); \
return elm; \ return elm; \
} \ } \
\ \
@ -399,13 +401,13 @@
decl##_node_t *prefix##skip_find_lte_##decl(decl##_t *slist, \ decl##_node_t *prefix##skip_find_lte_##decl(decl##_t *slist, \
decl##_node_t *n) \ decl##_node_t *n) \
{ \ { \
int cmp; \
unsigned int i; \ unsigned int i; \
decl##_node_t *elm = slist->slh_head; \ decl##_node_t *elm = slist->slh_head; \
\ \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
\ \
i = slist->max + 1; \
i = slist->level; \ i = slist->level; \
\ \
do { \ do { \
@ -414,9 +416,14 @@
slist->aux) < 0) \ slist->aux) < 0) \
elm = elm->field.sle_next[i]; \ elm = elm->field.sle_next[i]; \
} while (i--); \ } while (i--); \
if (__skip_key_compare_##decl(slist, elm->field.sle_next[0], n, \ elm = elm->field.sle_next[0]; \
slist->aux) == 0) { \ if (__skip_key_compare_##decl(slist, elm, n, slist->aux) == 0) { \
return elm->field.sle_next[0]; \ return elm; \
} else { \
do { \
elm = elm->field.sle_prev; \
cmp = __skip_key_compare_##decl(slist, elm, n, slist->aux); \
} while (cmp > 0); \
} \ } \
return elm; \ return elm; \
} \ } \
@ -431,7 +438,7 @@
{ \ { \
decl##_node_t *node; \ decl##_node_t *node; \
\ \
if (!slist || !new) \ if (slist == NULL || new == NULL) \
return -1; \ return -1; \
\ \
node = prefix##skip_find_##decl(slist, new); \ node = prefix##skip_find_##decl(slist, new); \
@ -448,7 +455,7 @@
size_t i, s; \ size_t i, s; \
decl##_node_t **path, *node; \ decl##_node_t **path, *node; \
\ \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return -1; \ return -1; \
if (slist->length == 0) \ if (slist->length == 0) \
return 0; \ return 0; \
@ -484,7 +491,7 @@
decl##_node_t *prefix##skip_next_node_##decl(decl##_t *slist, \ decl##_node_t *prefix##skip_next_node_##decl(decl##_t *slist, \
decl##_node_t *n) \ decl##_node_t *n) \
{ \ { \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
if (n->field.sle_next[0] == slist->slh_tail) \ if (n->field.sle_next[0] == slist->slh_tail) \
return NULL; \ return NULL; \
@ -495,7 +502,7 @@
decl##_node_t *prefix##skip_prev_node_##decl(decl##_t *slist, \ decl##_node_t *prefix##skip_prev_node_##decl(decl##_t *slist, \
decl##_node_t *n) \ decl##_node_t *n) \
{ \ { \
if (!slist || !n) \ if (slist == NULL || n == NULL) \
return NULL; \ return NULL; \
if (n->field.sle_prev == slist->slh_head) \ if (n->field.sle_prev == slist->slh_head) \
return NULL; \ return NULL; \
@ -506,7 +513,7 @@
int prefix##skip_destroy_##decl(decl##_t *slist) \ int prefix##skip_destroy_##decl(decl##_t *slist) \
{ \ { \
decl##_node_t *node, *next; \ decl##_node_t *node, *next; \
if (!slist) \ if (slist == NULL) \
return 0; \ return 0; \
if (prefix##skip_size_##decl(slist) == 0) \ if (prefix##skip_size_##decl(slist) == 0) \
return 0; \ return 0; \