snapshot v2/p4; _insert done
This commit is contained in:
parent
d5b5599c5d
commit
1b97e7b8d9
1 changed files with 42 additions and 2 deletions
44
include/sl.h
44
include/sl.h
|
@ -463,9 +463,49 @@
|
|||
level = __skip_toss_##decl(slist->max - 1); \
|
||||
n->field.sle.gen = slist->gen; \
|
||||
n->field.sle.height = level; \
|
||||
/* preserve nodes for snapshots if necessary */ \
|
||||
\
|
||||
/* preserve nodes for snapshots if necessary \
|
||||
* \
|
||||
* ALGORITHM: \
|
||||
* Foreach node in `path`, if the generation in that element \
|
||||
* is less than the current generation for the list then \
|
||||
* that node must be preserved before being mutated for this \
|
||||
* insert. So we: \
|
||||
* a) allocate a new node and copy this node into it without \
|
||||
* copying the user-supplied additional memory (that will \
|
||||
* happen iff an _update() is called on the node). \
|
||||
* b) zero out the next sle.prev/next[] pointers \
|
||||
* c) determine if this is a duplicate, if so we set the \
|
||||
* sle.next[1] field to 0x1 as a reminder to re-insert \
|
||||
* this element as a duplicate in the restore function. \
|
||||
* d) ignore the head and the tail nodes in path[] \
|
||||
*/ \
|
||||
for (i = 0; i < len; i++) { \
|
||||
if (path[i]->field.sle.gen >= slist->max_gen) { \
|
||||
if (path[i]->field.sle.gen < slist->gen) { \
|
||||
if (path[i] == slist->slh_head || path[i] == slist->slh_tail) \
|
||||
continue; \
|
||||
int rc; \
|
||||
decl##_node_t *src = node, *dest, *this; \
|
||||
size_t amt = sizeof(src); \
|
||||
char *d = NULL; \
|
||||
const char *s = (const char *)src; \
|
||||
rc = prefix##skip_alloc_node_##decl(slist, &dest); \
|
||||
if (rc) \
|
||||
return rc; \
|
||||
d = (char *)dest; \
|
||||
for (size_t i = 0; i < amt; i++) \
|
||||
d[i] = s[i]; \
|
||||
\
|
||||
this = dest; \
|
||||
this->field.sle.prev = NULL; \
|
||||
__SKIP_NEXT_ENTRIES_B2T(field, this) \
|
||||
{ \
|
||||
this->field.sle.next[lvl] = NULL; \
|
||||
} \
|
||||
\
|
||||
if (__skip_key_compare_##decl(slist, dest, dest->field.sle.next[0], slist->aux) == 0 || \
|
||||
__skip_key_compare_##decl(slist, dest, dest->field.sle.prev, slist->aux) == 0) \
|
||||
dest->field.sle.next[0] = (decl##_node_t *)0x1; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
|
Loading…
Reference in a new issue