Beispiel #1
0
bool
SITree::search(const char* _str, unsigned _len, int* _val)
{
	if (_str == NULL || _len == 0)
	{
		printf("error in SITree-search: empty string\n");
		*_val = -1;
		return false;
	}
	this->CopyToTransfer(_str, _len, 1);

	request = 0;
	Bstr bstr = this->transfer[1];	//not to modify its memory
	int store;
	SINode* ret = this->find(&transfer[1], &store, false);
	if (ret == NULL || store == -1 || bstr != *(ret->getKey(store)))	//tree is empty or not found
	{
		bstr.clear();
		return false;
	}
	*_val = ret->getValue(store);
	this->TSM->request(request);
	bstr.clear();
	return true;
}
Beispiel #2
0
bool
SITree::modify(const char* _str, unsigned _len, int _val)
{
	if (_str == NULL || _len == 0)
	{
		printf("error in SITree-modify: empty string\n");
		return false;
	}
	this->CopyToTransfer(_str, _len, 1);

	this->request = 0;
	const Bstr* _key = &transfer[1];
	Bstr bstr = *_key;
	int store;
	SINode* ret = this->find(_key, &store, true);
	if (ret == NULL || store == -1 || bstr != *(ret->getKey(store)))	//tree is empty or not found
	{
		bstr.clear();
		return false;
	}
	ret->setValue(_val, store);
	ret->setDirty();
	this->TSM->request(request);
	bstr.clear();
	return true;
}
Beispiel #3
0
//this function is useful for search and modify, and range-query 
SINode*		//return the first key's position that >= *_key
SITree::find(const Bstr* _key, int* _store, bool ifmodify)
{											//to assign value for this->bstr, function shouldn't be const!
	if (this->root == NULL)
		return NULL;						//SITree Is Empty
	SINode* p = root;
	int i, j;
	Bstr bstr = *_key;					//local Bstr: multiple delete
	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(bstr);

		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(bstr);

	if (i == j)
		*_store = -1;	//Not Found
	else
		*_store = i;
	bstr.clear();
	return p;
}
Beispiel #4
0
bool
Tree::search(const Bstr* _key, const Bstr*& _value)
{
    request = 0;
    Bstr bstr = *_key;	//not to modify its memory
    int store;
    Node* ret = this->find(_key, &store, false);
    if(ret == NULL || store == -1 || bstr != *(ret->getKey(store)))	//tree is empty or not found
    {
        bstr.clear();
        return false;
    }
    const Bstr* val = ret->getValue(store);
    this->CopyToTransfer(val->getStr(), val->getLen(), 0);		//not sum to request
    _value = &transfer[0];
    this->TSM->request(request);
    bstr.clear();
    return true;
}
Beispiel #5
0
bool
Tree::modify(const Bstr* _key, const Bstr* _value)
{
    request = 0;
    Bstr bstr = *_key;
    int store;
    Node* ret = this->find(_key, &store, true);
    if(ret == NULL || store == -1 || bstr != *(ret->getKey(store)))	//tree is empty or not found
    {
        bstr.clear();
        return false;
    }
    unsigned len = ret->getValue(store)->getLen();
    ret->setValue(_value, store, true);
    request += (_value->getLen()-len);
    //_value->clear();
    ret->setDirty();
    this->TSM->request(request);
    bstr.clear();
    return true;
}
Beispiel #6
0
bool
SITree::remove(const char* _str, unsigned _len)
{
	if (_str == NULL || _len == 0)
	{
		printf("error in SITree-remove: empty string\n");
		return false;
	}
	this->CopyToTransfer(_str, _len, 1);

	request = 0;
	const Bstr* _key = &transfer[1];
	SINode* ret;
	if (this->root == NULL)	//tree is empty
		return false;
	SINode* p = this->root;
	SINode* q;
	int i, j;
	Bstr bstr = *_key;
	while (!p->isLeaf())
	{
		j = p->getNum();
		//for(i = 0; i < j; ++i)
		//if(bstr < *(p->getKey(i)))
		//break;
		i = p->searchKey_less(bstr);

		q = p->getChild(i);
		this->prepare(q);
		if (q->getNum() < SINode::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;
	i = p->searchKey_equal(bstr);
	//WARN+NOTICE:here must check, because the key to remove maybe not exist
	if (i != (int)p->getNum())
	{
		request -= p->getKey(i)->getLen();
		p->subKey(i, true);		//to release
		p->subValue(i);	//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);
	bstr.clear();
	return flag;		//i == j, not found		
}
Beispiel #7
0
bool
SITree::insert(const char* _str, unsigned _len, int _val)
{
	if (_str == NULL || _len == 0)
	{
		printf("error in SITree-insert: empty string\n");
		return false;
	}
	this->CopyToTransfer(_str, _len, 1);

	this->request = 0;
	SINode* ret;
	if (this->root == NULL)	//tree is empty
	{
		leaves_tail = leaves_head = root = new SILeafNode;
		request += SINode::LEAF_SIZE;
		this->height = 1;
		root->setHeight(1);	//add to heap later
	}

	//this->prepare(this->root); //root must be in-mem
	if (root->getNum() == SINode::MAX_KEY_NUM)
	{
		SINode* father = new SIIntlNode;
		request += SINode::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 += SINode::LEAF_SIZE;
		else
			request += SINode::INTL_SIZE;
		this->height++;		//height rises only when root splits
		//WARN: height area in SINode: 4 bit!
		father->setHeight(this->height);	//add to heap later
		this->TSM->updateHeap(ret, ret->getRank(), false);
		this->root = father;
	}

	SINode* p = this->root;
	SINode* q;
	int i;
	const Bstr* _key = &transfer[1];
	Bstr bstr = *_key;
	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(bstr);

		q = p->getChild(i);
		this->prepare(q);
		if (q->getNum() == SINode::MAX_KEY_NUM)
		{
			ret = q->split(p, i);
			if (ret->isLeaf() && ret->getNext() == NULL)
				this->leaves_tail = ret;
			if (ret->isLeaf())
				request += SINode::LEAF_SIZE;
			else
				request += SINode::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 (bstr < *(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(bstr);

	//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 && bstr == *(p->getKey(i - 1)))
		ifexist = true;
	else
	{
		p->addKey(_key, i, true);
		p->addValue(_val, i);
		p->addNum();
		request += _key->getLen();
		p->setDirty();
		this->TSM->updateHeap(p, p->getRank(), true);
	}
	this->TSM->request(request);
	bstr.clear();		//NOTICE: must be cleared!
	return !ifexist;		//QUERY(which case:return false)
}
Beispiel #8
0
bool	//BETTER: if not found, the road are also dirty! find first?
Tree::remove(const Bstr* _key)
{
    request = 0;
    Node* ret;
    if(this->root == NULL)	//tree is empty
        return false;
    Node* p = this->root;
    Node* q;
    int i, j;
    Bstr bstr = *_key;
    while(!p->isLeaf())
    {
        j = p->getNum();
        for(i = 0; i < j; ++i)
            if(bstr < *(p->getKey(i)))
                break;
        q = p->getChild(i);
        this->prepare(q);
        if(q->getNum() < Node::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;
        }
    this->TSM->request(request);
    bstr.clear();
    return flag;		//i == j, not found
}
Beispiel #9
0
bool
Tree::insert(const Bstr* _key, const Bstr* _value)
{
    request = 0;
    Node* ret;
    if(this->root == NULL)	//tree is empty
    {
        leaves_tail = leaves_head = root = new LeafNode;
        request += Node::LEAF_SIZE;
        this->height = 1;
        root->setHeight(1);	//add to heap later
    }
    //this->prepare(this->root); //root must be in-mem
    if(root->getNum() == Node::MAX_KEY_NUM)
    {
        Node* father = new IntlNode;
        request += Node::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 += Node::LEAF_SIZE;
        else
            request += Node::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;
    }
    Node* p = this->root;
    Node* q;
    int i, j;
    Bstr bstr = *_key;
    while(!p->isLeaf())
    {
        j = p->getNum();
        for(i = 0; i < j; ++i)
            if(bstr < *(p->getKey(i)))
                break;
        q = p->getChild(i);
        this->prepare(q);
        if(q->getNum() == Node::MAX_KEY_NUM)
        {
            ret = q->split(p, i);
            if(ret->isLeaf() && ret->getNext() == NULL)
                this->leaves_tail = ret;
            if(ret->isLeaf())
                request += Node::LEAF_SIZE;
            else
                request += Node::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(bstr < *(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;
    //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 && bstr == *(p->getKey(i-1)))
        ifexist = true;
    else
    {
        p->addKey(_key, i, true);
        p->addValue(_value, i, true);
        p->addNum();
        request += (_key->getLen() + _value->getLen());
        p->setDirty();
        this->TSM->updateHeap(p, p->getRank(), true);
        //_key->clear();
        //_value->clear();
    }
    this->TSM->request(request);
    bstr.clear();		//NOTICE: must be cleared!
    return !ifexist;		//QUERY(which case:return false)
}