147 lines
3.1 KiB
C++
Executable File
147 lines
3.1 KiB
C++
Executable File
#ifndef CSSTREE_H
|
|
#define CSSTREE_H
|
|
|
|
#include <iostream>
|
|
#include <math.h>
|
|
using namespace std;
|
|
|
|
#define divRoundUp(n,s) (((n) / (s)) + ((((n) % (s)) > 0) ? 1 : 0))
|
|
#define CSS_TREE_FANOUT 33
|
|
//we use implicit pointer to perform the addressing.
|
|
|
|
typedef int Record;
|
|
|
|
class CC_GenericTree
|
|
{
|
|
public:
|
|
int numRecord;
|
|
Record *data;
|
|
//we use the BFS layout as the default layout.
|
|
int numNode;
|
|
int level;
|
|
int gResult;
|
|
CC_GenericTree(){}
|
|
//we assume that numR=2^i. Otherwise, we pad the array with -1 from the beginning.
|
|
//we also assume that the record are sorted by the key.
|
|
CC_GenericTree(Record *d, int numR)
|
|
{
|
|
data=d;
|
|
numRecord=numR;
|
|
}
|
|
virtual ~CC_GenericTree()
|
|
{
|
|
}
|
|
virtual int search(int key)=0;
|
|
|
|
};
|
|
|
|
class CC_CSSTree:public CC_GenericTree
|
|
{
|
|
public:
|
|
int *ntree;
|
|
int fanout;
|
|
int blockSize;
|
|
int *vStart;
|
|
int *vG;//vG[0] is used in computing the position for level 1.
|
|
int numKey;
|
|
CC_CSSTree(Record *d, int numR, int f):CC_GenericTree(d,numR)
|
|
{
|
|
fanout=f;
|
|
blockSize=fanout-1;
|
|
int numLeaf=divRoundUp(numR,blockSize);
|
|
level=1;
|
|
int temp=numLeaf;
|
|
while(temp>1)
|
|
{
|
|
temp=divRoundUp(temp, fanout);
|
|
level++;
|
|
}
|
|
numNode=(int)((pow((double)fanout,(double)level)-1)/(fanout-1));
|
|
numKey=numNode*blockSize;
|
|
ntree=new int[numKey];
|
|
vStart=new int[level];
|
|
vG=new int[level];
|
|
#ifdef DEBUG
|
|
cout<<numLeaf<<","<<level<<", "<<numNode<<endl;
|
|
#endif
|
|
//layout the tree from bottom up.
|
|
int i=0,j=0,k=0;
|
|
int startNode=0;
|
|
int endNode=0;
|
|
int startKey, endKey;
|
|
int curIndex;
|
|
for(i=0;i<numNode;i++)
|
|
ntree[i]=-1;
|
|
//for <level-1>, i.e., the leaf level. [start,end]
|
|
for(i=0;i<level;i++)//level
|
|
{
|
|
startNode=(int)((pow((double)fanout,(double)i)-1)/(fanout-1));
|
|
endNode=(int)((pow((double)fanout,(double)(i+1))-1)/(fanout-1));
|
|
for(j= startNode;j< endNode;j++)//which node
|
|
{
|
|
startKey=j*blockSize;
|
|
endKey=startKey+blockSize;
|
|
for(k=startKey;k<endKey;k++)
|
|
{
|
|
curIndex=(int)(blockSize*pow((double)fanout,(double)(level-i-1))*(k+1-startNode*blockSize+(j-startNode))-1);
|
|
if(curIndex<numRecord+blockSize)
|
|
{
|
|
if(curIndex>=numRecord)
|
|
curIndex=numRecord-1;
|
|
ntree[k]=data[curIndex];
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
~CC_CSSTree()
|
|
{
|
|
delete [] ntree;
|
|
delete [] vStart;
|
|
delete [] vG;
|
|
}
|
|
virtual int search(int key);
|
|
void print()
|
|
{
|
|
int i=0, j=0;
|
|
int k=0;
|
|
int startNode=0;
|
|
int endNode=0;
|
|
int startKey, endKey;
|
|
for(i=0;i<level;i++)//level
|
|
{
|
|
cout<<"Level, "<<i<<endl;
|
|
startNode=(int)((pow((double)fanout,(double)i)-1)/(fanout-1));
|
|
endNode=(int)((pow((double)fanout,(double)(i+1))-1)/(fanout-1));
|
|
for(j= startNode;j< endNode;j++)//which node
|
|
{
|
|
cout<<"Level, "<<i<<", Node, "<<j<<": ";
|
|
startKey=j*blockSize;
|
|
endKey=startKey+blockSize;
|
|
for(k=startKey;k<endKey;k++)
|
|
{
|
|
cout<<ntree[k]<<", ";
|
|
}
|
|
cout<<endl;
|
|
}
|
|
}
|
|
for(i=0;i<numRecord;i++)
|
|
{
|
|
cout<<data[i]<<", ";
|
|
if(i%(fanout-1)==(fanout-2))
|
|
cout<<"*"<<endl;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|