📄 p384.cpp
字号:
#include "p382.cpp" int PageFind ( const TwoChars & key, const paddr PageNumber ) //在由指针PageNumber所指的页块中搜索关键码key, 如果找到则返回1, 否则返回0。 //因为在页块内的搜索方法一般为顺序搜索, 算法不再特别给出, 可参看程序9.1。 { for (int i=0;i<PageNumber->Count;i++) { if (key==PageNumber->Names[i]) return 1; } return 0; }; paddr Find ( const TwoChars & key ) { //在文件中搜索具有关键字key的记录。若找到, 则返回该记录所在页块的地址; 若没有找到, 则返回 0。 unsigned int id = makeAddress ( key, DicDepth ); //按key与DicDepth计算目录地址 paddr FoundPage; FoundPage= Directory[id]; //在目录中找到相应页块地址 if ( PageFind ( key, FoundPage ) ) return FoundPage; //在该页块中搜索, 找到返回页块地址 else return 0; } void DirDouble ( ) { //目录成倍扩充的算法 unsigned int CurrentSize = Power2(DicDepth); paddr *TmpDir = Directory; //创建临时目录 Directory = new paddr[2*CurrentSize]; //创建新目录 for ( int i=0; i<CurrentSize; i++ ) //从临时目录向新目录传送页块指针 { Directory[i] = TmpDir[i]; Directory[CurrentSize+i] = TmpDir[i]; } DicDepth++; delete [] TmpDir; } int buddy ( const unsigned int index ) { //根据一个页块的二进制地址index计算该页块的伙伴的二进制地址, 前端的二进位是互补的。 if (DicDepth == 0 ) return 0; //目录深度为0, 没有伙伴 if ( Directory[index]->PgDepth < DicDepth ) //该页块的局部深度小于目录深度 return -1; //没有伙伴 unsigned int mask = 1; //工作变量 mask <<= DicDepth - 1; //左移DicDepth - 1位, 将1移到最高位 unsigned int buddyAddress = index ^ mask; //做异或操作, 求伙伴 return buddyAddress; } void ReDisTribute ( paddr PageNumber, paddr NewPage ) //将老页块中所有关键码重新分布 { int i=0; int CurrentSize=PageNumber->PgDepth; NewPage->Count=0; while (i<PageNumber->Count) { TwoChars key=PageNumber->Names[i]; int NowPage=makeAddress ( key, CurrentSize ); if (Directory[NowPage]==NewPage) { NewPage->Names[NewPage->Count]=key; NewPage->Count++; PageNumber->Count--; PageNumber->Names[i]=PageNumber->Names[PageNumber->Count]; } else i++; } } void Split ( const TwoChars key, paddr PageNumber ) { //分裂页块 int CurrentSize = DicDepth; //记下老的目录大小 if ( PageNumber->PgDepth == DicDepth ) //页块深度等于目录深度时 DirDouble( ); //页块分裂将导致目录成倍扩充 paddr NewPage = new page; //为伙伴页块分配存储空间 PageNumber->PgDepth ++; //老页块的局部深度加1 unsigned int id = makeAddress ( key, CurrentSize ); //按key与老DicDepth计算二进制地址 unsigned int bd = buddy ( id ); //找伙伴页块的二进制地址 Directory [ bd ] = NewPage; //建立伙伴页块的目录项 NewPage->PgDepth = PageNumber->PgDepth; //伙伴的局部深度等于老页块的局部深度 ReDisTribute ( PageNumber, NewPage ); //将老页块中所有关键码重新分布 } int Add (const TwoChars & key ) ; void Insert ( paddr PageNumber, const TwoChars & key ) { //将新关键码key插入到由PageNumber指定的页块中。 if ( PageNumber->Count != PageSize ) { //若本页块中关键码个数未满 PageNumber->Names [ PageNumber->Count ] = key; PageNumber->Count++; //直接插入 } else { //否则 Split ( key, PageNumber ); //将页块一分为二 Add ( key); //插入 } } int Add (const TwoChars & key ) { //将一个新关键码key插入到目录所指定的文件中。 paddr foundPage = Find ( key ); //按key在文件中搜索 if ( foundPage ) return 0; //若找到, 则不插入, 返回主程序 Insert ( Directory[makeAddress ( key, DicDepth )], key ); //将关键码key插入foundPage页块 return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -