From efd1933c6257b4547af956e822fd24223be2b463 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 21 Mar 2024 14:43:10 -0400 Subject: [PATCH] WIP snaps, pt6; serialization p2 --- examples/slm.c | 74 ++++++++++++++++++++++++++++---------------------- include/sl.h | 62 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 94 insertions(+), 42 deletions(-) diff --git a/examples/slm.c b/examples/slm.c index 8357c5f..7f6c4e0 100644 --- a/examples/slm.c +++ b/examples/slm.c @@ -43,17 +43,27 @@ struct slex_node { */ SKIPLIST_DECL( slex, api_, entries, - /* free node */ { (void)node; }, + /* free node */ { free(node->value); }, /* update node */ { node->value = new->value; }, /* snapshot node */ { new->key = node->key; - new->value = strncpy(new->value, node->value, strlen(node->value)); + char *nv = calloc(strlen(node->value) + 1, sizeof(char)); + if (nv == NULL) + return NULL; /* leaks some memory... TODO */ + new->value = strncpy(nv, node->value, strlen(node->value)); }, /* size in bytes of the content stored in an entry by you */ - { - size = strlen(node->value) + 1; - }) + { size = strlen(node->value) + 1; }) + +/* Optional: Create the functions used to visualize a Skiplist (DOT/Graphviz) */ +SKIPLIST_DECL_DOT(slex, api_, entries) + +void +sprintf_slex_node(slex_node_t *node, char *buf) +{ + sprintf(buf, "%d:%s", node->key, node->value); +} /* * Getter @@ -97,23 +107,31 @@ __slm_key_compare(slex_t *list, slex_node_t *a, slex_node_t *b, void *aux) return 0; } -static char* to_lower(char* str) { +static char * +to_lower(char *str) +{ char *p = str; - for ( ; *p; ++p) *p = *p >= 'A' && *p <= 'Z' ? *p|0x60 : *p; + for (; *p; ++p) + *p = *p >= 'A' && *p <= 'Z' ? *p | 0x60 : *p; return str; } -static char* to_upper(char* str) { +static char * +to_upper(char *str) +{ char *p = str; - for ( ; *p; ++p) *p = *p >= 'a' && *p <= 'z' ? *p&~0x20 : *p; + for (; *p; ++p) + *p = *p >= 'a' && *p <= 'z' ? *p & ~0x20 : *p; return str; } -static char *int_to_roman_numeral(int num){ - int del[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; // Key value in Roman counting - char * sym[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; //Symbols for key values - // The maximum length of the Roman numeral representation for the maximum signed 64-bit integer would be approximately 19 * 3 = 57 characters, assuming every digit is - // represented by its Roman numeral equivalent up to 3 repetitions. Therefore, 64 should be more than enough. +static char * +int_to_roman_numeral(int num) +{ + int del[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; // Key value in Roman counting + char *sym[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; // Symbols for key values + // The maximum length of the Roman numeral representation for the maximum signed 64-bit integer would be approximately 19 * 3 = 57 characters, assuming + // every digit is represented by its Roman numeral equivalent up to 3 repetitions. Therefore, 64 should be more than enough. char *res = (char *)calloc(64, sizeof(char)); int i = 0; if (num < 0) { @@ -125,21 +143,23 @@ static char *int_to_roman_numeral(int num){ res[0] = '0'; return res; } - while (num){ //while input number is not zero - while (num/del[i]){ //while a number contains the largest key value possible - strcat(res, sym[i]); //append the symbol for this key value to res string - num -= del[i]; //subtract the key value from number + while (num) { // while input number is not zero + while (num / del[i]) { // while a number contains the largest key value possible + strcat(res, sym[i]); // append the symbol for this key value to res string + num -= del[i]; // subtract the key value from number } - i++; //proceed to the next key value + i++; // proceed to the next key value } return res; } -void shuffle(int *array, size_t n) { +void +shuffle(int *array, size_t n) +{ if (n > 1) { size_t i; for (i = n - 1; i > 0; i--) { - size_t j = (unsigned int)(rand() % (i+1)); /* NOLINT(*-msc50-cpp) */ + size_t j = (unsigned int)(rand() % (i + 1)); /* NOLINT(*-msc50-cpp) */ int t = array[j]; array[j] = array[i]; array[i] = t; @@ -147,18 +167,6 @@ void shuffle(int *array, size_t n) { } } -#define DOT -#ifdef DOT -/* Also declare the functions used to visualize a Sliplist (DOT/Graphviz) */ -SKIPLIST_DECL_DOT(slex, api_, entries) - -void -sprintf_slex_node(slex_node_t *node, char *buf) -{ - sprintf(buf, "%d:%s", node->key, node->value); -} -#endif - #define TEST_ARRAY_SIZE 50 int diff --git a/include/sl.h b/include/sl.h index ac3c7c5..eb14b37 100644 --- a/include/sl.h +++ b/include/sl.h @@ -17,16 +17,18 @@ * I'd like to thank others for thoughtfully licensing their work, the * community of software engineers succeeds when we work together. * - * Portions of this code are derived from copyrighted work: + * Portions of this code are derived from other copyrighted works: * - * - MIT LICENSE + * - MIT License * - https://github.com/greensky00/skiplist * 2017-2024 Jung-Sang Ahn * - https://github.com/paulross/skiplist - * Copyright (c) 2017-2023 Paul Ross - * - gist skiplist.c - * - khash.h - * - async_nif.h + * Copyright (c) 2017-2023 Paul Ross + * - https://github.com/JP-Ellis/rust-skiplist + * Copyright (c) 2015 Joshua Ellis + * - Public Domain + * - https://gist.github.com/zhpengg/2873424 + * Zhipeng Li */ #ifndef _SKIPLIST_H_ @@ -82,9 +84,51 @@ * * References for this implementation include, but are not limited to: * - * - Skiplists: a probabilistic alternative to balanced trees. - * https://www.cl.cam.ac.uk/teaching/2005/Algorithms/skiplists.pdf - * 1990 William Pugh published: + * - Skip lists: a probabilistic alternative to balanced trees + * @article{10.1145/78973.78977, + * author = {Pugh, William}, + * title = {Skip lists: a probabilistic alternative to balanced trees}, + * year = {1990}, issue_date = {June 1990}, + * publisher = {Association for Computing Machinery}, + * address = {New York, NY, USA}, + * volume = {33}, number = {6}, issn = {0001-0782}, + * url = {https://doi.org/10.1145/78973.78977}, + * doi = {10.1145/78973.78977}, + * journal = {Commun. ACM}, month = {jun}, pages = {668–676}, numpages = {9}, + * keywords = {trees, searching, data structures}, + * download = {https://www.cl.cam.ac.uk/teaching/2005/Algorithms/skiplists.pdf} + * } + * + * - Tutorial: The Ubiquitous Skiplist, its Variants, and Applications in Modern Big Data Systems + * @article{Vadrevu2023TutorialTU, + * title={Tutorial: The Ubiquitous Skiplist, its Variants, and Applications in Modern Big Data Systems}, + * author={Venkata Sai Pavan Kumar Vadrevu and Lu Xing and Walid G. Aref}, + * journal={ArXiv}, + * year={2023}, + * volume={abs/2304.09983}, + * url={https://api.semanticscholar.org/CorpusID:258236678}, + * download={https://arxiv.org/pdf/2304.09983.pdf} + * } + * + * - The Splay-List: A Distribution-Adaptive Concurrent Skip-List + * @misc{aksenov2020splaylist, + * title={The Splay-List: A Distribution-Adaptive Concurrent Skip-List}, + * author={Vitaly Aksenov and Dan Alistarh and Alexandra Drozdova and Amirkeivan Mohtashami}, + * year={2020}, + * eprint={2008.01009}, + * archivePrefix={arXiv}, + * primaryClass={cs.DC}, + * download={https://arxiv.org/pdf/2008.01009.pdf} + * } + * + * - JellyFish: A Fast Skip List with MVCC}, + * @article{Yeon2020JellyFishAF, + * title={JellyFish: A Fast Skip List with MVCC}, + * author={Jeseong Yeon and Leeju Kim and Youil Han and Hyeon Gyu Lee and Eunji Lee and Bryan Suk Joon Kim}, + * journal={Proceedings of the 21st International Middleware Conference}, + * year={2020}, + * url={https://api.semanticscholar.org/CorpusID:228086012} + * } */ /*