WIP snaps
This commit is contained in:
parent
48a09e0c4d
commit
25f86f9e32
|
@ -41,7 +41,9 @@ struct slex_node {
|
|||
SKIPLIST_DECL(
|
||||
slex, api_, entries,
|
||||
/* free node */ { (void)node; },
|
||||
/* update node */ { node->value = new->value; })
|
||||
/* update node */ { node->value = new->value; },
|
||||
/* copy node */ { new->key = node->key; new->value = node->value; },
|
||||
int, /* into array */ { elm = node->value; })
|
||||
|
||||
/*
|
||||
* Getter
|
||||
|
|
65
include/sl.h
65
include/sl.h
|
@ -110,10 +110,6 @@
|
|||
struct type *prev, **next; \
|
||||
size_t cap, len; \
|
||||
} sle; \
|
||||
struct __skiplist_revs { \
|
||||
struct __skiplist_idx **rev; \
|
||||
size_t ref; \
|
||||
} **slr; \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -141,7 +137,7 @@
|
|||
fn \
|
||||
}
|
||||
|
||||
#define SKIPLIST_DECL(decl, prefix, field, free_node_blk, update_node_blk) \
|
||||
#define SKIPLIST_DECL(decl, prefix, field, free_node_blk, update_node_blk, snap_node_blk, array_type, into_array_blk) \
|
||||
\
|
||||
struct __##decl##_path { \
|
||||
size_t cap; \
|
||||
|
@ -557,6 +553,7 @@
|
|||
int prefix##skip_destroy_##decl(decl##_t *slist) \
|
||||
{ \
|
||||
decl##_node_t *node, *next; \
|
||||
\
|
||||
if (slist == NULL) \
|
||||
return 0; \
|
||||
if (prefix##skip_size_##decl(slist) == 0) \
|
||||
|
@ -577,22 +574,70 @@
|
|||
* 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. \
|
||||
* \
|
||||
* NOTE: There are many fancy algorithms for this, for now \
|
||||
* this implementation will simply create a copy of the nodes. \
|
||||
*/ \
|
||||
int prefix##skip_snapshot_##decl(decl##_t *slist) \
|
||||
decl##_node_t **prefix##skip_snapshot_##decl(decl##_t *slist) \
|
||||
{ \
|
||||
((void)slist); /* TODO */ \
|
||||
decl##_node_t **array, *node, *new; \
|
||||
\
|
||||
if (slist == NULL) \
|
||||
return 0; \
|
||||
if (prefix##skip_size_##decl(slist) == 0) \
|
||||
return 0; \
|
||||
\
|
||||
new = array = calloc(slist->length, sizeof(decl##_node_t) + 1); \
|
||||
if (array == NULL) \
|
||||
return NULL; \
|
||||
\
|
||||
node = prefix##skip_head_##decl(slist); \
|
||||
do { \
|
||||
memcopy(new, node, sizeof(decl##_node_t)); \
|
||||
snap_node_blk; \
|
||||
node = prefix##skip_next_node_##decl(slist, node); \
|
||||
new += sizeof(decl##_node_t); \
|
||||
} while (node != NULL); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
/* -- skip_restore_snapshot_ */ \
|
||||
int prefix##skip_restore_snapshot_##decl(decl##_t *slist) \
|
||||
decl##_t *prefix##skip_restore_snapshot_##decl(decl##_node_t **snap, int (*cmp)(struct list * head, struct type * a, struct type * b, void *aux)) \
|
||||
{ \
|
||||
((void)slist); /* TODO */ \
|
||||
int rc = 0; \
|
||||
decl##_t *slist(decl##_t *) cmalloc(1, sizeof(decl##_t)); \
|
||||
\
|
||||
if (slist == NULL) { \
|
||||
errno = ENOMEM; \
|
||||
return NULL; \
|
||||
} \
|
||||
/* memcpy head from snap, set cmp fn, memcpy each node into newly \
|
||||
allocated node, insert into list allow dups */ \
|
||||
((void)slist); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
/* -- skip_dispose_snapshot_ */ \
|
||||
int prefix##skip_dispose_snapshot_##decl(decl##_t *slist) \
|
||||
int prefix##skip_dispose_snapshot_##decl(decl##_node_t **snap) \
|
||||
{ \
|
||||
decl##_node_t *node = *snap; \
|
||||
do { \
|
||||
free_node_blk; \
|
||||
node += sizeof(decl##_node_t); \
|
||||
} while (*node != NULL); \
|
||||
free(snap); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
/* -- skip_to_array_ */ \
|
||||
int prefix##skip_to_array_##decl(decl##_t *slist) \
|
||||
{ \
|
||||
((void)slist); /* TODO array_type into_array_blk */ \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
/* -- skip_from_array_ */ \
|
||||
int prefix##skip_from_array_##decl(decl##_t *slist) \
|
||||
{ \
|
||||
((void)slist); /* TODO */ \
|
||||
return 0; \
|
||||
|
|
Loading…
Reference in a new issue