예제 #1
0
파일: ISTree.cpp 프로젝트: Caesar11/gStore
bool
ISTree::remove(unsigned _key)
{
	//DEBUG
	//if (_key < 0)
	//{
		//printf("error in ISTree-remove: empty string\n");
		//return false;
	//}

	this->request = 0;
	ISNode* ret;
	if (this->root == NULL)	//tree is empty
		return false;

	ISNode* p = this->root;
	ISNode* q;
	int i, j;
	while (!p->isLeaf())
	{
		j = p->getNum();
		//for(i = 0; i < j; ++i)
		//if(bstr < *(p->getKey(i)))
		//break;
		i = p->searchKey_less(_key);

		q = p->getChild(i);
		this->prepare(q);
		if (q->getNum() < ISNode::MIN_CHILD_NUM)	//==MIN_KEY_NUM
		{
			if (i > 0)
				this->prepare(p->getChild(i - 1));
			if (i < j)
				this->prepare(p->getChild(i + 1));
			ret = q->coalesce(p, i);
			if (ret != NULL)
				this->TSM->updateHeap(ret, 0, true);//non-sense node
			this->TSM->updateHeap(q, q->getRank(), true);
			if (q->isLeaf())
			{
				if (q->getPrev() == NULL)
					this->leaves_head = q;
				if (q->getNext() == NULL)
					this->leaves_tail = q;
			}
			if (p->getNum() == 0)		//root shrinks
			{
				//this->leaves_head = q;
				this->root = q;
				this->TSM->updateHeap(p, 0, true);	//instead of delete p				
				this->height--;
			}
		}
		else
			p->setDirty();
		this->TSM->updateHeap(p, p->getRank(), true);
		p = q;
	}
	bool flag = false;
	//j = p->getNum();		//LeafNode(maybe root)
	//for(i = 0; i < j; ++i)
	//	if(bstr == *(p->getKey(i)))
	//	{
	//		request -= p->getKey(i)->getLen();
	//		request -= p->getValue(i)->getLen();
	//		p->subKey(i, true);		//to release
	//		p->subValue(i, true);	//to release
	//		p->subNum();
	//		if(p->getNum() == 0)	//root leaf 0 key
	//		{
	//			this->root = NULL;
	//			this->leaves_head = NULL;
	//			this->leaves_tail = NULL;
	//			this->height = 0;
	//			this->TSM->updateHeap(p, 0, true);	//instead of delete p
	//		}
	//		p->setDirty();
	//		flag = true;
	//		break;
	//	}
	i = p->searchKey_equal(_key);
	//WARN+NOTICE:here must check, because the key to remove maybe not exist
	if (i != (int)p->getNum())
	{
		request -= p->getValue(i)->getLen();
		p->subKey(i);		//to release
		p->subValue(i, true);	//to release
		p->subNum();
		if (p->getNum() == 0)	//root leaf 0 key
		{
			this->root = NULL;
			this->leaves_head = NULL;
			this->leaves_tail = NULL;
			this->height = 0;
			this->TSM->updateHeap(p, 0, true);	//instead of delete p
		}
		p->setDirty();
		flag = true;
	}

	this->TSM->request(request);
	return flag;		//i == j, not found		
}
예제 #2
0
파일: ISTree.cpp 프로젝트: Caesar11/gStore
bool
ISTree::insert(unsigned _key, char* _str, unsigned _len)
{
	//if (_key < 0)
	//{
		//printf("error in ISTree-insert: empty string\n");
		//return false;
	//}

	//this->CopyToTransfer(_str, _len, 2);
	//const Bstr* val = &(this->transfer[2]);
	this->request = 0;
	ISNode* ret;
	if (this->root == NULL)	//tree is empty
	{
		leaves_tail = leaves_head = root = new ISLeafNode;
		request += ISNode::LEAF_SIZE;
		this->height = 1;
		root->setHeight(1);	//add to heap later
	}

	//this->prepare(this->root); //root must be in-mem
	if (root->getNum() == ISNode::MAX_KEY_NUM)
	{
		ISNode* father = new ISIntlNode;
		request += ISNode::INTL_SIZE;
		father->addChild(root, 0);
		ret = root->split(father, 0);
		if (ret->isLeaf() && ret->getNext() == NULL)
			this->leaves_tail = ret;
		if (ret->isLeaf())
			request += ISNode::LEAF_SIZE;
		else
			request += ISNode::INTL_SIZE;
		this->height++;		//height rises only when root splits
							//WARN: height area in Node: 4 bit!
		father->setHeight(this->height);	//add to heap later
		this->TSM->updateHeap(ret, ret->getRank(), false);
		this->root = father;
	}

	ISNode* p = this->root;
	ISNode* q;
	int i;
	while (!p->isLeaf())
	{
		//j = p->getNum();
		//for(i = 0; i < j; ++i)
		//if(bstr < *(p->getKey(i)))
		//break;
		//NOTICE: using binary search is better here
		i = p->searchKey_less(_key);

		q = p->getChild(i);
		this->prepare(q);
		if (q->getNum() == ISNode::MAX_KEY_NUM)
		{
			ret = q->split(p, i);
			if (ret->isLeaf() && ret->getNext() == NULL)
				this->leaves_tail = ret;
			if (ret->isLeaf())
				request += ISNode::LEAF_SIZE;
			else
				request += ISNode::INTL_SIZE;
			//BETTER: in loop may update multiple times
			this->TSM->updateHeap(ret, ret->getRank(), false);
			this->TSM->updateHeap(q, q->getRank(), true);
			this->TSM->updateHeap(p, p->getRank(), true);
			if (_key < p->getKey(i))
				p = q;
			else
				p = ret;
		}
		else
		{
			p->setDirty();
			this->TSM->updateHeap(p, p->getRank(), true);
			p = q;
		}
	}
	//j = p->getNum();
	//for(i = 0; i < j; ++i)
	//if(bstr < *(p->getKey(i)))
	//break;
	i = p->searchKey_less(_key);

	//insert existing key is ok, but not inserted in
	//however, the tree-shape may change due to possible split in former code
	bool ifexist = false;
	if (i > 0 && _key == p->getKey(i - 1))
		ifexist = true;
	else
	{
		p->addKey(_key, i);
		p->addValue(_str, _len, i, true);
		p->addNum();
		request += _len;
		p->setDirty();
		this->TSM->updateHeap(p, p->getRank(), true);
		//_key->clear();
		//_value->clear();
	}
	this->TSM->request(request);
	//if(_key == 0) 
	//{
		//cout<<"the 0th element is: "<<_str[0]<<endl;
	//}
	return !ifexist;		//QUERY(which case:return false)
}