⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexbtree.cpp

📁 lex语法分析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			assert(m_pNodeArea->root_node_slot==node_slot_ins);
			CreateNewRootNodeWithOneKey(node_slot_ins,fKeyToInsert,new_node_slot);
		}
	}
}
void CLexBTree::CreateNewRootNodeWithOneKey(int ptr_l,CKeyType key,int ptr_r)
{
	SNode* pNode;
	int new_root_node_slot;
	new_root_node_slot = GetSpareNodeSlot();
	// 已做m_pNodeArea->used_node_slot_sum++;
	pNode = &(m_pNodeArea->node_ary[new_root_node_slot]);
	ClearNode(pNode);
	pNode->ptr_o          = ptr_l;
	pNode->key_ary[0]     = key;
	pNode->ptr_ary[0]     = ptr_r;
	pNode->bDirty         = true;
	pNode->bPtToPageNaddr = false;
	pNode->used_key_slot_sum = 1;
	m_pNodeArea->root_node_slot = new_root_node_slot;
}
CKeyType CLexBTree::BirthKey(string strWord)
{
	int i, j,nRadix;
	CKeyType ktRet;
	//高位部分
	for(i=0,j=0;(i<strWord.length()) && (i<KT_BASENUM); i++,j++)
	{
		if('\040' == strWord[i]) { //空格 32
			nRadix = 0;
		}
		else if('\'' == strWord[i]) { // 单引号 39 
			nRadix = 1;
		}
		else if('-' == strWord[i]) { // 连字符 45
			nRadix = 2;
		}
		else if('.' == strWord[i]) { // 点号 46
			nRadix = 3;
		}
		else if(strWord[i]>='a'&&strWord[i]<='z') {
			nRadix = strWord[i] - 'a' + 4;
		}
		else if('{' == strWord[i]) { // 点号 46
			nRadix = 30;
		}
		else if('}' == strWord[i]) { // 点号 46
			nRadix = 31;
		}
		else {
			nRadix = 33; // 其实这个是没有必要的
		}
		ktRet.high = ktRet.high + nRadix * m_ulBase[j];
	}
	// 中高位部分
	for(i=KT_BASENUM,j=0; (i<strWord.length()) && (i<2*KT_BASENUM); i++,j++)
	{
		if('\040' == strWord[i]) { //空格 32
			nRadix = 0;
		}
		else if('\'' == strWord[i]) { // 单引号 39 
			nRadix = 1;
		}
		else if('-' == strWord[i]) { // 连字符 45
			nRadix = 2;
		}
		else if('.' == strWord[i]) { // 点号 46
			nRadix = 3;
		}
		else if(strWord[i]>='a'&&strWord[i]<='z') {
			nRadix = strWord[i] - 'a' + 4;
		}
		else if('{' == strWord[i]) { // 点号 46
			nRadix = 30;
		}
		else if('}' == strWord[i]) { // 点号 46
			nRadix = 31;
		}
		else {
			nRadix = 33; // 其实这个是没有必要的
		}
		ktRet.mid_high = ktRet.mid_high + nRadix * m_ulBase[j];
	}
	// 中低位部分
	for(i=2*KT_BASENUM,j=0; (i<strWord.length()) && (i<3*KT_BASENUM); i++,j++)
	{
		if('\040' == strWord[i]) { //空格 32
			nRadix = 0;
		}
		else if('\'' == strWord[i]) { // 单引号 39 
			nRadix = 1;
		}
		else if('-' == strWord[i]) { // 连字符 45
			nRadix = 2;
		}
		else if('.' == strWord[i]) { // 点号 46
			nRadix = 3;
		}
		else if(strWord[i]>='a'&&strWord[i]<='z') {
			nRadix = strWord[i] - 'a' + 4;
		}
		else if('{' == strWord[i]) { // 点号 46
			nRadix = 30;
		}
		else if('}' == strWord[i]) { // 点号 46
			nRadix = 31;
		}
		else {
			nRadix = 33; // 其实这个是没有必要的
		}
		ktRet.mid_low = ktRet.mid_low + nRadix * m_ulBase[j];
	}
	// 低位部分
	for(i=3*KT_BASENUM,j=0; (i<strWord.length()) && (i<4*KT_BASENUM); i++,j++)
	{
		if('\040' == strWord[i]) { //空格 32
			nRadix = 0;
		}
		else if('\'' == strWord[i]) { // 单引号 39 
			nRadix = 1;
		}
		else if('-' == strWord[i]) { // 连字符 45
			nRadix = 2;
		}
		else if('.' == strWord[i]) { // 点号 46
			nRadix = 3;
		}
		else if(strWord[i]>='a'&&strWord[i]<='z') {
			nRadix = strWord[i] - 'a' + 4;
		}
		else if('{' == strWord[i]) { // 点号 46
			nRadix = 30;
		}
		else if('}' == strWord[i]) { // 点号 46
			nRadix = 31;
		}
		else {
			nRadix = 33; // 其实这个是没有必要的
		}
		ktRet.low = ktRet.low + nRadix * m_ulBase[j];
	}
	if(i<strWord.length()) 
		ktRet.low++;

	return ktRet;
}
int CLexBTree::CeilInt(int divident,int divisor)
{
	int nRet,residue;
	nRet = divident / divisor;
	residue = divident % divisor;
	if(residue != 0)  {
		if(nRet>0)  //当小于零时,此时nRet就是ceil
			nRet ++;
	}
	return nRet;
}
int CLexBTree::CeilInt2(int divident,int divisor)
{
	// 比如 CeiInt2(2,2)=2 ceilint(3,2) = 3;
	int nRet;
	nRet = (int) (divident / divisor) + 1;
	return nRet;

}
void CLexBTree::SubAllPageAccessCount()
{ // 对NRU算法有用 对pageArena 内的pageslot 访问记数减一 
	for(int i=0;i<PAGENUM; i++) {
		if(m_pPageArena->access_ary[i] != -1) // -1 表示这个pageslot是空白
			m_pPageArena->access_ary[i] --;
	}
}

//  若B树没有怎么办? 
//  一开始必然m_pPageArena->total_page =  0;
//            m_pNodeArea->used_node_slot_sum   =  0;
// 	          m_pNodeArea->root_node_slot  = NIL_PTR;
//    建立 第一个 页子 则无须匹配了,直接插入
void CLexBTree::CreateFirstPageFirstNodeWithOnePtr(string strWord,unsigned int nTag)
{
	assert(m_pPageArena->total_page==0);
	assert(m_pNodeArea->root_node_slot==NIL_PTR);
	assert(nTag>0);
	
	int cur_page_slot;
	int cur_page_naddr;
	int cur_root;
	SPage page;
	
	cur_page_naddr = 0;
	cur_page_slot  = 0;
	cur_root       = 0;
	
	BuildOneCellPage(strWord,nTag,page);
	CopyPage(&page, &(m_pPageArena->page_ary[cur_page_slot]));

	SubAllPageAccessCount();
	m_pPageArena->access_ary[cur_page_slot] = INT_MAX;
	m_pPageArena->bDirty_ary[cur_page_slot] = true;
	m_pPageArena->page_naddr_ary[cur_page_slot] = cur_page_naddr;
	m_pPageArena->total_page = 1;
	//m_pPageArena->page_ary[cur_page_slot].next_page_naddr = NIL_PTR
	//m_pPageArena->page_ary[cur_page_slot].used_cell_slot_sum = 1
	//不用修改了

	//建立B树接点
	ClearNode(&(m_pNodeArea->node_ary[cur_root]));
	m_pNodeArea->node_ary[cur_root].bDirty            = true;
	m_pNodeArea->node_ary[cur_root].bPtToPageNaddr    = true;
	m_pNodeArea->node_ary[cur_root].used_key_slot_sum = 0;
	m_pNodeArea->node_ary[cur_root].ptr_o             = cur_page_naddr;
	m_pNodeArea->root_node_slot     = cur_root;
	m_pNodeArea->used_node_slot_sum = 1;
}

int CLexBTree::SearchPageNaddr(CKeyType fKey)
{
	int page_naddr_to_search;
	int key_slot;
	int cur_node_slot,pre_node_slot;
	cur_node_slot = m_pNodeArea->root_node_slot;
	if(cur_node_slot<0) 
		return NIL_PTR;  //如果没有B树则没法搜索返回无效指针
	while ( !(m_pNodeArea->node_ary[cur_node_slot].bPtToPageNaddr) )
	{
		pre_node_slot = cur_node_slot;
		for(key_slot=0;
		key_slot< m_pNodeArea->node_ary[pre_node_slot].used_key_slot_sum;
		key_slot++)
		{
			if(fKey<m_pNodeArea->node_ary[pre_node_slot].key_ary[key_slot])
			{
				if(0==key_slot)
					cur_node_slot = m_pNodeArea->node_ary[pre_node_slot].ptr_o;
				else 
					cur_node_slot = m_pNodeArea->node_ary[pre_node_slot].ptr_ary[key_slot-1];
				break;
			}
		}
		if(key_slot==0) { 
			// 当m_pNodeArea->node_ary[cur_node_slot].used_key_slot_sum =0 时
			cur_node_slot =  m_pNodeArea->node_ary[pre_node_slot].ptr_o;
		}
		// 搜索到SNode的最末端的Key 的 ptr
		else if (key_slot == m_pNodeArea->node_ary[pre_node_slot].used_key_slot_sum) {
			cur_node_slot 
				=  m_pNodeArea->node_ary[pre_node_slot].ptr_ary[key_slot-1];
		}
	}
	for(key_slot=0;
	key_slot< m_pNodeArea->node_ary[cur_node_slot].used_key_slot_sum;
	key_slot++)
	{
		if(fKey<m_pNodeArea->node_ary[cur_node_slot].key_ary[key_slot])
		{
			if(0==key_slot)
				page_naddr_to_search = m_pNodeArea->node_ary[cur_node_slot].ptr_o;
			else 
				page_naddr_to_search = m_pNodeArea->node_ary[cur_node_slot].ptr_ary[key_slot-1];
			break;
		}
	}
	if(key_slot==0) {
		// 当m_pNodeArea->node_ary[cur_node_slot].used_key_slot_sum =0 时
		page_naddr_to_search =  m_pNodeArea->node_ary[cur_node_slot].ptr_o;
	}
	else if (key_slot == m_pNodeArea->node_ary[cur_node_slot].used_key_slot_sum) {
		page_naddr_to_search 
			=  m_pNodeArea->node_ary[cur_node_slot].ptr_ary[key_slot-1];
	}
	return page_naddr_to_search; 
	// 找到了 B树指向可能满足此fKey页 的B数叶子
}
int CLexBTree::GetSpareNodeSlot()
throw (CNodeError)
{
	int nRet;
	if(m_pNodeArea->used_node_slot_sum < NODENUM) {
		nRet = m_pNodeArea->used_node_slot_sum;
		m_pNodeArea->used_node_slot_sum ++;
	}
	else {
		Clean();
	 //表示已无空白节点SLOT可以分配
		throw CNodeError();
	}
	return nRet;
}
int CLexBTree::GetSparePageSlotByNRU()
{
	int  page_slot;
	// 首先查看PageArena中有没有空白的pageslot
	// 当有空白的page_slot时直接返回此空白的page_slot	
	for(page_slot=0;page_slot<PAGENUM; page_slot++) {
		if(m_pPageArena->access_ary[page_slot] == -1) // -1 表示这个pageslot是空白
		{
			return page_slot;
		}
	}

	int  min_access;
	int  min_a_ps;// min_access_page_slot
	min_access   = m_pPageArena->access_ary[0];
	min_a_ps     = 0;
	for(page_slot=1;page_slot<PAGENUM; page_slot++) {
		if(min_access > m_pPageArena->access_ary[page_slot]) {
			min_access = m_pPageArena->access_ary[page_slot];
			min_a_ps   = page_slot;
		}
	}
	if(m_pPageArena->bDirty_ary[min_a_ps])
	{ //如果是修改过的需要写回文件中
		WriteAndClearPageSlot(min_a_ps);
	}
	return min_a_ps;	
}

void CLexBTree::WriteAndClearPageSlot(int page_slot)
{
	assert(page_slot>=0);
	assert(m_pPageArena->access_ary[page_slot]!=-1); // 这不是空白页
	void* buff;
	long  lOff;
	buff = (void *) &(m_pPageArena->page_ary[page_slot]);
	lOff = sizeof(SPage) * m_pPageArena->page_naddr_ary[page_slot];
	m_pDictFile->Seek(lOff,CFile::begin);
	m_pDictFile->WriteHuge(buff,sizeof(SPage));
	
	// 使此page_slot回到原初的状态
	m_pPageArena->bDirty_ary[page_slot]               = false;
	m_pPageArena->page_naddr_ary[page_slot]           = NIL_PTR;
	m_pPageArena->access_ary[page_slot]               = -1;
	ClearPage( &(m_pPageArena->page_ary[page_slot]) );
}
void CLexBTree::WriteNotClearPageSlot(int page_slot)
{
	assert(page_slot>=0);
	assert(m_pPageArena->access_ary[page_slot]!=-1); // 这不是空白页
	void* buff;
	long  lOff;
	buff = (void *) &(m_pPageArena->page_ary[page_slot]);
	lOff = sizeof(SPage) * m_pPageArena->page_naddr_ary[page_slot];
	m_pDictFile->Seek(lOff,CFile::begin);
	m_pDictFile->WriteHuge(buff,sizeof(SPage));
	
	// 此page_slot 已不 dirty
	m_pPageArena->bDirty_ary[page_slot]               = false;
}
void CLexBTree::ReadAndSetPageSlot(int from_page_addr,int to_page_slot)
{
	assert(from_page_addr>=0);
	assert(to_page_slot>=0);
	void* buff;
	long  lOff;
	buff = (void *) &(m_pPageArena->page_ary[to_page_slot]);
	lOff = sizeof(SPage) * from_page_addr;
	m_pDictFile->Seek(lOff,CFile::begin);
	m_pDictFile->ReadHuge(buff,sizeof(SPage));
	
	m_pPageArena->bDirty_ary[to_page_slot]               = false;
	m_pPageArena->page_naddr_ary[to_page_slot]           = from_page_addr;
	SubAllPageAccessCount();
	m_pPageArena->access_ary[to_page_slot]               = INT_MAX;
}
void CLexBTree::FlushToDisk()
{
	FlushToDict();
	FlushToIdx();
}
void CLexBTree::FlushToDict()
{
	int page_slot;
	for(page_slot=0; page_slot<PAGENUM; page_slot++) {
		if(m_pPageArena->bDirty_ary[page_slot]==true)
		{ //如果是修改过的需要写回文件中
			WriteNotClearPageSlot(page_slot);
		}
	}
}
void CLexBTree::FlushToIdx()
{
	CFile*  pIndexFile;
	void* p;

		pIndexFile = new CFile("lexidx.dat",CFile::modeCreate | CFile::modeWrite);
		
		p = (void*) &(m_pNodeArea->root_node_slot);
		pIndexFile->Write(p,sizeof(int));
		p = (void*) &(m_pNodeArea->used_node_slot_sum);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -