Esempio n. 1
0
int skiplist_insert(skiplist *list, int key, int value)
{
    snode *update[SKIPLIST_MAX_LEVEL+1];
    snode *x = list->header;
    int i, level;
    for (i = list->level; i >= 1; i--) {
        while (x->forward[i]->key < key)
            x = x->forward[i];
        update[i] = x;
    }
    x = x->forward[1];
 
    if (key == x->key) {
        x->value = value;
        return 0;
    } else {
        level = rand_level();
        if (level > list->level) {
            for (i = list->level+1; i <= level; i++) {
                update[i] = list->header;
            }
            list->level = level;
        }
 
        x = (snode *)malloc(sizeof(snode));
        x->key = key;
        x->value = value;
        x->forward = (snode **)malloc(sizeof(snode*) * (level + 1));
        for (i = 1; i <= level; i++) {
            x->forward[i] = update[i]->forward[i];
            update[i]->forward[i] = x;
        }
    }
    return 0;
}
Esempio n. 2
0
int skiplist_insert_raw(SkipList *list, unsigned char *key, void *value, int(* cmp)(unsigned char *, unsigned char *))
{
    Node *update[SKIPLIST_MAX_LEVEL + 1];
    Node *x = list->header;
    int i, level;
    for(i = list->level; i >= 1; i--) {
        while(cmp(x->forward[i]->key, key) < 0) {
            x = x->forward[i]; 
        }
        update[i] = x;
    }
    x = x->forward[1];

    if (cmp(key, x->key) == 0) {
        return 1; 
    } 
    /*
    if (key == x->key) {
        free(x->value);
        x->value = value; 
        return 0;
    }
    */
    else {
        level = rand_level();
        if (level > list->level) {
            for(i = list->level + 1; i <= level; i++) {
                update[i] = list->header; 
            } 
            list->level = level;
        } 

        x = (Node *)malloc(sizeof(Node));
        if (x == NULL) {
            printf("Error skiplist_insert_raw, allocate Node failed.\n");
            return -1;
        }
        x->key = key;
        x->value = value;
        x->forward = (Node **)malloc(sizeof(Node *) * (level + 1));
        for(i = 1; i <= level; i++) {
            x->forward[i] = update[i]->forward[i];
            update[i]->forward[i] = x;
        }
    }
    return 0;
}
Esempio n. 3
0
/**
 * 跳表的插入操作要点
 * 1 找到带插入的位置(在当前元素的前向指针的键与元素的键相等或者大于的适合退出),然后再更新在每个层次的update数组
 * 2 随机生成新节点的level
 * 3 调整指向,插入新节点
 */
void *skiplist_insert(skiplist_t *l,void *item){
	skiplist_node_t *cur=l->head;
	skiplist_node_t **update=l->update;
	int (*comp)(const void *,const void *);
	comp=l->comp;
	int i;
	/*查找键所属的位置*/
	for(i=l->level;i>=0;i--){
		while(cur->forward[i]!=NULL &&comp(cur->forward[i]->item,item)<0)
			cur=cur->forward[i]; //在当前层次遍历直至前向指针为NULL或者对应的前向指针的元素大于或等于item
		update[i]=cur; //更新插入位置的前驱指针
	}
	cur=cur->forward[0];
	if(cur!=NULL&&comp(cur->item,item)==0)
		return cur->item; //键值已存在,直接返回原来的节点

	int level=rand_level(l->prob,l->max_level); //最大的level控制在max_level
	if(level> l->level){ //如果新生成的层数比跳表层数大,更新下标大于i的update数组指向为头结点
		for(i=l->level+1;i<=level;i++){ //持续到当前生成的level上
			update[i]=l->head;
		}
		l->level=level; //更新自己的层级数
	}
	skiplist_node_t *tmp=new_skiplist_node(level,item);
	/**
	 * 调整前向指针的指向,插入新结点
	 * 问题就出现在这里,注意如果生成的level级别较低,只需要在从0..level的级别进行插入,切记不能使用l->level
	 * l->level和level是有不同的,除非level大于当前跳表的level时
	 */
	for(i=0;i<=level;i++){ 
		tmp->forward[i]=update[i]->forward[i];
		update[i]->forward[i]=tmp;
	}
	l->n++;
	return NULL;
}