406 lines
6.4 KiB
C++
406 lines
6.4 KiB
C++
/*=============================================================================
|
|
# Filename: SINode.cpp
|
|
# Author: syzz
|
|
# Mail: 1181955272@qq.com
|
|
# Last Modified: 2015-04-26 16:39
|
|
# Description: achieve functions in SINode.h
|
|
=============================================================================*/
|
|
|
|
#include "SINode.h"
|
|
|
|
using namespace std;
|
|
|
|
void
|
|
SINode::AllocKeys()
|
|
{
|
|
keys = new Bstr[MAX_KEY_NUM];
|
|
}
|
|
|
|
/*
|
|
void
|
|
SINode::FreeKeys()
|
|
{
|
|
delete[] keys;
|
|
}
|
|
*/
|
|
|
|
SINode::SINode()
|
|
{
|
|
store = flag = 0;
|
|
flag |= NF_IM;
|
|
AllocKeys();
|
|
}
|
|
|
|
SINode::SINode(bool isVirtual)
|
|
{
|
|
store = flag = 0;
|
|
if (!isVirtual)
|
|
{
|
|
flag |= NF_IM;
|
|
AllocKeys();
|
|
}
|
|
}
|
|
|
|
/*
|
|
SINode::Node(Storage* TSM)
|
|
{
|
|
AllocKeys();
|
|
TSM->readSINode(this, Storage::OVER);
|
|
}
|
|
*/
|
|
bool
|
|
SINode::isLeaf() const
|
|
{
|
|
return this->flag & NF_IL;
|
|
}
|
|
|
|
bool
|
|
SINode::isDirty() const
|
|
{
|
|
return this->flag & NF_ID;
|
|
}
|
|
|
|
void
|
|
SINode::setDirty()
|
|
{
|
|
this->flag |= NF_ID;
|
|
}
|
|
|
|
void
|
|
SINode::delDirty()
|
|
{
|
|
this->flag &= ~NF_ID;
|
|
}
|
|
|
|
bool
|
|
SINode::inMem() const
|
|
{
|
|
return this->flag & NF_IM;
|
|
}
|
|
|
|
void
|
|
SINode::setMem()
|
|
{
|
|
this->flag |= NF_IM;
|
|
}
|
|
|
|
void
|
|
SINode::delMem()
|
|
{
|
|
this->flag &= ~NF_IM;
|
|
}
|
|
|
|
/*
|
|
bool
|
|
SINode::isVirtual() const
|
|
{
|
|
return this->flag & NF_IV;
|
|
}
|
|
|
|
void
|
|
SINode::setVirtual()
|
|
{
|
|
this->flag |= NF_IV;
|
|
}
|
|
|
|
void
|
|
SINode::delVirtual()
|
|
{
|
|
this->flag &= ~NF_IV;
|
|
}
|
|
*/
|
|
|
|
unsigned
|
|
SINode::getRank() const
|
|
{
|
|
return this->flag & NF_RK;
|
|
}
|
|
|
|
void
|
|
SINode::setRank(unsigned _rank)
|
|
{
|
|
this->flag &= ~NF_RK;
|
|
this->flag |= _rank;
|
|
}
|
|
|
|
unsigned
|
|
SINode::getHeight() const
|
|
{
|
|
return (this->flag & NF_HT) >> 20;
|
|
}
|
|
|
|
void
|
|
SINode::setHeight(unsigned _h)
|
|
{
|
|
this->flag &= ~NF_HT;
|
|
this->flag |= (_h << 20);
|
|
}
|
|
|
|
unsigned
|
|
SINode::getNum() const
|
|
{
|
|
return (this->flag & NF_KN) >> 12;
|
|
}
|
|
|
|
bool
|
|
SINode::setNum(int _num)
|
|
{
|
|
if (_num < 0 || (unsigned)_num > MAX_KEY_NUM)
|
|
{
|
|
print(string("error in setNum: Invalid num ") + Util::int2string(_num));
|
|
return false;
|
|
}
|
|
this->flag &= ~NF_KN;
|
|
this->flag |= (_num << 12);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SINode::addNum()
|
|
{
|
|
if (this->getNum() + 1 > MAX_KEY_NUM)
|
|
{
|
|
print("error in addNum: Invalid!");
|
|
return false;
|
|
}
|
|
this->flag += (1 << 12);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SINode::subNum()
|
|
{
|
|
if (this->getNum() < 1)
|
|
{
|
|
print("error in subNum: Invalid!");
|
|
return false;
|
|
}
|
|
this->flag -= (1 << 12);
|
|
return true;
|
|
}
|
|
|
|
unsigned
|
|
SINode::getStore() const
|
|
{
|
|
return this->store;
|
|
}
|
|
|
|
void
|
|
SINode::setStore(unsigned _store)
|
|
{
|
|
this->store = _store;
|
|
}
|
|
|
|
unsigned
|
|
SINode::getFlag() const
|
|
{
|
|
return flag;
|
|
}
|
|
|
|
void
|
|
SINode::setFlag(unsigned _flag)
|
|
{
|
|
this->flag = _flag;
|
|
}
|
|
|
|
const Bstr*
|
|
SINode::getKey(int _index) const
|
|
{
|
|
int num = this->getNum();
|
|
if (_index < 0 || _index >= num)
|
|
{
|
|
//print(string("error in getKey: Invalid index ") + Util::int2string(_index));
|
|
printf("error in getKey: Invalid index\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return this->keys + _index;
|
|
}
|
|
|
|
bool
|
|
SINode::setKey(const Bstr* _key, int _index, bool ifcopy)
|
|
{
|
|
int num = this->getNum();
|
|
if (_index < 0 || _index >= num)
|
|
{
|
|
print(string("error in setKey: Invalid index ") + Util::int2string(_index));
|
|
return false;
|
|
}
|
|
if (ifcopy)
|
|
keys[_index].copy(_key);
|
|
else
|
|
keys[_index] = *_key;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SINode::addKey(const Bstr* _key, int _index, bool ifcopy)
|
|
{
|
|
int num = this->getNum();
|
|
if (_index < 0 || _index > num)
|
|
{
|
|
print(string("error in addKey: Invalid index ") + Util::int2string(_index));
|
|
return false;
|
|
}
|
|
int i;
|
|
//NOTICE: if num == MAX_KEY_NUM, will visit keys[MAX_KEY_NUM], not legal!!!
|
|
//however. tree operations ensure that: when node is full, not add but split first!
|
|
for (i = num - 1; i >= _index; --i)
|
|
keys[i + 1] = keys[i];
|
|
if (ifcopy)
|
|
keys[_index].copy(_key);
|
|
else
|
|
keys[_index] = *_key;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SINode::addKey(char* _str, unsigned _len, int _index, bool ifcopy)
|
|
{
|
|
int num = this->getNum();
|
|
if (_index < 0 || _index > num)
|
|
{
|
|
print(string("error in addKey: Invalid index ") + Util::int2string(_index));
|
|
return false;
|
|
}
|
|
int i;
|
|
//NOTICE: if num == MAX_KEY_NUM, will visit keys[MAX_KEY_NUM], not legal!!!
|
|
//however. tree operations ensure that: when node is full, not add but split first!
|
|
for (i = num - 1; i >= _index; --i)
|
|
keys[i + 1] = keys[i];
|
|
|
|
keys[_index].setStr(_str);
|
|
keys[_index].setLen(_len);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SINode::subKey(int _index, bool ifdel)
|
|
{
|
|
int num = this->getNum();
|
|
if (_index < 0 || _index >= num)
|
|
{
|
|
print(string("error in subKey: Invalid index ") + Util::int2string(_index));
|
|
return false;
|
|
}
|
|
int i;
|
|
if (ifdel)
|
|
keys[_index].release();
|
|
for (i = _index; i < num - 1; ++i)
|
|
keys[i] = keys[i + 1];
|
|
|
|
return true;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_less(const Bstr& _bstr) const
|
|
{
|
|
int num = this->getNum();
|
|
//for(i = 0; i < num; ++i)
|
|
//if(bstr < *(p->getKey(i)))
|
|
//break;
|
|
|
|
int low = 0, high = num - 1, mid = -1;
|
|
while (low <= high)
|
|
{
|
|
mid = (low + high) / 2;
|
|
if (this->keys[mid] > _bstr)
|
|
{
|
|
if (low == mid)
|
|
break;
|
|
high = mid;
|
|
}
|
|
else
|
|
{
|
|
low = mid + 1;
|
|
}
|
|
}
|
|
|
|
return low;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_equal(const Bstr& _bstr) const
|
|
{
|
|
int num = this->getNum();
|
|
//for(i = 0; i < num; ++i)
|
|
// if(bstr == *(p->getKey(i)))
|
|
// {
|
|
|
|
int ret = this->searchKey_less(_bstr);
|
|
if (ret > 0 && this->keys[ret - 1] == _bstr)
|
|
return ret - 1;
|
|
else
|
|
return num;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_lessEqual(const Bstr& _bstr) const
|
|
{
|
|
//int num = this->getNum();
|
|
//for(i = 0; i < num; ++i)
|
|
//if(bstr <= *(p->getKey(i)))
|
|
//break;
|
|
|
|
int ret = this->searchKey_less(_bstr);
|
|
if (ret > 0 && this->keys[ret - 1] == _bstr)
|
|
return ret - 1;
|
|
else
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_less(const char* _str, unsigned _len) const
|
|
{
|
|
int num = this->getNum();
|
|
|
|
int low = 0, high = num - 1, mid = -1;
|
|
while (low <= high)
|
|
{
|
|
mid = (low + high) / 2;
|
|
//if (this->keys[mid] > _bstr)
|
|
if (Util::compare(this->keys[mid].getStr(), this->keys[mid].getLen(), _str, _len) > 0)
|
|
{
|
|
if (low == mid)
|
|
break;
|
|
high = mid;
|
|
}
|
|
else
|
|
{
|
|
low = mid + 1;
|
|
}
|
|
}
|
|
|
|
return low;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_equal(const char* _str, unsigned _len) const
|
|
{
|
|
int num = this->getNum();
|
|
//for(i = 0; i < num; ++i)
|
|
// if(bstr == *(p->getKey(i)))
|
|
// {
|
|
|
|
int ret = this->searchKey_less(_str, _len);
|
|
//if (ret > 0 && this->keys[ret - 1] == _bstr)
|
|
if (ret > 0 && Util::compare(this->keys[ret-1].getStr(), this->keys[ret-1].getLen(), _str, _len) == 0)
|
|
return ret - 1;
|
|
else
|
|
return num;
|
|
}
|
|
|
|
int
|
|
SINode::searchKey_lessEqual(const char* _str, unsigned _len) const
|
|
{
|
|
int ret = this->searchKey_less(_str, _len);
|
|
//if (ret > 0 && this->keys[ret - 1] == _bstr)
|
|
if (ret > 0 && Util::compare(this->keys[ret-1].getStr(), this->keys[ret-1].getLen(), _str, _len) == 0)
|
|
return ret - 1;
|
|
else
|
|
return ret;
|
|
}
|
|
|