add struct for levels within entry in node, lots of renaming
This commit is contained in:
parent
52c85316f6
commit
d725cfc297
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
// Local demo application OPTIONS:
|
// Local demo application OPTIONS:
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
#define TEST_ARRAY_SIZE 50
|
#define TEST_ARRAY_SIZE 1000
|
||||||
#define VALIDATE
|
#define VALIDATE
|
||||||
#define SNAPSHOTS
|
//define SNAPSHOTS
|
||||||
#define DOT
|
//define DOT
|
||||||
#ifdef DOT
|
#ifdef DOT
|
||||||
size_t gen = 0;
|
size_t gen = 0;
|
||||||
FILE *of = 0;
|
FILE *of = 0;
|
||||||
|
@ -182,7 +182,7 @@ SKIPLIST_DECL_DOT(esempio, api_, entries)
|
||||||
void
|
void
|
||||||
sprintf_esempio_node(esempio_node_t *node, char *buf)
|
sprintf_esempio_node(esempio_node_t *node, char *buf)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%d:%s (hits: %lu)", node->key, node->value, node->entries.sle_hits);
|
sprintf(buf, "%d:%s (hits: %lu)", node->key, node->value, node->entries.sle_levels[0]->hits);
|
||||||
//TODO sprintf(buf, "%d:%s", node->key, node->value);
|
//TODO sprintf(buf, "%d:%s", node->key, node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,10 @@ int_to_roman_numeral(int num)
|
||||||
res[0] = '0';
|
res[0] = '0';
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
if (num > 10000) {
|
||||||
|
sprintf(res, "The person you were looking for is not here, their mailbox is full, good bye.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
while (num) { // while input number is not zero
|
while (num) { // while input number is not zero
|
||||||
while (num / del[i]) { // while a number contains the largest key value possible
|
while (num / del[i]) { // while a number contains the largest key value possible
|
||||||
strcat(res, sym[i]); // append the symbol for this key value to res string
|
strcat(res, sym[i]); // append the symbol for this key value to res string
|
||||||
|
|
187
include/sl.h
187
include/sl.h
|
@ -204,10 +204,13 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
*/
|
*/
|
||||||
#define SKIPLIST_ENTRY(decl) \
|
#define SKIPLIST_ENTRY(decl) \
|
||||||
struct __skiplist_##decl##_entry { \
|
struct __skiplist_##decl##_entry { \
|
||||||
struct decl##_node *sle_prev, **sle_next; \
|
|
||||||
size_t sle_height; \
|
|
||||||
size_t sle_era; \
|
size_t sle_era; \
|
||||||
size_t sle_hits; \
|
size_t sle_height; \
|
||||||
|
struct decl##_node *sle_prev; \
|
||||||
|
struct __skiplist_##decl##_level { \
|
||||||
|
struct decl##_node *next; \
|
||||||
|
size_t hits; \
|
||||||
|
} **sle_levels; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SKIPLIST_FOREACH_H2T(decl, prefix, list, elm, iter) \
|
#define SKIPLIST_FOREACH_H2T(decl, prefix, list, elm, iter) \
|
||||||
|
@ -231,9 +234,9 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
|
|
||||||
/* Iterate over the subtree to the left (v, or 'lt') and right (u) or "CHu" and "CHv". */
|
/* Iterate over the subtree to the left (v, or 'lt') and right (u) or "CHu" and "CHv". */
|
||||||
#define __SKIP_SUBTREE_CHv(decl, field, list, path, nth) \
|
#define __SKIP_SUBTREE_CHv(decl, field, list, path, nth) \
|
||||||
for (decl##_node_t *elm = path[nth].node; elm->field.sle_next[path[nth].in] == path[nth].node; elm = elm->field.sle_prev)
|
for (decl##_node_t *elm = path[nth].node; elm->field.sle_levels[path[nth].in]->next == path[nth].node; elm = elm->field.sle_prev)
|
||||||
#define __SKIP_SUBTREE_CHu(decl, field, list, path, nth) \
|
#define __SKIP_SUBTREE_CHu(decl, field, list, path, nth) \
|
||||||
for (decl##_node_t *elm = path[nth].node; elm != path[nth].node->field.sle_next[0]; elm = elm->field.sle_next[0])
|
for (decl##_node_t *elm = path[nth].node; elm != path[nth].node->field.sle_levels[0]->next; elm = elm->field.sle_levels[0]->next)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skiplist declarations and access methods.
|
* Skiplist declarations and access methods.
|
||||||
|
@ -394,12 +397,12 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
decl##_node_t *n; \
|
decl##_node_t *n; \
|
||||||
/* Calculate the size of the struct sle within decl##_node_t, multiply \
|
/* Calculate the size of the struct sle within decl##_node_t, multiply \
|
||||||
by array size. (16/24 bytes on 32/64 bit systems) */ \
|
by array size. (16/24 bytes on 32/64 bit systems) */ \
|
||||||
size_t sle_arr_sz = sizeof(struct __skiplist_##decl##_entry) * slist->slh_max_height; \
|
size_t sle_arr_sz = sizeof(struct __skiplist_##decl##_level) * slist->slh_max_height; \
|
||||||
n = (decl##_node_t *)calloc(1, sizeof(decl##_node_t) + sle_arr_sz); \
|
n = (decl##_node_t *)calloc(1, sizeof(decl##_node_t) + sle_arr_sz); \
|
||||||
if (n == NULL) \
|
if (n == NULL) \
|
||||||
return ENOMEM; \
|
return ENOMEM; \
|
||||||
n->field.sle_height = 0; \
|
n->field.sle_height = 0; \
|
||||||
n->field.sle_next = (decl##_node_t **)((uintptr_t)n + sizeof(decl##_node_t)); \
|
n->field.sle_levels = (struct __skiplist_##decl##_level **)((uintptr_t)n + sizeof(decl##_node_t)); \
|
||||||
*node = n; \
|
*node = n; \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
|
@ -432,12 +435,12 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
slist->slh_head->field.sle_height = floor(log(slist->slh_max_height) / M_LOG2E); \
|
slist->slh_head->field.sle_height = floor(log(slist->slh_max_height) / M_LOG2E); \
|
||||||
for (i = 0; i < slist->slh_max_height; i++) \
|
for (i = 0; i < slist->slh_max_height; i++) \
|
||||||
slist->slh_head->field.sle_next[i] = slist->slh_tail; \
|
slist->slh_head->field.sle_levels[i]->next = slist->slh_tail; \
|
||||||
slist->slh_head->field.sle_prev = NULL; \
|
slist->slh_head->field.sle_prev = NULL; \
|
||||||
\
|
\
|
||||||
slist->slh_tail->field.sle_height = slist->slh_head->field.sle_height; \
|
slist->slh_tail->field.sle_height = slist->slh_head->field.sle_height; \
|
||||||
for (i = 0; i < slist->slh_max_height; i++) \
|
for (i = 0; i < slist->slh_max_height; i++) \
|
||||||
slist->slh_tail->field.sle_next[i] = NULL; \
|
slist->slh_tail->field.sle_levels[i]->next = NULL; \
|
||||||
slist->slh_tail->field.sle_prev = slist->slh_head; \
|
slist->slh_tail->field.sle_prev = slist->slh_head; \
|
||||||
\
|
\
|
||||||
/* NOTE: Here's a testing aid, simply set `max` to a negative number to \
|
/* NOTE: Here's a testing aid, simply set `max` to a negative number to \
|
||||||
|
@ -493,7 +496,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
*/ \
|
*/ \
|
||||||
decl##_node_t *prefix##skip_head_##decl(decl##_t *slist) \
|
decl##_node_t *prefix##skip_head_##decl(decl##_t *slist) \
|
||||||
{ \
|
{ \
|
||||||
return slist->slh_head->field.sle_next[0] == slist->slh_tail ? NULL : slist->slh_head->field.sle_next[0]; \
|
return slist->slh_head->field.sle_levels[0]->next == slist->slh_tail ? NULL : slist->slh_head->field.sle_levels[0]->next; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/** \
|
/** \
|
||||||
|
@ -504,7 +507,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
*/ \
|
*/ \
|
||||||
decl##_node_t *prefix##skip_tail_##decl(decl##_t *slist) \
|
decl##_node_t *prefix##skip_tail_##decl(decl##_t *slist) \
|
||||||
{ \
|
{ \
|
||||||
return slist->slh_tail->field.sle_prev == slist->slh_head->field.sle_next[0] ? NULL : slist->slh_tail->field.sle_prev; \
|
return slist->slh_tail->field.sle_prev == slist->slh_head->field.sle_levels[0]->next ? NULL : slist->slh_tail->field.sle_prev; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/** \
|
/** \
|
||||||
|
@ -517,9 +520,9 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
{ \
|
{ \
|
||||||
if (slist == NULL || n == NULL) \
|
if (slist == NULL || n == NULL) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
if (n->field.sle_next[0] == slist->slh_tail) \
|
if (n->field.sle_levels[0]->next == slist->slh_tail) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
return n->field.sle_next[0]; \
|
return n->field.sle_levels[0]->next; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/** \
|
/** \
|
||||||
|
@ -560,7 +563,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
} while (node != NULL); \
|
} while (node != NULL); \
|
||||||
\
|
\
|
||||||
while (node) { \
|
while (node) { \
|
||||||
next = node->field.sle_next[0]; \
|
next = node->field.sle_levels[0]->next; \
|
||||||
if (next->field.sle_prev) \
|
if (next->field.sle_prev) \
|
||||||
slist->slh_fns.free_entry(node); \
|
slist->slh_fns.free_entry(node); \
|
||||||
free(node); \
|
free(node); \
|
||||||
|
@ -620,8 +623,9 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
size_t i, j, u_hits, hits_CHu = 0, hits_CHv = 0, delta_height, new_height, cur_hits, prev_hits; \
|
size_t i, j, u_hits, hits_CHu = 0, hits_CHv = 0, delta_height, new_height, cur_hits, prev_hits; \
|
||||||
double k_threshold, m_total_hits, asc_cond, dsc_cond; \
|
double k_threshold, m_total_hits, asc_cond, dsc_cond; \
|
||||||
\
|
\
|
||||||
|
return; \
|
||||||
/* Total hits, `k`, accross all nodes. */ \
|
/* Total hits, `k`, accross all nodes. */ \
|
||||||
m_total_hits = slist->slh_head->field.sle_next[slist->slh_head->field.sle_height]->field.sle_hits; \
|
m_total_hits = slist->slh_head->field.sle_levels[slist->slh_head->field.sle_height]->hits; \
|
||||||
\
|
\
|
||||||
/* Height of the head node, should be close to floor(log(max_height)). */ \
|
/* Height of the head node, should be close to floor(log(max_height)). */ \
|
||||||
k_threshold = slist->slh_head->field.sle_height + 1; \
|
k_threshold = slist->slh_head->field.sle_height + 1; \
|
||||||
|
@ -638,11 +642,11 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
__SKIP_SUBTREE_CHu(decl, field, slist, path, i) \
|
__SKIP_SUBTREE_CHu(decl, field, slist, path, i) \
|
||||||
{ \
|
{ \
|
||||||
hits_CHu += elm->field.sle_hits; \
|
hits_CHu += elm->field.sle_levels[i]->hits; \
|
||||||
} \
|
} \
|
||||||
__SKIP_SUBTREE_CHv(decl, field, slist, path, i) \
|
__SKIP_SUBTREE_CHv(decl, field, slist, path, i) \
|
||||||
{ \
|
{ \
|
||||||
hits_CHv += elm->field.sle_hits; \
|
hits_CHv += elm->field.sle_levels[i]->hits; \
|
||||||
} \
|
} \
|
||||||
u_hits = hits_CHu + hits_CHv; \
|
u_hits = hits_CHu + hits_CHv; \
|
||||||
\
|
\
|
||||||
|
@ -660,21 +664,22 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (path[i - 1].node->field.sle_prev != slist->slh_head) { \
|
if (path[i - 1].node->field.sle_prev != slist->slh_head) { \
|
||||||
/* 1) go backwards along path from where we are until head */ \
|
/* 1) go backwards along path from where we are until head */ \
|
||||||
j = i; \
|
j = i; \
|
||||||
cur_hits = path[j].node->field.sle_next[path[j].in]->field.sle_hits; \
|
cur_hits = path[j].node->field.sle_levels[path[j].in]->hits; \
|
||||||
do { \
|
do { \
|
||||||
/* 2) propagate hits */ \
|
/* 2) propagate hits */ \
|
||||||
prev_hits = path[j - 1].node->field.sle_next[path[j - 1].in]->field.sle_hits; \
|
prev_hits = path[j - 1].node->field.sle_levels[path[j - 1].in]->hits; \
|
||||||
path[j - 1].node->field.sle_next[path[j - 1].in]->field.sle_hits += cur_hits; \
|
path[j - 1].node->field.sle_levels[path[j - 1].in]->hits += cur_hits; \
|
||||||
cur_hits = prev_hits; \
|
cur_hits = prev_hits; \
|
||||||
/* 3) adjust forward pointers */ \
|
/* 3) adjust forward pointers */ \
|
||||||
if (path[j - 1].node->field.sle_next[j] == path[i].node) \
|
if (path[j - 1].node->field.sle_levels[j]->next == path[i].node) \
|
||||||
path[j - 1].node->field.sle_next[j] = path[i].node->field.sle_next[j]; \
|
path[j - 1].node->field.sle_levels[j]->next = path[i].node->field.sle_levels[j]->next; \
|
||||||
} while (j-- > 1); \
|
} while (j-- > 1); \
|
||||||
/* 4) reduce height by one */ \
|
/* 4) reduce height by one */ \
|
||||||
path[i].node->field.sle_height--; \
|
path[i].node->field.sle_height--; \
|
||||||
/* TODO: remove me */ \
|
/* TODO: remove me \
|
||||||
__skip_integrity_check_##decl(slist, 0); \
|
__skip_integrity_check_##decl(slist, 0); \
|
||||||
prefix##skip_dot_##decl(of, slist, gen, "dsc_cond", sprintf_##decl##_node); \
|
prefix##skip_dot_##decl(of, slist, gen, "dsc_cond", sprintf_##decl##_node); \
|
||||||
|
*/ \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* (b) Check the ascent condition: \
|
/* (b) Check the ascent condition: \
|
||||||
|
@ -691,14 +696,15 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
/* 2) increase height by one */ \
|
/* 2) increase height by one */ \
|
||||||
new_height = path[i].node->field.sle_height++; \
|
new_height = path[i].node->field.sle_height++; \
|
||||||
/* 3) update hit counter */ \
|
/* 3) update hit counter */ \
|
||||||
path[i].node->field.sle_next[new_height]->field.sle_hits += path[i - 1].node->field.sle_next[path[i - 1].in]->field.sle_hits; \
|
path[i].node->field.sle_levels[new_height]->hits += path[i - 1].node->field.sle_levels[path[i - 1].in]->hits; \
|
||||||
/* 4) reset the prev node hits to 0 */ \
|
/* 4) reset the prev node hits to 0 */ \
|
||||||
path[i - 1].node->field.sle_next[path[i - 1].in]->field.sle_hits = 0; \
|
path[i - 1].node->field.sle_levels[path[i - 1].in]->hits = 0; \
|
||||||
if (path[i - 1].in != 0) \
|
if (path[i - 1].in != 0) \
|
||||||
path[i - 1].node->field.sle_next[path[i - 1].in]->field.sle_next[path[i - 1].in] = path[i].node; \
|
path[i - 1].node->field.sle_levels[path[i - 1].in]->next->field.sle_levels[path[i - 1].in]->next = path[i].node; \
|
||||||
/* TODO: remove me */ \
|
/* TODO: remove me \
|
||||||
__skip_integrity_check_##decl(slist, 0); \
|
__skip_integrity_check_##decl(slist, 0); \
|
||||||
prefix##skip_dot_##decl(of, slist, gen, "asc_cond", sprintf_##decl##_node); \
|
prefix##skip_dot_##decl(of, slist, gen, "asc_cond", sprintf_##decl##_node); \
|
||||||
|
*/ \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -724,19 +730,20 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
i = slist->slh_head->field.sle_height; \
|
i = slist->slh_head->field.sle_height; \
|
||||||
do { \
|
do { \
|
||||||
path[i + 1].pu = 0; \
|
path[i + 1].pu = 0; \
|
||||||
while (elm != slist->slh_tail && elm->field.sle_next[i] && __skip_compare_nodes_##decl(slist, elm->field.sle_next[i], n, slist->slh_aux) < 0) { \
|
while (elm != slist->slh_tail && elm->field.sle_levels[i]->next && \
|
||||||
elm = elm->field.sle_next[i]; \
|
__skip_compare_nodes_##decl(slist, elm->field.sle_levels[i]->next, n, slist->slh_aux) < 0) { \
|
||||||
|
elm = elm->field.sle_levels[i]->next; \
|
||||||
path[i + 1].in = i; \
|
path[i + 1].in = i; \
|
||||||
path[i + 1].pu += elm->field.sle_next[path[i + 1].in]->field.sle_hits; \
|
path[i + 1].pu += elm->field.sle_levels[path[i + 1].in]->hits; \
|
||||||
} \
|
} \
|
||||||
path[i + 1].node = elm; \
|
path[i + 1].node = elm; \
|
||||||
path[i + 1].node->field.sle_next[path[i + 1].in]->field.sle_hits++; \
|
path[i + 1].node->field.sle_levels[path[i + 1].in]->hits++; \
|
||||||
len++; \
|
len++; \
|
||||||
} while (i--); \
|
} while (i--); \
|
||||||
elm = elm->field.sle_next[0]; \
|
elm = elm->field.sle_levels[0]->next; \
|
||||||
if (__skip_compare_nodes_##decl(slist, elm, n, slist->slh_aux) == 0) { \
|
if (__skip_compare_nodes_##decl(slist, elm, n, slist->slh_aux) == 0) { \
|
||||||
path[0].node = elm; \
|
path[0].node = elm; \
|
||||||
path[0].node->field.sle_hits++; \
|
path[0].node->field.sle_levels[0]->hits++; \
|
||||||
__skip_rebalence_##decl(slist, len, path); \
|
__skip_rebalence_##decl(slist, len, path); \
|
||||||
} \
|
} \
|
||||||
return len; \
|
return len; \
|
||||||
|
@ -789,7 +796,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
/* Ensure all next[] point to tail. */ \
|
/* Ensure all next[] point to tail. */ \
|
||||||
__SKIP_ENTRIES_B2T(field, new) \
|
__SKIP_ENTRIES_B2T(field, new) \
|
||||||
{ \
|
{ \
|
||||||
new->field.sle_next[lvl] = slist->slh_tail; \
|
new->field.sle_levels[lvl]->next = slist->slh_tail; \
|
||||||
} \
|
} \
|
||||||
/* Adjust all forward pointers for each element in the path. */ \
|
/* Adjust all forward pointers for each element in the path. */ \
|
||||||
for (i = 0; i <= new_height; i++) { \
|
for (i = 0; i <= new_height; i++) { \
|
||||||
|
@ -797,25 +804,25 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
next[i] for our new node. Also, don't set the tail's next[i] \
|
next[i] for our new node. Also, don't set the tail's next[i] \
|
||||||
because it is always NULL. */ \
|
because it is always NULL. */ \
|
||||||
if (path[i + 1].node != slist->slh_tail) { \
|
if (path[i + 1].node != slist->slh_tail) { \
|
||||||
new->field.sle_next[i] = path[i + 1].node->field.sle_next[i]; \
|
new->field.sle_levels[i]->next = path[i + 1].node->field.sle_levels[i]->next; \
|
||||||
path[i + 1].node->field.sle_next[i] = new; \
|
path[i + 1].node->field.sle_levels[i]->next = new; \
|
||||||
loc = path[i + 1].node == slist->slh_head ? i : loc; \
|
loc = path[i + 1].node == slist->slh_head ? i : loc; \
|
||||||
} else { \
|
} else { \
|
||||||
new->field.sle_next[i] = slist->slh_tail; \
|
new->field.sle_levels[i]->next = slist->slh_tail; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Ensure all slh_head->next[] above loc point to tail. */ \
|
/* Ensure all slh_head->next[] above loc point to tail. */ \
|
||||||
if (path[1].node == slist->slh_head) { \
|
if (path[1].node == slist->slh_head) { \
|
||||||
__SKIP_ENTRIES_B2T_FROM(field, slist->slh_head, loc + 1) \
|
__SKIP_ENTRIES_B2T_FROM(field, slist->slh_head, loc + 1) \
|
||||||
{ \
|
{ \
|
||||||
slist->slh_head->field.sle_next[lvl] = slist->slh_tail; \
|
slist->slh_head->field.sle_levels[lvl]->next = slist->slh_tail; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Adujust the previous pointers in the nodes. */ \
|
/* Adujust the previous pointers in the nodes. */ \
|
||||||
new->field.sle_prev = path[1].node; \
|
new->field.sle_prev = path[1].node; \
|
||||||
new->field.sle_next[0]->field.sle_prev = new; \
|
new->field.sle_levels[0]->next->field.sle_prev = new; \
|
||||||
/* Account for insert at tail. */ \
|
/* Account for insert at tail. */ \
|
||||||
if (new->field.sle_next[0] == slist->slh_tail) { \
|
if (new->field.sle_levels[0]->next == slist->slh_tail) { \
|
||||||
slist->slh_tail->field.sle_prev = new; \
|
slist->slh_tail->field.sle_prev = new; \
|
||||||
} \
|
} \
|
||||||
/* Adjust the head/tail boundary node heights if necessary. */ \
|
/* Adjust the head/tail boundary node heights if necessary. */ \
|
||||||
|
@ -827,7 +834,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (slist->slh_fns.snapshot_record_era) \
|
if (slist->slh_fns.snapshot_record_era) \
|
||||||
slist->slh_fns.snapshot_record_era(slist, new); \
|
slist->slh_fns.snapshot_record_era(slist, new); \
|
||||||
/* Set hits for rebalencing to 1 when new born. */ \
|
/* Set hits for rebalencing to 1 when new born. */ \
|
||||||
new->field.sle_hits = 1; \
|
new->field.sle_levels[new_height]->hits = 1; \
|
||||||
/* Increase our list length (aka. size, count, etc.) by one. */ \
|
/* Increase our list length (aka. size, count, etc.) by one. */ \
|
||||||
slist->slh_length++; \
|
slist->slh_length++; \
|
||||||
\
|
\
|
||||||
|
@ -914,7 +921,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
__skip_locate_##decl(slist, query, path); \
|
__skip_locate_##decl(slist, query, path); \
|
||||||
node = path[1].node; \
|
node = path[1].node; \
|
||||||
do { \
|
do { \
|
||||||
node = node->field.sle_next[0]; \
|
node = node->field.sle_levels[0]->next; \
|
||||||
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
||||||
} while (cmp < 0); \
|
} while (cmp < 0); \
|
||||||
\
|
\
|
||||||
|
@ -953,7 +960,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (node == slist->slh_tail) \
|
if (node == slist->slh_tail) \
|
||||||
goto done; \
|
goto done; \
|
||||||
do { \
|
do { \
|
||||||
node = node->field.sle_next[0]; \
|
node = node->field.sle_levels[0]->next; \
|
||||||
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
||||||
} while (cmp <= 0 && node != slist->slh_tail); \
|
} while (cmp <= 0 && node != slist->slh_tail); \
|
||||||
\
|
\
|
||||||
|
@ -1154,23 +1161,23 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
} \
|
} \
|
||||||
/* We found it, set the next->prev to the node->prev keeping in mind \
|
/* We found it, set the next->prev to the node->prev keeping in mind \
|
||||||
that the next node might be the tail). */ \
|
that the next node might be the tail). */ \
|
||||||
node->field.sle_next[0]->field.sle_prev = node->field.sle_prev; \
|
node->field.sle_levels[0]->next->field.sle_prev = node->field.sle_prev; \
|
||||||
/* Walk the path, stop when the next node is not the one we're \
|
/* Walk the path, stop when the next node is not the one we're \
|
||||||
removing. At each step along our walk... */ \
|
removing. At each step along our walk... */ \
|
||||||
for (i = 0; i < len; i++) { \
|
for (i = 0; i < len; i++) { \
|
||||||
if (path[i + 1].node->field.sle_next[i] != node) \
|
if (path[i + 1].node->field.sle_levels[i]->next != node) \
|
||||||
break; \
|
break; \
|
||||||
/* ... adjust the next pointer at that level. */ \
|
/* ... adjust the next pointer at that level. */ \
|
||||||
path[i + 1].node->field.sle_next[i] = node->field.sle_next[i]; \
|
path[i + 1].node->field.sle_levels[i]->next = node->field.sle_levels[i]->next; \
|
||||||
/* Adjust the height so we're only pointing at the tail once at \
|
/* Adjust the height so we're only pointing at the tail once at \
|
||||||
the top so we don't waste steps later when searching. */ \
|
the top so we don't waste steps later when searching. */ \
|
||||||
if (path[i + 1].node->field.sle_next[i] == slist->slh_tail) { \
|
if (path[i + 1].node->field.sle_levels[i]->next == slist->slh_tail) { \
|
||||||
height = path[i + 1].node->field.sle_height; \
|
height = path[i + 1].node->field.sle_height; \
|
||||||
path[i + 1].node->field.sle_height = height - 1; \
|
path[i + 1].node->field.sle_height = height - 1; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Account for delete at tail. */ \
|
/* Account for delete at tail. */ \
|
||||||
if (node->field.sle_next[0] == slist->slh_tail) { \
|
if (node->field.sle_levels[0]->next == slist->slh_tail) { \
|
||||||
slist->slh_tail->field.sle_prev = query->field.sle_prev; \
|
slist->slh_tail->field.sle_prev = query->field.sle_prev; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
@ -1181,7 +1188,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
/* Reduce the height of the head node. */ \
|
/* Reduce the height of the head node. */ \
|
||||||
i = 0; \
|
i = 0; \
|
||||||
while (slist->slh_head->field.sle_next[i] != slist->slh_tail && i < slist->slh_head->field.sle_height) \
|
while (slist->slh_head->field.sle_levels[i]->next != slist->slh_tail && i < slist->slh_head->field.sle_height) \
|
||||||
i++; \
|
i++; \
|
||||||
slist->slh_head->field.sle_height = i; \
|
slist->slh_head->field.sle_height = i; \
|
||||||
slist->slh_tail->field.sle_height = i; \
|
slist->slh_tail->field.sle_height = i; \
|
||||||
|
@ -1235,7 +1242,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
node = slist->slh_snap.pres; \
|
node = slist->slh_snap.pres; \
|
||||||
while (node) { \
|
while (node) { \
|
||||||
next = node->field.sle_next[0]; \
|
next = node->field.sle_levels[0]->next; \
|
||||||
prefix##skip_free_node_##decl(slist, node); \
|
prefix##skip_free_node_##decl(slist, node); \
|
||||||
node = next; \
|
node = next; \
|
||||||
} \
|
} \
|
||||||
|
@ -1271,14 +1278,14 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
return 0; \
|
return 0; \
|
||||||
\
|
\
|
||||||
/* (a) alloc, ... */ \
|
/* (a) alloc, ... */ \
|
||||||
size_t sle_arr_sz = sizeof(struct __skiplist_##decl##_entry) * slist->slh_max_height; \
|
size_t sle_arr_sz = sizeof(struct __skiplist_##decl##_level) * slist->slh_max_height; \
|
||||||
rc = prefix##skip_alloc_node_##decl(slist, &dest); \
|
rc = prefix##skip_alloc_node_##decl(slist, &dest); \
|
||||||
if (rc) \
|
if (rc) \
|
||||||
return rc; \
|
return rc; \
|
||||||
\
|
\
|
||||||
/* (b) shallow copy, fix sle_next pointer, ... */ \
|
/* (b) shallow copy, fix sle_levels pointer, ... */ \
|
||||||
memcpy(dest, src, sizeof(decl##_node_t) + sle_arr_sz); \
|
memcpy(dest, src, sizeof(decl##_node_t) + sle_arr_sz); \
|
||||||
dest->field.sle_next = (decl##_node_t **)((uintptr_t)dest + sizeof(decl##_node_t)); \
|
dest->field.sle_levels = (struct __skiplist_##decl##_level **)((uintptr_t)dest + sizeof(decl##_node_t)); \
|
||||||
\
|
\
|
||||||
/* ... if we're not preserving the head or the tail, ... */ \
|
/* ... if we're not preserving the head or the tail, ... */ \
|
||||||
if (!(src == slist->slh_head || src == slist->slh_tail)) { \
|
if (!(src == slist->slh_head || src == slist->slh_tail)) { \
|
||||||
|
@ -1291,7 +1298,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* (d) is this a duplicate? */ \
|
/* (d) is this a duplicate? */ \
|
||||||
if (__skip_compare_nodes_##decl(slist, dest, dest->field.sle_next[0], slist->slh_aux) == 0 || \
|
if (__skip_compare_nodes_##decl(slist, dest, dest->field.sle_levels[0]->next, slist->slh_aux) == 0 || \
|
||||||
__skip_compare_nodes_##decl(slist, dest, dest->field.sle_prev, slist->slh_aux) == 0) \
|
__skip_compare_nodes_##decl(slist, dest, dest->field.sle_prev, slist->slh_aux) == 0) \
|
||||||
is_dup = (decl##_node_t *)0x1; \
|
is_dup = (decl##_node_t *)0x1; \
|
||||||
\
|
\
|
||||||
|
@ -1299,20 +1306,20 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
dest->field.sle_prev = NULL; \
|
dest->field.sle_prev = NULL; \
|
||||||
__SKIP_ALL_ENTRIES_B2T(field, dest) \
|
__SKIP_ALL_ENTRIES_B2T(field, dest) \
|
||||||
{ \
|
{ \
|
||||||
dest->field.sle_next[lvl] = NULL; \
|
dest->field.sle_levels[lvl]->next = NULL; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* (f) set duplicate flag */ \
|
/* (f) set duplicate flag */ \
|
||||||
dest->field.sle_next[1] = (decl##_node_t *)is_dup; \
|
dest->field.sle_levels[1]->next = (decl##_node_t *)is_dup; \
|
||||||
\
|
\
|
||||||
/* (g) insert node into slh_pres list at head */ \
|
/* (g) insert node into slh_pres list at head */ \
|
||||||
if (slist->slh_snap.pres == NULL) { \
|
if (slist->slh_snap.pres == NULL) { \
|
||||||
dest->field.sle_next[0] = NULL; \
|
dest->field.sle_levels[0]->next = NULL; \
|
||||||
slist->slh_snap.pres = dest; \
|
slist->slh_snap.pres = dest; \
|
||||||
} else { \
|
} else { \
|
||||||
/* The next[0] pointer forms the singly-linked list when \
|
/* The next[0] pointer forms the singly-linked list when \
|
||||||
preserved. */ \
|
preserved. */ \
|
||||||
dest->field.sle_next[0] = slist->slh_snap.pres; \
|
dest->field.sle_levels[0]->next = slist->slh_snap.pres; \
|
||||||
slist->slh_snap.pres = dest; \
|
slist->slh_snap.pres = dest; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
@ -1352,11 +1359,11 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
* c) restore nodes == era by... \
|
* c) restore nodes == era by... \
|
||||||
* i) remove node from slh_pres list \
|
* i) remove node from slh_pres list \
|
||||||
* ii) _insert(node) or \
|
* ii) _insert(node) or \
|
||||||
* _insert_dup() if node->field.sle_next[1] != 0 (clear that) \
|
* _insert_dup() if node->field.sle_levels[1] != 0 (clear that) \
|
||||||
* d) set slist's era to `era` \
|
* d) set slist's era to `era` \
|
||||||
* \
|
* \
|
||||||
* NOTES: \
|
* NOTES: \
|
||||||
* - Starting with slh_pres, the `node->field.sle_next[0]` form a \
|
* - Starting with slh_pres, the `node->field.sle_levels[0]->next` form a \
|
||||||
* singly-linked list. \
|
* singly-linked list. \
|
||||||
*/ \
|
*/ \
|
||||||
decl##_t *prefix##skip_restore_snapshot_##decl(decl##_t *slist, size_t era) \
|
decl##_t *prefix##skip_restore_snapshot_##decl(decl##_t *slist, size_t era) \
|
||||||
|
@ -1387,12 +1394,12 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (node->field.sle_era > era) { \
|
if (node->field.sle_era > era) { \
|
||||||
/* remove node from slh_snap.pres list */ \
|
/* remove node from slh_snap.pres list */ \
|
||||||
if (slist->slh_snap.pres == node) \
|
if (slist->slh_snap.pres == node) \
|
||||||
slist->slh_snap.pres = node->field.sle_next[0]; \
|
slist->slh_snap.pres = node->field.sle_levels[0]->next; \
|
||||||
else { \
|
else { \
|
||||||
if (node->field.sle_next[0] == NULL) \
|
if (node->field.sle_levels[0]->next == NULL) \
|
||||||
prev->field.sle_next[0] = NULL; \
|
prev->field.sle_levels[0]->next = NULL; \
|
||||||
else \
|
else \
|
||||||
prev->field.sle_next[0] = node->field.sle_next[0]; \
|
prev->field.sle_levels[0]->next = node->field.sle_levels[0]->next; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
prefix##skip_free_node_##decl(slist, node); \
|
prefix##skip_free_node_##decl(slist, node); \
|
||||||
|
@ -1403,24 +1410,24 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (node->field.sle_era == era) { \
|
if (node->field.sle_era == era) { \
|
||||||
/* remove node from slh_snap.pres list */ \
|
/* remove node from slh_snap.pres list */ \
|
||||||
if (slist->slh_snap.pres == node) \
|
if (slist->slh_snap.pres == node) \
|
||||||
slist->slh_snap.pres = node->field.sle_next[0]; \
|
slist->slh_snap.pres = node->field.sle_levels[0]->next; \
|
||||||
else { \
|
else { \
|
||||||
if (node->field.sle_next[0] == NULL) \
|
if (node->field.sle_levels[0]->next == NULL) \
|
||||||
prev->field.sle_next[0] = NULL; \
|
prev->field.sle_levels[0]->next = NULL; \
|
||||||
else \
|
else \
|
||||||
prev->field.sle_next[0] = node->field.sle_next[0]; \
|
prev->field.sle_levels[0]->next = node->field.sle_levels[0]->next; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
node->field.sle_prev = NULL; \
|
node->field.sle_prev = NULL; \
|
||||||
if (node->field.sle_next[1] != 0) { \
|
if (node->field.sle_levels[1] != 0) { \
|
||||||
node->field.sle_next[1] = NULL; \
|
node->field.sle_levels[1] = NULL; \
|
||||||
prefix##skip_insert_dup_##decl(slist, node); \
|
prefix##skip_insert_dup_##decl(slist, node); \
|
||||||
} else { \
|
} else { \
|
||||||
prefix##skip_insert_##decl(slist, node); \
|
prefix##skip_insert_##decl(slist, node); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
prev = node; \
|
prev = node; \
|
||||||
node = node->field.sle_next[0]; \
|
node = node->field.sle_levels[0]->next; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* (d) */ \
|
/* (d) */ \
|
||||||
|
@ -1547,12 +1554,12 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
slist->slh_head->field.sle_height = 0; \
|
slist->slh_head->field.sle_height = 0; \
|
||||||
for (i = 0; i < slist->slh_max_height; i++) \
|
for (i = 0; i < slist->slh_max_height; i++) \
|
||||||
slist->slh_head->field.sle_next[i] = slist->slh_tail; \
|
slist->slh_head->field.sle_levels[i]->next = slist->slh_tail; \
|
||||||
slist->slh_head->field.sle_prev = NULL; \
|
slist->slh_head->field.sle_prev = NULL; \
|
||||||
\
|
\
|
||||||
slist->slh_tail->field.sle_height = slist->slh_max_height; \
|
slist->slh_tail->field.sle_height = slist->slh_max_height; \
|
||||||
for (i = 0; i < slist->slh_max_height; i++) \
|
for (i = 0; i < slist->slh_max_height; i++) \
|
||||||
slist->slh_tail->field.sle_next[i] = NULL; \
|
slist->slh_tail->field.sle_levels[i]->next = NULL; \
|
||||||
slist->slh_tail->field.sle_prev = slist->slh_head; \
|
slist->slh_tail->field.sle_prev = slist->slh_head; \
|
||||||
\
|
\
|
||||||
i = 0; \
|
i = 0; \
|
||||||
|
@ -1678,26 +1685,26 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
node = slist->slh_head; \
|
node = slist->slh_head; \
|
||||||
__SKIP_ENTRIES_B2T(field, node) \
|
__SKIP_ENTRIES_B2T(field, node) \
|
||||||
{ \
|
{ \
|
||||||
if (node->field.sle_next[lvl] == NULL) { \
|
if (node->field.sle_levels[lvl]->next == NULL) { \
|
||||||
__skip_integrity_failure_##decl("the head's %lu next node should not be NULL\n", lvl); \
|
__skip_integrity_failure_##decl("the head's %lu next node should not be NULL\n", lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} \
|
} \
|
||||||
n = lvl; \
|
n = lvl; \
|
||||||
if (node->field.sle_next[lvl] == slist->slh_tail) \
|
if (node->field.sle_levels[lvl]->next == slist->slh_tail) \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
n++; \
|
n++; \
|
||||||
__SKIP_ENTRIES_B2T_FROM(field, node, n) \
|
__SKIP_ENTRIES_B2T_FROM(field, node, n) \
|
||||||
{ \
|
{ \
|
||||||
if (node->field.sle_next[lvl] == NULL) { \
|
if (node->field.sle_levels[lvl]->next == NULL) { \
|
||||||
__skip_integrity_failure_##decl("the head's %lu next node should not be NULL\n", lvl); \
|
__skip_integrity_failure_##decl("the head's %lu next node should not be NULL\n", lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} \
|
} \
|
||||||
if (node->field.sle_next[lvl] != slist->slh_tail) { \
|
if (node->field.sle_levels[lvl]->next != slist->slh_tail) { \
|
||||||
__skip_integrity_failure_##decl("after internal nodes, the head's %lu next node should always be the tail\n", lvl); \
|
__skip_integrity_failure_##decl("after internal nodes, the head's %lu next node should always be the tail\n", lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
|
@ -1728,7 +1735,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (this->sle_next == NULL) { \
|
if (this->sle_levels == NULL) { \
|
||||||
__skip_integrity_failure_##decl("the %lu node's [%p] next field should never be NULL\n", nth, (void *)node); \
|
__skip_integrity_failure_##decl("the %lu node's [%p] next field should never be NULL\n", nth, (void *)node); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
|
@ -1744,25 +1751,25 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
__SKIP_ENTRIES_B2T(field, node) \
|
__SKIP_ENTRIES_B2T(field, node) \
|
||||||
{ \
|
{ \
|
||||||
if (this->sle_next[lvl] == NULL) { \
|
if (this->sle_levels[lvl]->next == NULL) { \
|
||||||
__skip_integrity_failure_##decl("the %lu node's next[%lu] should not be NULL\n", nth, lvl); \
|
__skip_integrity_failure_##decl("the %lu node's next[%lu] should not be NULL\n", nth, lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} \
|
} \
|
||||||
n = lvl; \
|
n = lvl; \
|
||||||
if (this->sle_next[lvl] == slist->slh_tail) \
|
if (this->sle_levels[lvl]->next == slist->slh_tail) \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
n++; \
|
n++; \
|
||||||
__SKIP_ENTRIES_B2T_FROM(field, node, n) \
|
__SKIP_ENTRIES_B2T_FROM(field, node, n) \
|
||||||
{ \
|
{ \
|
||||||
if (this->sle_next[lvl] == NULL) { \
|
if (this->sle_levels[lvl]->next == NULL) { \
|
||||||
__skip_integrity_failure_##decl("after the %lunth the %lu node's next[%lu] should not be NULL\n", n, nth, lvl); \
|
__skip_integrity_failure_##decl("after the %lunth the %lu node's next[%lu] should not be NULL\n", n, nth, lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} else if (this->sle_next[lvl] != slist->slh_tail) { \
|
} else if (this->sle_levels[lvl]->next != slist->slh_tail) { \
|
||||||
__skip_integrity_failure_##decl("after the %lunth the %lu node's next[%lu] should point to the tail\n", n, nth, lvl); \
|
__skip_integrity_failure_##decl("after the %lunth the %lu node's next[%lu] should point to the tail\n", n, nth, lvl); \
|
||||||
n_err++; \
|
n_err++; \
|
||||||
if (flags) \
|
if (flags) \
|
||||||
|
@ -1770,7 +1777,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
decl##_node_t *a = (decl##_node_t *)(uintptr_t)this->sle_next; \
|
decl##_node_t *a = (decl##_node_t *)(uintptr_t)this->sle_levels; \
|
||||||
decl##_node_t *b = (decl##_node_t *)(intptr_t)((uintptr_t)node + sizeof(decl##_node_t)); \
|
decl##_node_t *b = (decl##_node_t *)(intptr_t)((uintptr_t)node + sizeof(decl##_node_t)); \
|
||||||
if (a != b) { \
|
if (a != b) { \
|
||||||
__skip_integrity_failure_##decl("the %lu node's [%p] next field isn't at the proper offset relative to the node\n", nth, (void *)node); \
|
__skip_integrity_failure_##decl("the %lu node's [%p] next field isn't at the proper offset relative to the node\n", nth, (void *)node); \
|
||||||
|
@ -1779,7 +1786,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
return n_err; \
|
return n_err; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
next = this->sle_next[0]; \
|
next = this->sle_levels[0]->next; \
|
||||||
prev = this->sle_prev; \
|
prev = this->sle_prev; \
|
||||||
if (__skip_compare_nodes_##decl(slist, node, node, slist->slh_aux) != 0) { \
|
if (__skip_compare_nodes_##decl(slist, node, node, slist->slh_aux) != 0) { \
|
||||||
__skip_integrity_failure_##decl("the %lu node [%p] is not equal to itself\n", nth, (void *)node); \
|
__skip_integrity_failure_##decl("the %lu node [%p] is not equal to itself\n", nth, (void *)node); \
|
||||||
|
@ -2002,7 +2009,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
fflush(os); \
|
fflush(os); \
|
||||||
__SKIP_ENTRIES_T2B(field, node) \
|
__SKIP_ENTRIES_T2B(field, node) \
|
||||||
{ \
|
{ \
|
||||||
next = (node->field.sle_next[lvl] == slist->slh_tail) ? NULL : node->field.sle_next[lvl]; \
|
next = (node->field.sle_levels[lvl]->next == slist->slh_tail) ? NULL : node->field.sle_levels[lvl]->next; \
|
||||||
width = __skip_dot_width_##decl(slist, node, next ? next : slist->slh_tail); \
|
width = __skip_dot_width_##decl(slist, node, next ? next : slist->slh_tail); \
|
||||||
fprintf(os, " { <w%lu> %lu | <f%lu> ", lvl, width, lvl); \
|
fprintf(os, " { <w%lu> %lu | <f%lu> ", lvl, width, lvl); \
|
||||||
if (next) \
|
if (next) \
|
||||||
|
@ -2024,7 +2031,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
/* Now edges */ \
|
/* Now edges */ \
|
||||||
__SKIP_ENTRIES_B2T(field, node) \
|
__SKIP_ENTRIES_B2T(field, node) \
|
||||||
{ \
|
{ \
|
||||||
next = (node->field.sle_next[lvl] == slist->slh_tail) ? NULL : node->field.sle_next[lvl]; \
|
next = (node->field.sle_levels[lvl]->next == slist->slh_tail) ? NULL : node->field.sle_levels[lvl]->next; \
|
||||||
__skip_dot_write_node_##decl(os, nsg, node); \
|
__skip_dot_write_node_##decl(os, nsg, node); \
|
||||||
fprintf(os, ":f%lu -> ", lvl); \
|
fprintf(os, ":f%lu -> ", lvl); \
|
||||||
__skip_dot_write_node_##decl(os, nsg, next); \
|
__skip_dot_write_node_##decl(os, nsg, next); \
|
||||||
|
@ -2103,7 +2110,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
fprintf(os, "\"HeadNode%lu\" [\n", nsg); \
|
fprintf(os, "\"HeadNode%lu\" [\n", nsg); \
|
||||||
fprintf(os, "label = \""); \
|
fprintf(os, "label = \""); \
|
||||||
\
|
\
|
||||||
if (slist->slh_head->field.sle_height || slist->slh_head->field.sle_next[0] != slist->slh_tail) \
|
if (slist->slh_head->field.sle_height || slist->slh_head->field.sle_levels[0]->next != slist->slh_tail) \
|
||||||
letitgo = 1; \
|
letitgo = 1; \
|
||||||
\
|
\
|
||||||
/* Write out the fields */ \
|
/* Write out the fields */ \
|
||||||
|
@ -2111,7 +2118,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
if (letitgo) { \
|
if (letitgo) { \
|
||||||
__SKIP_ENTRIES_T2B(field, node) \
|
__SKIP_ENTRIES_T2B(field, node) \
|
||||||
{ \
|
{ \
|
||||||
next = (node->field.sle_next[lvl] == slist->slh_tail) ? NULL : node->field.sle_next[lvl]; \
|
next = (node->field.sle_levels[lvl]->next == slist->slh_tail) ? NULL : node->field.sle_levels[lvl]->next; \
|
||||||
width = __skip_dot_width_##decl(slist, node, next ? next : slist->slh_tail); \
|
width = __skip_dot_width_##decl(slist, node, next ? next : slist->slh_tail); \
|
||||||
fprintf(os, "{ %lu | <f%lu> ", width, lvl); \
|
fprintf(os, "{ %lu | <f%lu> ", width, lvl); \
|
||||||
if (next) \
|
if (next) \
|
||||||
|
@ -2135,7 +2142,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
node = slist->slh_head; \
|
node = slist->slh_head; \
|
||||||
__SKIP_ENTRIES_B2T(field, node) \
|
__SKIP_ENTRIES_B2T(field, node) \
|
||||||
{ \
|
{ \
|
||||||
next = (node->field.sle_next[lvl] == slist->slh_tail) ? NULL : node->field.sle_next[lvl]; \
|
next = (node->field.sle_levels[lvl]->next == slist->slh_tail) ? NULL : node->field.sle_levels[lvl]->next; \
|
||||||
fprintf(os, "\"HeadNode%lu\":f%lu -> ", nsg, lvl); \
|
fprintf(os, "\"HeadNode%lu\":f%lu -> ", nsg, lvl); \
|
||||||
__skip_dot_write_node_##decl(os, nsg, next); \
|
__skip_dot_write_node_##decl(os, nsg, next); \
|
||||||
fprintf(os, ":w%lu [];\n", lvl); \
|
fprintf(os, ":w%lu [];\n", lvl); \
|
||||||
|
@ -2164,7 +2171,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
node = slist->slh_tail; \
|
node = slist->slh_tail; \
|
||||||
size_t th = slist->slh_head->field.sle_height; \
|
size_t th = slist->slh_head->field.sle_height; \
|
||||||
for (size_t lvl = th; lvl != (size_t)-1; lvl--) { \
|
for (size_t lvl = th; lvl != (size_t)-1; lvl--) { \
|
||||||
next = (node->field.sle_next[lvl] == slist->slh_tail) ? NULL : node->field.sle_next[lvl]; \
|
next = (node->field.sle_levels[lvl]->next == slist->slh_tail) ? NULL : node->field.sle_levels[lvl]->next; \
|
||||||
fprintf(os, "<w%lu> 0x0", lvl); \
|
fprintf(os, "<w%lu> 0x0", lvl); \
|
||||||
__SKIP_IS_LAST_ENTRY_T2B() continue; \
|
__SKIP_IS_LAST_ENTRY_T2B() continue; \
|
||||||
fprintf(os, " | "); \
|
fprintf(os, " | "); \
|
||||||
|
|
Loading…
Reference in a new issue