fixes
This commit is contained in:
parent
448aa42e6c
commit
d3d491f1c7
|
@ -7,6 +7,11 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Setting this will do two things:
|
||||
* 1) limit our max height across all instances of this datastructure.
|
||||
* 2) remove a heap allocation on frequently used paths, insert/remove/etc.
|
||||
* so, use it when you need it.
|
||||
*/
|
||||
#define SKIPLIST_MAX_HEIGHT 12
|
||||
#include "../include/sl.h"
|
||||
|
||||
|
@ -109,7 +114,7 @@ main()
|
|||
struct slex_node *n;
|
||||
|
||||
/* Insert 7 key/value pairs into the list. */
|
||||
for (int i = -2; i <= 2; i++) {
|
||||
for (int i = -200; i <= 200; i++) {
|
||||
int v;
|
||||
slex_node_t new;
|
||||
rc = api_skip_alloc_node_slex(list, &n);
|
||||
|
@ -129,17 +134,19 @@ main()
|
|||
q.key = 0;
|
||||
api_skip_remove_slex(list, &q);
|
||||
|
||||
assert(api_skip_gte_slex(list, -3) == -20);
|
||||
// assert(api_skip_gte_slex(list, -3000000) == -20);
|
||||
assert(api_skip_gte_slex(list, -2) == -20);
|
||||
assert(api_skip_gte_slex(list, 0) == 10);
|
||||
// assert(api_skip_gte_slex(list, 0) == 0);
|
||||
assert(api_skip_gte_slex(list, 2) == 20);
|
||||
assert(api_skip_gte_slex(list, 3) == 0);
|
||||
assert(api_skip_gte_slex(list, 30000000) == 0);
|
||||
|
||||
assert(api_skip_lte_slex(list, -3) == 0);
|
||||
assert(api_skip_lte_slex(list, -3000000) == 0);
|
||||
assert(api_skip_lte_slex(list, -2) == -20);
|
||||
assert(api_skip_lte_slex(list, 0) == -10);
|
||||
// assert(api_skip_lte_slex(list, 0) == 0);
|
||||
assert(api_skip_lte_slex(list, 2) == 20);
|
||||
assert(api_skip_lte_slex(list, 3) == 20);
|
||||
// assert(api_skip_lte_slex(list, 30000000) == 20);
|
||||
|
||||
FILE *of = fopen("/tmp/slm.dot", "w");
|
||||
if (!of) {
|
||||
|
|
28
include/sl.h
28
include/sl.h
|
@ -226,6 +226,9 @@
|
|||
slist->level = 0; \
|
||||
slist->length = 0; \
|
||||
slist->max = (size_t)(max < 0 ? -max : max); \
|
||||
slist->max = SKIPLIST_MAX_HEIGHT == 1 ? slist->max : SKIPLIST_MAX_HEIGHT; \
|
||||
if (SKIPLIST_MAX_HEIGHT > 1 && slist->max > SKIPLIST_MAX_HEIGHT) \
|
||||
return -1; \
|
||||
slist->cmp = cmp; \
|
||||
rc = prefix##skip_alloc_node_##decl(slist, &slist->slh_head); \
|
||||
if (rc) \
|
||||
|
@ -241,8 +244,9 @@
|
|||
for (i = 0; i < slist->max; i++) \
|
||||
slist->slh_tail->field.sle.next[i] = NULL; \
|
||||
slist->slh_head->field.sle_prev = slist->slh_tail; \
|
||||
/* Testing aid: set `max` to a negative number to seed the PRNG in a \
|
||||
predictable way and have reproducible numbers. */ \
|
||||
/* NOTE: Here's a testing aid, simply set `max` to a negative number to \
|
||||
* seed the PRNG in a predictable way and have reproducible random numbers. \
|
||||
*/ \
|
||||
if (max < 0) \
|
||||
srand(-max); \
|
||||
else \
|
||||
|
@ -315,7 +319,7 @@
|
|||
/* -- __skip_insert_ */ \
|
||||
static int __skip_insert_##decl(decl##_t *slist, decl##_node_t *n, int flags) \
|
||||
{ \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT]; \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
size_t i, len, level; \
|
||||
decl##_node_t *node, **path = (decl##_node_t **)&apath; \
|
||||
\
|
||||
|
@ -344,13 +348,17 @@
|
|||
path[i + 1]->field.sle.next[i] = n; \
|
||||
} else { \
|
||||
n->field.sle.next[i] = slist->slh_tail; \
|
||||
slist->level++; \
|
||||
} \
|
||||
} \
|
||||
n->field.sle_prev = path[1]; \
|
||||
if (n->field.sle.next[0] == slist->slh_tail) { \
|
||||
slist->slh_tail->field.sle_prev = n; \
|
||||
} \
|
||||
if (level > slist->level) { \
|
||||
slist->level = level; \
|
||||
slist->slh_head->entries.sle.len = slist->level; \
|
||||
slist->slh_tail->entries.sle.len = slist->level; \
|
||||
} \
|
||||
slist->length++; \
|
||||
\
|
||||
if (SKIPLIST_MAX_HEIGHT == 1) \
|
||||
|
@ -476,7 +484,7 @@
|
|||
/* -- skip_remove_ */ \
|
||||
int prefix##skip_remove_##decl(decl##_t *slist, decl##_node_t *n) \
|
||||
{ \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT]; \
|
||||
static decl##_node_t apath[SKIPLIST_MAX_HEIGHT + 1]; \
|
||||
size_t i, len, level; \
|
||||
decl##_node_t *node, **path = (decl##_node_t **)&apath; \
|
||||
\
|
||||
|
@ -511,9 +519,13 @@
|
|||
\
|
||||
/* Find all levels in the first element in the list that point \
|
||||
at the tail and shrink the level. */ \
|
||||
while (slist->level > 0 && slist->slh_head->field.sle.next[slist->level] == slist->slh_tail) { \
|
||||
slist->level--; \
|
||||
} \
|
||||
i = 0; \
|
||||
node = slist->slh_head; \
|
||||
while (node->field.sle.next[i] != slist->slh_tail && i++ < slist->level) \
|
||||
; \
|
||||
slist->level = i; \
|
||||
slist->slh_head->field.sle.len = i; \
|
||||
slist->slh_tail->field.sle.len = i; \
|
||||
slist->length--; \
|
||||
} \
|
||||
return 0; \
|
||||
|
|
Loading…
Reference in a new issue