working on it...

This commit is contained in:
Gregory Burd 2024-03-19 21:33:43 -04:00
parent 6e97787aa3
commit 03790de272
2 changed files with 219 additions and 190 deletions

View file

@ -143,7 +143,7 @@ main()
perror("Failed to open file /tmp/slm.dot"); perror("Failed to open file /tmp/slm.dot");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
api_skip_dot_slex(of, list, sprintf_slex_node); api_skip_dot_slex(of, list, 0, sprintf_slex_node);
fclose(of); fclose(of);
api_skip_destroy_slex(list); api_skip_destroy_slex(list);

View file

@ -277,8 +277,9 @@
return NULL; \ return NULL; \
} \ } \
\ \
/* -- skip_insert_ */ \ /* -- __skip_insert_ */ \
int prefix##skip_insert_##decl(decl##_t *slist, decl##_node_t *n) \ static int __skip_insert_##decl(decl##_t *slist, decl##_node_t *n, \
int flags) \
{ \ { \
unsigned int i; \ unsigned int i; \
decl##_node_t *prev, *elm = slist->slh_head; \ decl##_node_t *prev, *elm = slist->slh_head; \
@ -305,10 +306,12 @@
prev = elm; \ prev = elm; \
elm = elm->field.sle_next[0]; \ elm = elm->field.sle_next[0]; \
if (__skip_key_compare_##decl(slist, elm, n, slist->aux) == 0) { \ if (__skip_key_compare_##decl(slist, elm, n, slist->aux) == 0) { \
if (flags == 0) { \
/* Don't overwrite, to do that use _REPLACE not _INSERT */ \ /* Don't overwrite, to do that use _REPLACE not _INSERT */ \
ARRAY_FREE(path); \ ARRAY_FREE(path); \
return -1; \ return -1; \
} \ } \
} \
size_t level = __skip_toss_##decl(slist->max, slist->fanout); \ size_t level = __skip_toss_##decl(slist->max, slist->fanout); \
ARRAY_SET_LENGTH(n->field.sle_next, level); \ ARRAY_SET_LENGTH(n->field.sle_next, level); \
if (level > slist->level) { \ if (level > slist->level) { \
@ -330,14 +333,17 @@
return 0; \ return 0; \
} \ } \
\ \
/* -- skip_insert_dup_ TODO \ /* -- skip_insert_ */ \
int prefix##skip_insert_##decl(decl##_t *slist, decl##_node_t *n) \
{ \
return __skip_insert_##decl(slist, n, 0); \
} \
\
/* -- skip_insert_dup_ */ \
int prefix##skip_insert_dup_##decl(decl##_t *slist, decl##_node_t *n) \ int prefix##skip_insert_dup_##decl(decl##_t *slist, decl##_node_t *n) \
{ \ { \
((void)slist); \ return __skip_insert_##decl(slist, n, 1); \
((void)n); \
return 0; \
} \ } \
*/ \
\ \
/* -- skip_find_ \ /* -- skip_find_ \
* Find a node that matches another node. This differs from the locate() \ * Find a node that matches another node. This differs from the locate() \
@ -477,7 +483,7 @@
ARRAY_FREE(path); \ ARRAY_FREE(path); \
free_node_blk; \ free_node_blk; \
/* Find all levels in the first element in the list that point \ /* Find all levels in the first element in the list that point \
at the tail and shrink the level*/ \ at the tail and shrink the level. */ \
while (slist->level > 0 && \ while (slist->level > 0 && \
slist->slh_head->field.sle_next[slist->level] == slist->slh_tail) { \ slist->slh_head->field.sle_next[slist->level] == slist->slh_tail) { \
slist->level--; \ slist->level--; \
@ -531,6 +537,31 @@
return 0; \ return 0; \
} \ } \
\ \
/* -- skip_snapshot_ \
* A snapshot is a read-only view of a Skiplist at a point in \
* time. Once taken, a snapshot must be restored or disposed. \
* Any number of snapshots can be created. \
*/ \
int prefix##skip_snapshot_##decl(decl##_t *slist) \
{ \
((void)slist); /* TODO */ \
return 0; \
} \
\
/* -- skip_restore_snapshot_ */ \
int prefix##skip_restore_snapshot_##decl(decl##_t *slist) \
{ \
((void)slist); /* TODO */ \
return 0; \
} \
\
/* -- skip_dispose_snapshot_ */ \
int prefix##skip_dispose_snapshot_##decl(decl##_t *slist) \
{ \
((void)slist); /* TODO */ \
return 0; \
} \
\
/* -- __skip_integrity_check_ */ \ /* -- __skip_integrity_check_ */ \
static int __skip_integrity_check_##decl(decl##_t *slist) \ static int __skip_integrity_check_##decl(decl##_t *slist) \
{ \ { \
@ -586,15 +617,15 @@
decl##_node_t *node, size_t nsg, skip_sprintf_node_##decl##_t fn) \ decl##_node_t *node, size_t nsg, skip_sprintf_node_##decl##_t fn) \
{ \ { \
char buf[2048]; \ char buf[2048]; \
size_t level, height = ARRAY_LENGTH(node->field.sle_next); \ size_t level, height = ARRAY_LENGTH(node->field.sle_next) - 1; \
decl##_node_t *next; \
\
fprintf(os, "\"node%zu %p\"", nsg, (void *)node); \ fprintf(os, "\"node%zu %p\"", nsg, (void *)node); \
fprintf(os, " [label = \""); \ fprintf(os, " [label = \""); \
level = height; \ level = height; \
do { \ do { \
fprintf(os, " { <w%zu> | <f%zu> %p }", level + 1, level + 1, \ fprintf(os, " { <w%zu> | <f%zu> %p } |", level, level, \
(void *)node->field.sle_next[level]); \ (void *)node->field.sle_next[level]); \
if (level != 0) \
fprintf(os, " | "); \
} while (level--); \ } while (level--); \
if (fn) { \ if (fn) { \
fn(node, buf); \ fn(node, buf); \
@ -609,17 +640,17 @@
level = 0; \ level = 0; \
for (level = 0; level < height; level++) { \ for (level = 0; level < height; level++) { \
fprintf(os, "\"node%zu %p\"", nsg, (void *)node); \ fprintf(os, "\"node%zu %p\"", nsg, (void *)node); \
fprintf(os, ":f%zu -> ", level + 1); \ fprintf(os, ":f%zu -> ", level); \
fprintf(os, "\"node%zu %p\"", nsg, (void *)node->field.sle_next[level]); \ fprintf(os, "\"node%zu %p\"", nsg, (void *)node->field.sle_next[level]); \
fprintf(os, ":w%zu [];\n", level + 1); \ fprintf(os, ":w%zu [];\n", level); \
} \ } \
\ next = prefix##skip_next_node_##decl(slist, node); \
if (node->field.sle_next[0] != SKIP_LAST(slist)) \ if (next) \
__skip_dot_node_##decl(os, slist, node->field.sle_next[0], nsg, fn); \ __skip_dot_node_##decl(os, slist, next, nsg, fn); \
} \ } \
\ \
/* -- __skip_dot_finish_ \ /* -- __skip_dot_finish_ \
* Finalise the DOT file of the internal representation. \ * Finalize the DOT file of the internal representation. \
*/ \ */ \
static void __skip_dot_finish_##decl(FILE *os, size_t nsg) \ static void __skip_dot_finish_##decl(FILE *os, size_t nsg) \
{ \ { \
@ -645,7 +676,6 @@
} \ } \
nsg = 0; \ nsg = 0; \
} \ } \
fprintf(os, "}\n"); \
} \ } \
\ \
/* -- skip_dot_start_ */ \ /* -- skip_dot_start_ */ \
@ -672,13 +702,13 @@
if (SKIP_EMPTY(slist)) \ if (SKIP_EMPTY(slist)) \
fprintf(os, "Empty HeadNode"); \ fprintf(os, "Empty HeadNode"); \
else { \ else { \
level = ARRAY_LENGTH(head->field.sle_next); \ level = ARRAY_LENGTH(head->field.sle_next) - 1; \
while (level--) { \ do { \
decl##_node_t *node = head->field.sle_next[level]; \ decl##_node_t *node = head->field.sle_next[level]; \
fprintf(os, "{ <f%zu> %p }", level + 1, (void *)node); \ fprintf(os, "{ <f%zu> %p }", level, (void *)node); \
if (level + 1 != 0) \ if (level) \
fprintf(os, " | "); \ fprintf(os, " | "); \
} \ } while (level--); \
} \ } \
fprintf(os, "\"\n"); \ fprintf(os, "\"\n"); \
fprintf(os, "shape = \"record\"\n"); \ fprintf(os, "shape = \"record\"\n"); \
@ -688,15 +718,15 @@
decl##_node_t *node = slist->slh_head; \ decl##_node_t *node = slist->slh_head; \
level = 0; \ level = 0; \
do { \ do { \
fprintf(os, "\"HeadNode%zu\":f%zu -> ", nsg, level + 1); \ fprintf(os, "\"HeadNode%zu\":f%zu -> ", nsg, level); \
fprintf(os, "\"node%zu %p\"", nsg, (void *)node->field.sle_next[level]); \ fprintf(os, "\"node%zu %p\"", nsg, (void *)node->field.sle_next[level]); \
fprintf(os, ":w%zu [];\n", level + 1); \ fprintf(os, ":w%zu [];\n", level); \
} while (level++ < slist->level); \ } while (++level < slist->level); \
fprintf(os, "}\n\n"); \ fprintf(os, "}\n\n"); \
\ \
/* Now all nodes via level 0, if non-empty */ \ /* Now all nodes via level 0, if non-empty */ \
node = slist->slh_head; \ node = prefix##skip_head_##decl(slist); \
if (ARRAY_LENGTH(node->field.sle_next)) \ if (node) \
__skip_dot_node_##decl(os, slist, node->field.sle_next[0], nsg, fn); \ __skip_dot_node_##decl(os, slist, node->field.sle_next[0], nsg, fn); \
fprintf(os, "\n"); \ fprintf(os, "\n"); \
\ \
@ -705,18 +735,18 @@
fprintf(os, "\"node%zu 0x0\" [label = \"", nsg); \ fprintf(os, "\"node%zu 0x0\" [label = \"", nsg); \
level = slist->level; \ level = slist->level; \
do { \ do { \
fprintf(os, "<w%zu> NULL", level + 1); \ fprintf(os, "<w%zu> NULL", level); \
if (level != 0) \ if (level) \
fprintf(os, " | "); \ fprintf(os, " | "); \
} while (level-- > 0); \ } while (--level); \
fprintf(os, "\" shape = \"record\"];\n"); \ fprintf(os, "\" shape = \"record\"];\n"); \
} \ } \
\ \
/* End: "subgraph cluster1 {" */ \ /* End: "subgraph cluster0 {" */ \
fprintf(os, "}\n\n"); \ fprintf(os, "}\n\n"); \
nsg += 1; \ nsg += 1; \
\ \
return 0; \ return nsg; \
} \ } \
\ \
/* -- skip_dot_ \ /* -- skip_dot_ \
@ -731,10 +761,9 @@
* \ * \
* https://en.wikipedia.org/wiki/DOT_(graph_description_language) \ * https://en.wikipedia.org/wiki/DOT_(graph_description_language) \
*/ \ */ \
int prefix##skip_dot_##decl(FILE *os, decl##_t *slist, \ int prefix##skip_dot_##decl(FILE *os, decl##_t *slist, size_t nsg, \
skip_sprintf_node_##decl##_t fn) \ skip_sprintf_node_##decl##_t fn) \
{ \ { \
size_t nsg = 0; \
if (__skip_integrity_check_##decl(slist) != 0) { \ if (__skip_integrity_check_##decl(slist) != 0) { \
perror("Skiplist failed integrity checks, impossible to diagram."); \ perror("Skiplist failed integrity checks, impossible to diagram."); \
return -1; \ return -1; \