Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修改insert_element 更新连接🔗时,陷入死循环 #27

Open
ahclfz opened this issue Dec 19, 2024 · 1 comment
Open

修改insert_element 更新连接🔗时,陷入死循环 #27

ahclfz opened this issue Dec 19, 2024 · 1 comment

Comments

@ahclfz
Copy link

ahclfz commented Dec 19, 2024

template<typename K, typename V>
int SkipList<K, V>::insert_element(K key, V value) { //为0,插入成功
mtx.lock();
Node<K, V>* cur = this->_header;
Node<K, V>* update[_max_level + 1];
//update 的类型是 Node<K, V>[](指针数组),而 update[i] 的类型是 Node<K, V>(指向一个 Node 对象的指针)
memset(update, 0, sizeof(Node<K, V>*) * (_max_level + 1));

for (int i = _skip_list_level; i >= 0; i--) {
	while (cur->forward[i] != nullptr && cur->forward[i]->get_key() < key) {
		cur = cur->forward[i];
	}
	update[i] = cur;
	//每一层都将插入位置的前驱节点保存到 update[i]
}
cur = cur->forward[0]; //当前cur为待插入位置的下一个节点

if (cur != nullptr && cur->get_key() == key) {
	std::cout << "key:" << key << ", exists" << std::endl;
	mtx.unlock();
	return 1;
}

if (cur == nullptr || cur->get_key() != key) {
	int random_level = get_random_level();
	int tmp = _skip_list_level;
	
	if (random_level > _skip_list_level) {
		for (int i = _skip_list_level + 1; i < random_level + 1; i++) {
			update[i] = _header;
		}

// tmp = _skip_list_level;
_skip_list_level = random_level;
}

	Node<K, V>* inserted_node = create_node(key, value, random_level);

// for (int i = 0; i <= random_level; i++) {
// inserted_node->forward[i] = update[i]->forward[i];
// update[i]->forward[i] = inserted_node; //更新_header对应Node内部的forward指针数组
// }

	//上述循环可针对更新前的_skip_list_level和random_level进行区分
	//对于原_skip_list_level+1到random_level之间的值只进行update[i]->forward[i] = inserted_node
	
	for (int i = 0; i <= tmp; i++) {
		inserted_node->forward[i] = update[i]->forward[i];
		update[i]->forward[i] = inserted_node;  //更新_header对应Node内部的forward指针数组
	}
	
	for (int i = tmp + 1; i <= random_level; i++) {
		update[i]->forward[i] = inserted_node;
	}

// _skip_list_level = random_level; //不能写在这里!!-2024-12-19下午
std::cout << "Successfully inserted key:" << key << ", value:" << value << std::endl;
_element_count++;
}
mtx.unlock();
return 0; //插入成功🏅
}

//使用tmp获取当前原最大层,然后更新新节点 链接关系时,针对原来最大层一下以及原最大层+1到random(更高层)使用不同的for循环,我认为update[i]->forward[i]在当前层大于原最大层时候一定为nullptr,新节点inserted_node->forward[i] 也一样,所以无需更新

//当就是会陷入死循环!!

@ahclfz
Copy link
Author

ahclfz commented Dec 21, 2024

template<typename K, typename V>
int SkipList<K, V>::insert_element(K key, V value) { //为0,插入成功
	mtx.lock();
	Node<K, V>* cur = this->_header;
	Node<K, V>* update[_max_level + 1];
	//update 的类型是 Node<K, V>*[](指针数组),而 update[i] 的类型是 Node<K, V>*(指向一个 Node 对象的指针)
	memset(update, 0, sizeof(Node<K, V>*) * (_max_level + 1));
	
	for (int i = _skip_list_level; i >= 0; i--) {
		while (cur->forward[i] != nullptr && cur->forward[i]->get_key() < key) {
			cur = cur->forward[i];
		}
		update[i] = cur;
		//每一层都将插入位置的前驱节点保存到 update[i]
	}
	cur = cur->forward[0]; //当前cur为待插入位置的下一个节点
	
	if (cur != nullptr && cur->get_key() == key) {
		std::cout << "key:" << key << ", exists" << std::endl;
		mtx.unlock();
		return 1;
	}
	
	if (cur == nullptr || cur->get_key() != key) {
		int random_level = get_random_level();
//		int tmp = _skip_list_level;
		
		if (random_level > _skip_list_level) {
			for (int i = _skip_list_level + 1; i < random_level + 1; i++) {
				update[i] = _header;
			}
//			tmp = _skip_list_level;
			_skip_list_level = random_level;
		}
		
		Node<K, V>* inserted_node = create_node(key, value, random_level);
		
		for (int i = 0; i <= random_level; i++) {
			inserted_node->forward[i] = update[i]->forward[i];
			update[i]->forward[i] = inserted_node;  //更新_header对应Node内部的forward指针数组
		}
		
		//上述循环可针对更新前的_skip_list_level和random_level进行区分
		//对于原_skip_list_level+1到random_level之间的值只进行update[i]->forward[i] = inserted_node
		
//		for (int i = 0; i <= tmp; i++) {
//			inserted_node->forward[i] = update[i]->forward[i];
//			update[i]->forward[i] = inserted_node;  //更新_header对应Node内部的forward指针数组
//		}
//		
//		for (int i = tmp + 1; i <= random_level; i++) {
//			update[i]->forward[i] = inserted_node;
//		}
		
//		_skip_list_level = random_level;  //不能写在这里!!-2024-12-19下午
		std::cout << "Successfully inserted key:" << key << ", value:" << value << std::endl;
		_element_count++;
	}
	mtx.unlock();
	return 0;  //插入成功🏅
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant