//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; }
bool skip_list<T>::insert_node(int key, T value) { //find in every level in the past skip list //which node is the last smaller than key skip_node<T> *last_smaller_in_level[MAX_LEVEL]; skip_node<T> *tmp = header; for(int i = 0; i <= level; i++) { while(tmp->next_in_level[i] != NULL) { if(tmp->next_in_level[i]->key == key) { printf("can't insert same key\n"); return false; } if(tmp->next_in_level[i]->key > key) break; else tmp = tmp->next_in_level[i]; } last_smaller_in_level[i] = tmp; } //random how much level to inserit //build a new skip list int insert_level = get_random_level(); printf("key %d insert_level %d\n", key, insert_level); skip_node<T> *p = create_skip_node(key, value); if(insert_level > level) { for(int i = 0; i <= level; i++) { skip_node<T> *tmp2 = last_smaller_in_level[i]->next_in_level[i]; last_smaller_in_level[i]->next_in_level[i] = p; p->next_in_level[i] = tmp2; } for(int i = level + 1; i <= insert_level; i++) { header->next_in_level[i] = p; } level = insert_level; } else { for(int i = 0; i <= insert_level; i++) { skip_node<T> *tmp2 = last_smaller_in_level[i]->next_in_level[i]; last_smaller_in_level[i]->next_in_level[i] = p; p->next_in_level[i] = tmp2; } } return true; }
//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; } }