Пример #1
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;
}
Пример #2
0
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;
}
Пример #3
0
//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;
    }
}