147 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			147 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | #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
 | ||
|  | 
 |