This commit is contained in:
Gregory Burd 2024-05-24 22:55:52 -04:00
parent 8b71b98bd7
commit c5529b6677

View file

@ -53,20 +53,23 @@
#define _SKIPLIST_H_ #define _SKIPLIST_H_
/* /*
* This file defines a skiplist data structure written in C. Implemented as * This file defines a skip-list data structure written in C. Implemented as
* using macros this code provides a way to essentially "template" (as in C++) * using macros this code provides a way to essentially "template" (as in C++)
* and emit code with types and functions specific to your use case. You can * and emit code with types and functions specific to your use case. You can
* apply these macros multiple times safely in your code, once for each * apply these macros multiple times safely, once for each list type you need.
* application.
* *
* A skiplist is a sorted list with O(log(n)) on average for most operations. * A skip-list is a sorted list with O(log(n)) on average for most operations.
* It is a probabilistic datastructure, meaning that it does not guarantee * It is a probabilistic datastructure, meaning that it does not guarantee
* O(log(n)) it approximates it over time. This implementation improves the * O(log(n)), but it has been shown to approximate it over time. This
* probability by integrating the splay list algorithm for rebalancing trading * implementation includes the rebalancing techniques that improve on that
* off a bit of computational overhead and code complexity for a nearly always * approximation using an adaptive technique called "splay-list" (named after
* optimal, or "perfect" skiplist. * the splay-tree due to the similarities between the two). It is similar to a
* standard skip-list, with the key distinction that the height of each element
* adapts dynamically to its access rate: popular elements increase in height,
* whereas rarely-accessed elements decrease in height. See below for the link
* to the research behind this adaptive technique.
* *
* Conceptually, a skiplist is arranged as follows: * Conceptually, at a high level, a skip-list is arranged as follows:
* *
* <head> ----------> [2] --------------------------------------------------> [9] ----------> * <head> ----------> [2] --------------------------------------------------> [9] ---------->
* <head> ----------> [2] ------------------------------------[7] ----------> [9] ----------> * <head> ----------> [2] ------------------------------------[7] ----------> [9] ---------->
@ -79,22 +82,22 @@
* diagram). This allows for the algorithm to move down the list faster than * diagram). This allows for the algorithm to move down the list faster than
* having to visit every element. * having to visit every element.
* *
* Conceptually, the skiplist can be thought of as a stack of linked lists. At * A skip-list can be thought of as a stack of linked lists. At the very bottom
* the very bottom is the full linked list with every element, and each layer * is a linked list with every element, and each layer above corresponds to a
* above corresponds to a linked list containing a random subset of the elements * linked list containing a random subset of the elements from the layer
* from the layer immediately below it. The probability distribution that * immediately below it. The probability distribution that determines this
* determines this random subset can be customized, but typically a layer will * random subset can be customized, but typically a layer will contain half the
* contain half the nodes from the layer below. * nodes from the layer below.
* *
* This implementation maintains a doubly-linked list at the bottom layer to * This implementation maintains a doubly-linked list at the bottom layer to
* support efficient iteration in either direction. There is also a guard * support efficient iteration in either direction. There is also a guard node
* node at the tail rather than simply pointing to NULL. * at the tail rather than simply pointing to NULL.
* *
* <head> <-> [1] <-> [2] <-> [3] <-> [4] <-> [5] <-> [6] <-> [7] <-> <tail> * <head> <-> [1] <-> [2] <-> [3] <-> [4] <-> [5] <-> [6] <-> [7] <-> <tail>
* *
* Safety: * Safety:
* *
* The ordered skiplist relies on a well-behaved comparison * The ordered skip-list relies on a well-behaved comparison
* function. Specifically, given some ordering function f(a, b), it must satisfy * function. Specifically, given some ordering function f(a, b), it must satisfy
* the following properties: * the following properties:
* *
@ -639,7 +642,7 @@ void __attribute__((format(printf, 4, 5))) __skip_diag_(const char *file, int li
size_t i, j, u_hits, hits_CHu = 0, hits_CHv = 0, delta_height, new_height, cur_hits, prev_hits; \ size_t i, j, u_hits, hits_CHu = 0, hits_CHv = 0, delta_height, new_height, cur_hits, prev_hits; \
double k_threshold, m_total_hits, asc_cond, dsc_cond; \ double k_threshold, m_total_hits, asc_cond, dsc_cond; \
\ \
/* return; TODO/WIP */ \ /* return; TODO/WIP */ \
/* Total hits, `k`, accross all nodes. */ \ /* Total hits, `k`, accross all nodes. */ \
m_total_hits = slist->slh_head->field.sle_levels[slist->slh_head->field.sle_height].hits; \ m_total_hits = slist->slh_head->field.sle_levels[slist->slh_head->field.sle_height].hits; \
\ \