Exemple #1
0
bool
ISTree::modify(int _key, const char* _str, unsigned _len)
{
	if (_key < 0)
	{
		printf("error in ISTree-modify: empty string\n");
		return false;
	}

	this->CopyToTransfer(_str, _len, 2);	//not check value
	const Bstr* val = &(this->transfer[2]);
	this->request = 0;
	int store;
	ISNode* ret = this->find(_key, &store, true);
	if (ret == NULL || store == -1 || _key != ret->getKey(store))	//tree is empty or not found
	{
		cerr<<"tree is empty or not found"<<endl;
		return false;
	}
	//cout<<"ISTree::modify() - key is found, now to remove"<<endl;
	unsigned len = ret->getValue(store)->getLen();
	ret->setValue(val, store, true);
	//cout<<"value reset"<<endl;
	//cout<<"newlen: "<<val->getLen()<<" oldlen: "<<len<<endl;
	//request += (val->getLen() - len);
	this->request = val->getLen();
	this->request -= len;
	ret->setDirty();
	//cout<<"to request"<<endl;
	this->TSM->request(request);
	//cout<<"memory requested"<<endl;
	return true;
}
Exemple #2
0
bool
ISHeap::remove()
{
	if (this->length == 0)
	{
		print("error in remove: remove from empty heap!");
		return false;
	}
	//Node* tp = this->heap[0];
	this->length--;
	this->heap[0]->heapId = -1;
	if (this->length == 0)
		return true;
	ISNode* xp = this->heap[this->length];
	unsigned i = 0, j = 1;
	while (j < this->length)
	{
		if (j < this->length - 1 && this->heap[j]->getRank() > this->heap[j + 1]->getRank())
			j++;
		if (xp->getRank() <= this->heap[j]->getRank())
			break;
		this->heap[i] = this->heap[j];
		this->heap[i]->heapId = i;
		i = j;
		j = 2 * i + 1;
	}
	this->heap[i] = xp;
	this->heap[i]->heapId = i;
	return true;
}
Exemple #3
0
//this function is useful for search and modify, and range-query 
ISNode*		//return the first key's position that >= *_key
ISTree::find(int _key, int* _store, bool ifmodify)
{											//to assign value for this->bstr, function shouldn't be const!
	if (this->root == NULL)
		return NULL;						//ISTree Is Empty
	ISNode* p = root;
	int i, j;
	while (!p->isLeaf())
	{
		if (ifmodify)
			p->setDirty();
		//j = p->getNum();
		//for(i = 0; i < j; ++i)				//BETTER(Binary-Search)
		//if(bstr < *(p->getKey(i)))
		//break;
		i = p->searchKey_less(_key);

		p = p->getChild(i);
		this->prepare(p);
	}

	j = p->getNum();
	//for(i = 0; i < j; ++i)
	//if(bstr <= *(p->getKey(i)))
	//break;
	i = p->searchKey_lessEqual(_key);

	if (i == j)
		*_store = -1;	//Not Found
	else
		*_store = i;
	return p;
}
Exemple #4
0
bool
ISTree::search(unsigned _key, char*& _str, unsigned& _len)
{
	//DEBUG
	//if (_key < 0)
	//{
		//printf("error in ISTree-search: empty string\n");
		//return false;
	//}

	this->request = 0;
	int store;
	ISNode* ret = this->find(_key, &store, false);
	//cout<<"to find the position: "<<store<<endl;
	if (ret == NULL || store == -1 || _key != ret->getKey(store))	//tree is empty or not found
	{
		return false;
	}

	const Bstr* val = ret->getValue(store);
	//this->CopyToTransfer(val->getStr(), val->getLen(), 0);		//not sum to request
	//_str = this->transfer[0].getStr();
	//_len = this->transfer[0].getLen();
	_str = val->getStr();
	_len = val->getLen();

	char* debug = new char[_len];
	memcpy(debug, _str, _len);
//	debug[_len] = '\0';
	_str = debug;

	//if(_key==62)
	//{
		//cout<<"check in search: "<<string(_str, _len)<<endl;
	//}
	this->TSM->request(request);
	//if(_key==62)
	//{
		//cout<<"check in search: "<<string(_str, _len)<<endl;
	//}
	return true;
}
Exemple #5
0
bool
ISTree::search(int _key, char*& _str, int& _len)
{
	if (_key < 0)
	{
		//printf("error in ISTree-search: empty string\n");
		return false;
	}

	this->request = 0;
	int store;
	ISNode* ret = this->find(_key, &store, false);
	if (ret == NULL || store == -1 || _key != ret->getKey(store))	//tree is empty or not found
	{
		return false;
	}

	const Bstr* val = ret->getValue(store);
	this->CopyToTransfer(val->getStr(), val->getLen(), 0);		//not sum to request
	_str = this->transfer[0].getStr();
	_len = this->transfer[0].getLen();
	this->TSM->request(request);
	return true;
}
Exemple #6
0
void
ISTree::print(string s)
{
#ifdef DEBUG_KVSTORE
	fputs(Util::showtime().c_str(), Util::debug_kvstore);
	fputs("Class ISTree\n", Util::debug_kvstore);
	fputs("Message: ", Util::debug_kvstore);
	fputs(s.c_str(), Util::debug_kvstore);
	fputs("\n", Util::debug_kvstore);
	fprintf(Util::debug_kvstore, "Height: %d\n", this->height);
	if (s == "tree" || s == "TREE")
	{
		if (this->root == NULL)
		{
			fputs("Null ISTree\n", Util::debug_kvstore);
			return;
		}
		ISNode** ns = new ISNode*[this->height];
		int* ni = new int[this->height];
		ISNode* np;
		int i, pos = 0;
		ns[pos] = this->root;
		ni[pos] = this->root->getNum();
		pos++;
		while (pos > 0)
		{
			np = ns[pos - 1];
			i = ni[pos - 1];
			this->prepare(np);
			if (np->isLeaf() || i < 0)	//LeafNode or ready IntlNode
			{							//child-num ranges: 0~num
				if (s == "tree")
					np->print("node");
				else
					np->print("NODE");	//print full node-information
				pos--;
				continue;
			}
			else
			{
				ns[pos] = np->getChild(i);
				ni[pos - 1]--;
				ni[pos] = ns[pos]->getNum();
				pos++;
			}
		}
		delete[] ns;
		delete[] ni;
	}
	else if (s == "LEAVES" || s == "leaves")
	{
		ISNode* np;
		for (np = this->leaves_head; np != NULL; np = np->getNext())
		{
			this->prepare(np);
			if (s == "leaves")
				np->print("node");
			else
				np->print("NODE");
		}
	}
	else if (s == "check tree")
	{
		//check the tree, if satisfy B+ definition
		//TODO	
	}
	else;
#endif
}
Exemple #7
0
bool	//special case: not exist, one-edge-case
ISTree::range_query(int _key1, int _key2)
{		//the range is: *_key1 <= x < *_key2 	
		//if(_key1 <0 && _key2 <0)
		//return false;
		//ok to search one-edge, requiring only one be negative
		//find and write value
	int store1, store2;
	ISNode *p1, *p2;
	if (_key1 >= 0)
	{
		request = 0;
		p1 = this->find(_key1, &store1, false);
		if (p1 == NULL || store1 == -1)
			return false;	//no element
		this->TSM->request(request);
	}
	else
	{
		p1 = this->leaves_head;
		store1 = 0;
	}
	if (_key2 >= 0)
	{		//QUERY: another strategy is to getnext and compare every time to tell end
		request = 0;
		p2 = this->find(_key2, &store2, false);
		if (p2 == NULL)
			return false;
		else if (store2 == -1)
			store2 = p2->getNum();
		else if (store2 == 0)
		{
			p2 = p2->getPrev();
			if (p2 == NULL)
				return false;		//no element
			store2 = p2->getNum();
		}
		this->TSM->request(request);
	}
	else
	{
		p2 = this->leaves_tail;
		store2 = p2->getNum();
	}

	ISNode* p = p1;
	unsigned i, l, r;
	//get the num of answers first, not need to prepare the node
	unsigned ansNum = 0;
	while (true)
	{
		//request = 0;
		//this->prepare(p);
		if (p == p1)
			l = store1;
		else
			l = 0;
		if (p == p2)
			r = store2;
		else
			r = p->getNum();
		ansNum += (r - l);
		//this->TSM->request(request);
		if (p != p2)
			p = p->getNext();
		else
			break;
	}

	if (this->stream != NULL)
	{
		delete this->stream;
		this->stream = NULL;
	}
	vector<int> keys;
	vector<bool> desc;
	this->stream = new Stream(keys, desc, ansNum, 1, false);

	p = p1;
	while (1)
	{
		request = 0;
		this->prepare(p);
		if (p == p1)
			l = store1;
		else
			l = 0;
		if (p == p2)
			r = store2;
		else
			r = p->getNum();
		for (i = l; i < r; ++i)
		{
			//NOTICE:Bstr* in an array, used as Bstr[]
			this->stream->write(p->getValue(i));
		}
		this->TSM->request(request);
		if (p != p2)
			p = p->getNext();
		else
			break;
	}
	this->stream->setEnd();
	return true;
}
Exemple #8
0
bool
ISTree::remove(int _key)
{
	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		
}
Exemple #9
0
bool
ISTree::insert(int _key, const 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(val, i, true);
		p->addNum();
		request += val->getLen();
		p->setDirty();
		this->TSM->updateHeap(p, p->getRank(), true);
		//_key->clear();
		//_value->clear();
	}
	this->TSM->request(request);
	return !ifexist;		//QUERY(which case:return false)
}