splay v1/p1; every search via locate()
This commit is contained in:
parent
65f4bf6bf4
commit
37321594e3
|
@ -68,16 +68,11 @@ SKIPLIST_DECL(
|
|||
},
|
||||
/* free entry: node */
|
||||
{ free(node->value); },
|
||||
/* update entry: rc, src, dest */
|
||||
/* update entry: rc, node, value */
|
||||
{
|
||||
char *new = calloc(strlen(node->value) + 1, sizeof(char));
|
||||
if (new == NULL) {
|
||||
rc = ENOMEM;
|
||||
} else {
|
||||
strncpy(new, node->value, strlen(node->value));
|
||||
if (node->value)
|
||||
free(node->value);
|
||||
node->value = new;
|
||||
}
|
||||
node->value = (char*)value;
|
||||
},
|
||||
/* archive an entry: rc, src, dest */
|
||||
{
|
||||
|
@ -178,6 +173,7 @@ SKIPLIST_DECL_DOT(sample, api_, entries)
|
|||
void
|
||||
sprintf_sample_node(sample_node_t *node, char *buf)
|
||||
{
|
||||
// sprintf(buf, "h:%lu <<>> %d:%s", node->entries.sle_hits, node->key, node->value);
|
||||
sprintf(buf, "%d:%s", node->key, node->value);
|
||||
}
|
||||
|
||||
|
@ -298,8 +294,8 @@ main()
|
|||
shuffle(array, asz);
|
||||
|
||||
for (i = 0; i < asz; i++) {
|
||||
numeral = int_to_roman_numeral(array[i]);
|
||||
rc = api_skip_put_sample(list, array[i], to_lower(numeral));
|
||||
numeral = to_lower(int_to_roman_numeral(array[i]));
|
||||
rc = api_skip_put_sample(list, array[i], numeral);
|
||||
CHECK;
|
||||
#ifdef SNAPSHOTS
|
||||
if (i > TEST_ARRAY_SIZE + 1) {
|
||||
|
@ -314,7 +310,10 @@ main()
|
|||
#endif
|
||||
char *v = api_skip_get_sample(list, array[i]);
|
||||
CHECK;
|
||||
api_skip_set_sample(list, array[i], to_upper(v));
|
||||
char *upper_numeral = calloc(1, strlen(v) + 1);
|
||||
strncpy(upper_numeral, v, strlen(v));
|
||||
to_upper(upper_numeral);
|
||||
api_skip_set_sample(list, array[i], upper_numeral);
|
||||
CHECK;
|
||||
}
|
||||
numeral = int_to_roman_numeral(-1);
|
||||
|
@ -358,7 +357,7 @@ main()
|
|||
|
||||
#ifdef SNAPSHOTS
|
||||
//api_skip_restore_snapshot_sample(list, snap_ids[snap_i - 1]);
|
||||
api_skip_release_snapshots_sample(list);
|
||||
//api_skip_release_snapshots_sample(list);
|
||||
#endif
|
||||
|
||||
assert(strcmp(api_skip_pos_sample(list, SKIP_GTE, -(TEST_ARRAY_SIZE)-1)->value, int_to_roman_numeral(-(TEST_ARRAY_SIZE))) == 0);
|
||||
|
|
267
include/sl.h
267
include/sl.h
|
@ -200,6 +200,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
struct decl##_node *sle_prev, **sle_next; \
|
||||
size_t sle_height; \
|
||||
size_t sle_era; \
|
||||
size_t sle_hits; \
|
||||
}
|
||||
|
||||
#define SKIPLIST_FOREACH_H2T(decl, prefix, list, elm, iter) \
|
||||
|
@ -235,9 +236,12 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
/* Skiplist structure and type */ \
|
||||
typedef struct decl { \
|
||||
size_t slh_length, slh_height, slh_max_height; \
|
||||
void *slh_aux; \
|
||||
decl##_node_t *slh_head; \
|
||||
decl##_node_t *slh_tail; \
|
||||
struct { \
|
||||
void (*free_entry)(decl##_node_t *); \
|
||||
int (*update_entry)(decl##_node_t *); \
|
||||
int (*update_entry)(decl##_node_t *, void *); \
|
||||
int (*archive_entry)(decl##_node_t *, const decl##_node_t *); \
|
||||
size_t (*sizeof_entry)(decl##_node_t *); \
|
||||
int (*compare_entries)(struct decl *, decl##_node_t *, decl##_node_t *, void *); \
|
||||
|
@ -249,9 +253,9 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
size_t (*snapshot_incr_era)(struct decl *); \
|
||||
void (*snapshot_record_era)(struct decl *, decl##_node_t *); \
|
||||
} slh_fns; \
|
||||
void *slh_aux; \
|
||||
decl##_node_t *slh_head; \
|
||||
decl##_node_t *slh_tail; \
|
||||
struct { \
|
||||
size_t threshold; \
|
||||
} slh_splay; \
|
||||
struct { \
|
||||
size_t era; \
|
||||
decl##_node_t *pres; \
|
||||
|
@ -283,7 +287,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* \
|
||||
* Wraps the `update_entry_blk` code into `slh_fns.update_entry`. \
|
||||
*/ \
|
||||
static int __skip_update_entry_fn_##decl(decl##_node_t *node) \
|
||||
static int __skip_update_entry_fn_##decl(decl##_node_t *node, void *value) \
|
||||
{ \
|
||||
int rc = 0; \
|
||||
update_entry_blk; \
|
||||
|
@ -575,6 +579,18 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
return nodes; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
* -- __skip_rebalance_ TODO \
|
||||
* \
|
||||
*/ \
|
||||
static void __skip_rebalance_##decl(decl##_t *slist, size_t len, decl##_node_t **path, size_t par_sum) \
|
||||
{ \
|
||||
((void)slist); \
|
||||
((void)len); \
|
||||
((void)path); \
|
||||
((void)par_sum); \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
* -- __skip_locate_ \
|
||||
* \
|
||||
|
@ -586,7 +602,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
static size_t __skip_locate_##decl(decl##_t *slist, decl##_node_t *n, decl##_node_t **path) \
|
||||
{ \
|
||||
unsigned int i; \
|
||||
size_t len = 0; \
|
||||
size_t par_sum = 0, len = 0; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
\
|
||||
if (slist == NULL || n == NULL) \
|
||||
|
@ -598,11 +614,14 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
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) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
path[i + 1] = elm; \
|
||||
par_sum += elm->field.sle_hits; \
|
||||
len++; \
|
||||
} while (i--); \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
if (__skip_compare_nodes_##decl(slist, elm, n, slist->slh_aux) == 0) { \
|
||||
path[0] = elm; \
|
||||
path[0]->field.sle_hits++; \
|
||||
__skip_rebalance_##decl(slist, len, path, par_sum); \
|
||||
} \
|
||||
return len; \
|
||||
} \
|
||||
|
@ -616,10 +635,10 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
*/ \
|
||||
static int __skip_insert_##decl(decl##_t *slist, decl##_node_t *new, int flags) \
|
||||
{ \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
int rc = 0; \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
size_t i, len, loc = 0, cur_height, new_height; \
|
||||
decl##_node_t *node, **path = (decl##_node_t **)&apath; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || new == NULL) \
|
||||
return ENOENT; \
|
||||
|
@ -725,29 +744,33 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* \
|
||||
* Find a node that matches the node `n`. This differs from the locate() \
|
||||
* API in that it does not return the path to the node, only the match. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_eq_##decl(decl##_t *slist, decl##_node_t *n) \
|
||||
decl##_node_t *prefix##skip_position_eq_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
unsigned int i; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
size_t len = 0; \
|
||||
decl##_node_t *rc = NULL, *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || n == NULL) \
|
||||
return NULL; \
|
||||
\
|
||||
i = slist->slh_head->field.sle_height; \
|
||||
\
|
||||
do { \
|
||||
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) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
} while (i--); \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
if (__skip_compare_nodes_##decl(slist, elm, n, slist->slh_aux) == 0) { \
|
||||
return elm; \
|
||||
/* Allocate a buffer, or use a static one. */ \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) { \
|
||||
path = malloc(sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
if (path == NULL) \
|
||||
goto done; \
|
||||
} \
|
||||
return NULL; \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
/* Find a `path` to `new` in the list and a match (`path[0]`) if it exists. */ \
|
||||
len = __skip_locate_##decl(slist, query, path); \
|
||||
if (len == 0) \
|
||||
goto done; \
|
||||
node = path[0]; \
|
||||
if (node != NULL) \
|
||||
rc = node; \
|
||||
done:; \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
return rc; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
|
@ -756,30 +779,34 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* Position and return a cursor at the first node that is equal to \
|
||||
* or greater than the provided node `n`, otherwise if the largest \
|
||||
* key is less than the key in `n` return NULL. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_gte_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
int cmp; \
|
||||
unsigned int i; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || query == NULL) \
|
||||
return NULL; \
|
||||
\
|
||||
i = slist->slh_head->field.sle_height; \
|
||||
/* Allocate a buffer, or use a static one. */ \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) { \
|
||||
path = malloc(sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
if (path == NULL) \
|
||||
goto done; \
|
||||
} \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
/* Find a `path` to `new` in the list and a match (`path[0]`) if it exists. */ \
|
||||
__skip_locate_##decl(slist, query, path); \
|
||||
node = path[1]; \
|
||||
do { \
|
||||
while (elm != slist->slh_tail && elm->field.sle_next[i] && __skip_compare_nodes_##decl(slist, elm->field.sle_next[i], query, slist->slh_aux) < 0) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
} while (i--); \
|
||||
do { \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, elm, query, slist->slh_aux); \
|
||||
node = node->field.sle_next[0]; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
||||
} while (cmp < 0); \
|
||||
return elm; \
|
||||
\
|
||||
done:; \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
|
@ -788,30 +815,36 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* Position and return a cursor at the first node that is greater than \
|
||||
* the provided node `n`. If the largestkey is less than the key in `n` \
|
||||
* return NULL. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_gt_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
int cmp; \
|
||||
unsigned int i; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || query == NULL) \
|
||||
return NULL; \
|
||||
\
|
||||
i = slist->slh_head->field.sle_height; \
|
||||
/* Allocate a buffer, or use a static one. */ \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) { \
|
||||
path = malloc(sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
if (path == NULL) \
|
||||
goto done; \
|
||||
} \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
/* Find a `path` to `new` in the list and a match (`path[0]`) if it exists. */ \
|
||||
__skip_locate_##decl(slist, query, path); \
|
||||
node = path[1]; \
|
||||
if (node == slist->slh_tail) \
|
||||
goto done; \
|
||||
do { \
|
||||
while (elm != slist->slh_tail && elm->field.sle_next[i] && __skip_compare_nodes_##decl(slist, elm->field.sle_next[i], query, slist->slh_aux) < 0) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
} while (i--); \
|
||||
do { \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, elm, query, slist->slh_aux); \
|
||||
} while (cmp <= 0); \
|
||||
return elm; \
|
||||
node = node->field.sle_next[0]; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, node, query, slist->slh_aux); \
|
||||
} while (cmp <= 0 && node != slist->slh_tail); \
|
||||
\
|
||||
done:; \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
|
@ -820,35 +853,32 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* Position and return a cursor at the last node that is less than \
|
||||
* or equal to node `n`. \
|
||||
* Return NULL if nothing is less than or equal. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_lte_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
int cmp; \
|
||||
unsigned int i; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || query == NULL) \
|
||||
return NULL; \
|
||||
\
|
||||
i = slist->slh_head->field.sle_height; \
|
||||
\
|
||||
do { \
|
||||
while (elm != slist->slh_tail && elm->field.sle_next[i] && __skip_compare_nodes_##decl(slist, elm->field.sle_next[i], query, slist->slh_aux) < 0) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
} while (i--); \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
if (__skip_compare_nodes_##decl(slist, elm, query, slist->slh_aux) == 0) { \
|
||||
return elm; \
|
||||
} else { \
|
||||
do { \
|
||||
elm = elm->field.sle_prev; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, elm, query, slist->slh_aux); \
|
||||
} while (cmp >= 0); \
|
||||
/* Allocate a buffer, or use a static one. */ \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) { \
|
||||
path = malloc(sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
if (path == NULL) \
|
||||
goto done; \
|
||||
} \
|
||||
return elm; \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
/* Find a `path` to `new` in the list and a match (`path[0]`) if it exists. */ \
|
||||
__skip_locate_##decl(slist, query, path); \
|
||||
node = path[0]; \
|
||||
if (node) \
|
||||
goto done; \
|
||||
node = path[1]; \
|
||||
\
|
||||
done:; \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
|
@ -856,40 +886,35 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* \
|
||||
* Position and return a cursor at the last node that is less than \
|
||||
* to the node `n`. Return NULL if nothing is less than or equal. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_lt_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
int cmp; \
|
||||
unsigned int i; \
|
||||
decl##_node_t *elm = slist->slh_head; \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || query == NULL) \
|
||||
return NULL; \
|
||||
/* Allocate a buffer, or use a static one. */ \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) { \
|
||||
path = malloc(sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
if (path == NULL) \
|
||||
goto done; \
|
||||
} \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
i = slist->slh_head->field.sle_height; \
|
||||
/* Find a `path` to `new` in the list and a match (`path[0]`) if it exists. */ \
|
||||
__skip_locate_##decl(slist, query, path); \
|
||||
node = path[1]; \
|
||||
\
|
||||
do { \
|
||||
while (elm != slist->slh_tail && elm->field.sle_next[i] && __skip_compare_nodes_##decl(slist, elm->field.sle_next[i], query, slist->slh_aux) < 0) \
|
||||
elm = elm->field.sle_next[i]; \
|
||||
} while (i--); \
|
||||
elm = elm->field.sle_next[0]; \
|
||||
do { \
|
||||
elm = elm->field.sle_prev; \
|
||||
cmp = __skip_compare_nodes_##decl(slist, elm, query, slist->slh_aux); \
|
||||
} while (cmp >= 0); \
|
||||
return elm; \
|
||||
done:; \
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
* -- skip_position_ \
|
||||
* \
|
||||
* Position a cursor relative to `n`. \
|
||||
* \
|
||||
* NOTE: This differs from _locate() in that it avoids an alloc/free \
|
||||
* for the path when SKIPLIST_MAX_HEIGHT == 1. \
|
||||
*/ \
|
||||
decl##_node_t *prefix##skip_position_##decl(decl##_t *slist, skip_pos_##decl_t op, decl##_node_t *query) \
|
||||
{ \
|
||||
|
@ -925,11 +950,11 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
* 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 *dest) \
|
||||
int prefix##skip_update_##decl(decl##_t *slist, decl##_node_t *query, void *value) \
|
||||
{ \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
int rc = 0, np; \
|
||||
decl##_node_t *src, **path = (decl##_node_t **)&apath; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL) \
|
||||
return -1; \
|
||||
|
@ -942,31 +967,29 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
} \
|
||||
memset(path, 0, sizeof(decl##_node_t *) * slist->slh_max_height + 1); \
|
||||
\
|
||||
__skip_locate_##decl(slist, dest, path); \
|
||||
src = path[0]; \
|
||||
__skip_locate_##decl(slist, query, path); \
|
||||
node = path[0]; \
|
||||
\
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
free(path); \
|
||||
\
|
||||
if (src == NULL) \
|
||||
if (node == NULL) \
|
||||
return -1; \
|
||||
\
|
||||
/* If the optional snapshots feature is configured, use it now. \
|
||||
Snapshots preserve the node if it is younger than our snapshot \
|
||||
moment. */ \
|
||||
if (slist->slh_fns.preserve_node) { \
|
||||
np = slist->slh_fns.preserve_node(slist, src, NULL); \
|
||||
np = slist->slh_fns.preserve_node(slist, node, NULL); \
|
||||
if (np > 0) \
|
||||
return np; \
|
||||
if (slist->slh_fns.snapshot_incr_era) \
|
||||
slist->slh_fns.snapshot_incr_era(slist); \
|
||||
} \
|
||||
\
|
||||
slist->slh_fns.update_entry(src); \
|
||||
slist->slh_fns.update_entry(node, value); \
|
||||
\
|
||||
/* Record the era for this node to enable snapshots. */ \
|
||||
if (slist->slh_fns.snapshot_record_era) \
|
||||
slist->slh_fns.snapshot_record_era(slist, src); \
|
||||
slist->slh_fns.snapshot_record_era(slist, node); \
|
||||
\
|
||||
return rc; \
|
||||
} \
|
||||
|
@ -978,10 +1001,10 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
*/ \
|
||||
int prefix##skip_remove_node_##decl(decl##_t *slist, decl##_node_t *query) \
|
||||
{ \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
static decl##_node_t *apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
int np = 0; \
|
||||
size_t i, len, height; \
|
||||
decl##_node_t *node, **path = (decl##_node_t **)&apath; \
|
||||
decl##_node_t *node, **path = apath; \
|
||||
\
|
||||
if (slist == NULL || query == NULL) \
|
||||
return -1; \
|
||||
|
@ -1007,8 +1030,6 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
np = slist->slh_fns.preserve_node(slist, node, NULL); \
|
||||
if (np > 0) \
|
||||
return np; \
|
||||
if (slist->slh_fns.snapshot_incr_era) \
|
||||
slist->slh_fns.snapshot_incr_era(slist); \
|
||||
} \
|
||||
/* We found it, set the next->prev to the node->prev keeping in mind \
|
||||
that the next node might be the tail). */ \
|
||||
|
@ -1192,6 +1213,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
if (slist == NULL) \
|
||||
return 0; \
|
||||
slist->slh_snap.era = slist->slh_fns.snapshot_current_era(slist); \
|
||||
slist->slh_fns.snapshot_incr_era(slist); \
|
||||
return slist->slh_snap.era; \
|
||||
} \
|
||||
\
|
||||
|
@ -1796,8 +1818,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
|||
{ \
|
||||
decl##_node_t node; \
|
||||
node.key = key; \
|
||||
node.value = value; \
|
||||
return prefix##skip_update_##decl(slist, &node); \
|
||||
return prefix##skip_update_##decl(slist, &node, (void *)value); \
|
||||
} \
|
||||
\
|
||||
/** \
|
||||
|
|
Loading…
Reference in a new issue