splay v1/p2; decent cond
This commit is contained in:
parent
c87d7f5014
commit
bfc5c76b30
4
Makefile
4
Makefile
|
@ -34,7 +34,7 @@ test: $(TESTS)
|
||||||
# env LSAN_OPTIONS=verbosity=1:log_threads=1 ./tests/test
|
# env LSAN_OPTIONS=verbosity=1:log_threads=1 ./tests/test
|
||||||
|
|
||||||
tests/test: $(TEST_OBJS) $(STATIC_LIB)
|
tests/test: $(TEST_OBJS) $(STATIC_LIB)
|
||||||
$(CC) $^ -o $@ $(CFLAGS) $(TEST_FLAGS) -pthread
|
$(CC) $^ -o $@ $(CFLAGS) $(TEST_FLAGS) -lm -pthread
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) munit.o test.o
|
rm -f $(OBJS) munit.o test.o
|
||||||
|
@ -61,7 +61,7 @@ examples/mls.c: examples/slm.c
|
||||||
# $(CC) $(CFLAGS) -C -E examples/slm.c | sed -e '1,7d' -e 's/^#\( [0-9]* ".*$$\)/\/\* \1 \*\//' | clang-format > examples/mls.c
|
# $(CC) $(CFLAGS) -C -E examples/slm.c | sed -e '1,7d' -e 's/^#\( [0-9]* ".*$$\)/\/\* \1 \*\//' | clang-format > examples/mls.c
|
||||||
|
|
||||||
examples/mls: examples/mls.o $(STATIC_LIB)
|
examples/mls: examples/mls.o $(STATIC_LIB)
|
||||||
$(CC) $^ -o $@ $(CFLAGS) $(TEST_FLAGS) -pthread
|
$(CC) $^ -o $@ $(CFLAGS) $(TEST_FLAGS) -lm -pthread
|
||||||
|
|
||||||
#dot:
|
#dot:
|
||||||
# ./examples/mls
|
# ./examples/mls
|
||||||
|
|
47
include/sl.h
47
include/sl.h
|
@ -31,8 +31,14 @@
|
||||||
* Zhipeng Li <zhpeng.is@gmail.com>
|
* Zhipeng Li <zhpeng.is@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES // needed to have definition of M_LOG2E
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -41,6 +47,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#ifndef _SKIPLIST_H_
|
#ifndef _SKIPLIST_H_
|
||||||
#define _SKIPLIST_H_
|
#define _SKIPLIST_H_
|
||||||
|
@ -254,7 +261,8 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
void (*snapshot_record_era)(struct decl *, decl##_node_t *); \
|
void (*snapshot_record_era)(struct decl *, decl##_node_t *); \
|
||||||
} slh_fns; \
|
} slh_fns; \
|
||||||
struct { \
|
struct { \
|
||||||
size_t threshold; \
|
size_t threshold; /* `k`, the floor of log(max height) */ \
|
||||||
|
size_t total_hits; /* total hits across nodes in the list */ \
|
||||||
} slh_splay; \
|
} slh_splay; \
|
||||||
struct { \
|
struct { \
|
||||||
size_t era; \
|
size_t era; \
|
||||||
|
@ -403,6 +411,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
slist->slh_max_height = SKIPLIST_MAX_HEIGHT == 1 ? slist->slh_max_height : SKIPLIST_MAX_HEIGHT; \
|
slist->slh_max_height = SKIPLIST_MAX_HEIGHT == 1 ? slist->slh_max_height : SKIPLIST_MAX_HEIGHT; \
|
||||||
if (SKIPLIST_MAX_HEIGHT > 1 && slist->slh_max_height > SKIPLIST_MAX_HEIGHT) \
|
if (SKIPLIST_MAX_HEIGHT > 1 && slist->slh_max_height > SKIPLIST_MAX_HEIGHT) \
|
||||||
return -1; \
|
return -1; \
|
||||||
|
slist->slh_splay.threshold = floor(log(max) / M_LOG2E); \
|
||||||
slist->slh_fns.free_entry = __skip_free_entry_fn_##decl; \
|
slist->slh_fns.free_entry = __skip_free_entry_fn_##decl; \
|
||||||
slist->slh_fns.update_entry = __skip_update_entry_fn_##decl; \
|
slist->slh_fns.update_entry = __skip_update_entry_fn_##decl; \
|
||||||
slist->slh_fns.archive_entry = __skip_archive_entry_fn_##decl; \
|
slist->slh_fns.archive_entry = __skip_archive_entry_fn_##decl; \
|
||||||
|
@ -585,10 +594,30 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
*/ \
|
*/ \
|
||||||
static void __skip_rebalance_##decl(decl##_t *slist, size_t len, decl##_node_t **path, size_t par_sum) \
|
static void __skip_rebalance_##decl(decl##_t *slist, size_t len, decl##_node_t **path, size_t par_sum) \
|
||||||
{ \
|
{ \
|
||||||
((void)slist); \
|
size_t i; \
|
||||||
((void)len); \
|
double asc_cond, dsc_cond; \
|
||||||
((void)path); \
|
\
|
||||||
((void)par_sum); \
|
/* Moving backwards along the path... */ \
|
||||||
|
for (i = 1; i <=len; i++) { \
|
||||||
|
if (par_sum > 0) { \
|
||||||
|
/* check the decent condition: \
|
||||||
|
par_sum <= hits total / (2 ^ (height of head - height of node)) \
|
||||||
|
*/ \
|
||||||
|
dsc_cond = pow(2.0, slist->slh_head->field.sle_height - path[i]->field.sle_height); \
|
||||||
|
if (0 && par_sum <= dsc_cond) { \
|
||||||
|
/* reduce height by one, change forward pointer */ \
|
||||||
|
path[i - 1]->field.sle_next[i] = path[i]->field.sle_next[i]; \
|
||||||
|
path[i]->field.sle_next[i] = slist->slh_tail; \
|
||||||
|
path[i]->field.sle_height--; \
|
||||||
|
} \
|
||||||
|
/* check the ascent condition \
|
||||||
|
par_sum + node_hits > hits total / (2 ^ (height of head - height of node - 1)) \
|
||||||
|
*/ \
|
||||||
|
asc_cond = pow(2.0, slist->slh_head->field.sle_height - path[i]->field.sle_height - 1); \
|
||||||
|
if (+ path[i]->field.sle_hits > asc_cond) { \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/** \
|
/** \
|
||||||
|
@ -706,6 +735,8 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
slist->slh_head->field.sle_height = new_height; \
|
slist->slh_head->field.sle_height = new_height; \
|
||||||
slist->slh_tail->field.sle_height = new_height; \
|
slist->slh_tail->field.sle_height = new_height; \
|
||||||
} \
|
} \
|
||||||
|
/* Adjust the splay threshold based on the height. */ \
|
||||||
|
slist->slh_splay.threshold = floor(log(slist->slh_head->field.sle_height) / M_LOG2E); \
|
||||||
/* Record the era for this node to enable snapshots. */ \
|
/* Record the era for this node to enable snapshots. */ \
|
||||||
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); \
|
||||||
|
@ -1058,12 +1089,14 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
\
|
\
|
||||||
slist->slh_fns.free_entry(node); \
|
slist->slh_fns.free_entry(node); \
|
||||||
\
|
\
|
||||||
/* Reduce the height of the header. */ \
|
/* 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_next[i] != 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; \
|
||||||
|
/* Adjust the splay threshold based on the height. */ \
|
||||||
|
slist->slh_splay.threshold = floor(log(slist->slh_head->field.sle_height) / M_LOG2E); \
|
||||||
\
|
\
|
||||||
slist->slh_length--; \
|
slist->slh_length--; \
|
||||||
} \
|
} \
|
||||||
|
@ -1218,7 +1251,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/** \
|
/** \
|
||||||
* -- skip_restore_snapshot_ \
|
* -- skip_restore_snapshot_ TODO test! \
|
||||||
* \
|
* \
|
||||||
* Restores the Skiplist to generation `era`. Once you restore `era` you \
|
* Restores the Skiplist to generation `era`. Once you restore `era` you \
|
||||||
* can no longer access any generations > `era`. \
|
* can no longer access any generations > `era`. \
|
||||||
|
|
Loading…
Reference in a new issue