extern void *skip_search(skip_list *sl, unsigned int key) { int i; skip_node *x; check_hard(sl, "Invalid Skip List"); check_hard(key, "Invalid Key"); x = sl->header; for (i = sl->level - 1; i >= 0; i--) { while (x->level[i].forward && // not end NULL default_compare(x->level[i].forward->key, key)) { x = x->level[i].forward; } } // make sure were not nulled x = (x->level[0].forward) ? x->level[0].forward : x; if (x->key == key) { //log_success("Found key"); return x->payload; } else { //log_warn("Key search failed"); return NULL; } }
//TODO: Switch to a more robust error handling policy extern int skip_insert(skip_t sl, unsigned int key, void *payload) { int i, rand_level; skip_node *x, *update[SKIP_MAX]; check_hard(sl, "Invalid Skip List"); check_hard(key, "Invalid Key"); check_hard(payload, " Empty payload"); x = sl->header; for (i = sl->level - 1; i >= 0; i--) { while (x->level[i].forward && // not end NULL default_compare(x->level[i].forward->key, key)) { x = x->level[i].forward; // log_warn("still in whleLoop"); } update[i] = x; sl->finger[i] = x; //log_warn("still in ForLoop"); } // make sure were not nulled x = (x->level[0].forward) ? x->level[0].forward : x; //TODO: Decide if we should warn, or reject an overwrite, //log_info(" %u, %u", x->key, key); if (x->key == key) { sl->free_func(x->payload); x->payload = payload; //log_warn("Key overwrite"); return 2; } else { rand_level = random_level(); if (rand_level > sl->level) { for (i = sl->level; i < rand_level; i++) { update[i] = sl->header; sl->finger[i] = sl->header; } sl->level = rand_level; //log_info("Lvl: %d",sl->level); } x = create_skip_node(rand_level, key, payload); for (i = 0 ; i < rand_level; i++) { x->level[i].forward = update[i]->level[i].forward; update[i]->level[i].forward = x; } //log_success("inserted key %u and data", key); sl->length++; return 1; } }
int main (int argc, char *argv[]) { tests_start_mpfr (); check_inexact (); check_hard (); check_special (); check_lowr (); check_float (); /* checks single precision */ check_double (); check_convergence (); check_64 (); check4("4.0","4.503599627370496e15", MPFR_RNDZ, 62, "0.10000000000000000000000000000000000000000000000000000000000000E-49"); check4("1.0","2.10263340267725788209e+187", MPFR_RNDU, 65, "0.11010011111001101011111001100111110100000001101001111100111000000E-622"); check4("2.44394909079968374564e-150", "2.10263340267725788209e+187",MPFR_RNDU, 65, "0.11010011111001101011111001100111110100000001101001111100111000000E-1119"); consistency (); test_20070603 (); test_20070628 (); test_generic (2, 800, 50); tests_end_mpfr (); return 0; }
//TODO: Switch to a more robust error handling policy extern skip_t skip_init(free_func_t free_func) { int i; skip_list *new_skip; new_skip = malloc(sizeof(*new_skip)); check_hard(new_skip, "Couldn't find memory for a new skip list."); // data structure callbacks new_skip->free_func = (free_func == NULL) ? default_free : free_func; // init our random generator srand(time(NULL)); new_skip->level = 1; // following algorithm to the letter new_skip->length = 0; new_skip->header = create_skip_node(SKIP_MAX, 0, NULL); for (i = 0; i < SKIP_MAX; i++) { new_skip->finger[i] = NULL; new_skip->header->level[i].forward = NULL; } return new_skip; }
skip_node *create_skip_node(int level, unsigned int key, void *payload) { skip_node *node = malloc(sizeof(*node) + level * sizeof(struct skip_level)); //TODO: Switch to a more robust error handling policy check_hard(node, "Failed to find memory for a new skip node"); node->key = key; node->payload = payload; return node; }
//TODO: Switch to a more robust error handling policy extern int skip_delete(skip_t sl, unsigned int key) { int i; skip_node *x, *update[SKIP_MAX]; check_hard(sl, "Invalid Skip List"); check_hard(key, "Invalid Key"); x = sl->header; for (i = sl->level - 1; i >= 0; i--) { while (x->level[i].forward && // not end NULL default_compare(x->level[i].forward->key, key)) { x = x->level[i].forward; } update[i] = x; sl->finger[i] = x; } // make sure were not nulled x = (x->level[0].forward) ? x->level[0].forward : x; if (x->key == key) { for (i = 0; i < sl->level ; i++) { if (update[i]->level[i].forward == x) { update[i]->level[i].forward = x->level[i].forward; } } sl->free_func(x->payload); free(x); while (sl->level > 1 && (sl->header->level[sl->level - 1].forward == NULL)) { // log_info("Where going down a level"); sl->level--; } sl->length--; return 1; } else { return 0; } }
extern void skip_destroy(skip_t sl) { check_hard(sl, "Invalid pointer to skip list"); skip_node *next, *node; node = sl->header->level[0].forward; free(sl->header); while (node) { next = node->level[0].forward; sl->free_func(node->payload); free(node); node = next; } free(sl); }
extern int skip_length(skip_t s) { check_hard(s, "Invalid pointer to skip list"); return s->length; }