/** * @brief 初始化系统,从文件中读入相关的信息完成初始化;如果文件不存在,则重新创建文件,并进行初始化。 * * @param [in/out] head : struct dbSysHead * * @return int * * @author linzhixia * @date 2013/11/6 **/ int initSys(struct dbSysHead *head) { FILE *fp; int i; fp = fopen( DBMS_DAT, "rb" ); if( NULL == fp ) { printf("数据库文件不存在,开始创建数据库......\n\n"); creaSysHead(); fp = fopen( DBMS_DAT, "rb" ); } isAvail( fp, "initSys", FOPEN); rewind(fp); fread( &(head->desc), sizeof(struct SysDesc), 1, fp ); head->bitMap = (unsigned long *)malloc(head->desc.sizeBitMap); isAvail(head->bitMap,"initSys",MALLOC); rewind(fp); fseek( fp, head->desc.bitMapAddr, SEEK_SET ); fread( head->bitMap, 1, head->desc.sizeBitMap, fp ); for( i=0; i<SIZE_BUFF; i++ ) { head->buff.map[i].pageNo = -1; head->buff.map[i].vstTime = 0; head->buff.map[i].edit = P_UNEDIT; } head->buff.curTimeStamp = 0; fclose(fp); return 0; }
void free(void* p) { if (p == 0) return; if (p == (void*) array) return; int idx = ((((long) p) - ((long) array)) / 4) - 1; sanity(idx); if (!isTaken(idx)) { //Debug::panic("freeing free block %p %d\n",p,idx); return; } int sz = size(idx); int leftIndex = left(idx); int rightIndex = right(idx); if (isAvail(leftIndex)) { remove(leftIndex); idx = leftIndex; sz += size(leftIndex); } if (isAvail(rightIndex)) { remove(rightIndex); sz += size(rightIndex); } makeAvail(idx,sz); }
/** * @brief 把文件的页转化成系统的页 * * @param [in] head : struct dbSysHead * * @param [in] fid : long 文件标识 * @return long * @retval 返回文件中的页在系统中的页号 * * @author tianzhenwu * @date 2015/10/20 **/ long mapPage( struct dbSysHead *head, long fid, long num ) { int idx; long segmentAddr; struct Segment segment; long pageMap; int ithSegment; int tmp; idx = queryFileID( head, fid ); if( idx <0 ) { isAvail(NULL,"mapPage",ARRAY); } if( num > head->desc.fileDesc[idx].filePageNum ) { isAvail(NULL,"mapPage",PAGE_BOUND); } segmentAddr = head->desc.fileDesc[idx].fileAddr; ithSegment = num / PAGE_PER_SEGMENT + 1; while( ithSegment > 0 ) { getSegmentValue( head, segmentAddr, &segment ); segmentAddr = segment.nextAddr; ithSegment --; } tmp = num / PAGE_PER_SEGMENT; num = num - tmp * PAGE_PER_SEGMENT; pageMap = segment.pageNo[num]; if( num>PAGE_PER_SEGMENT ) { isAvail(NULL,"mapPage",DEFAULT); } return pageMap; }
/** * @brief 从一个文件中任意位置读入任意长度的字符(不能超过文件的大小) * * @param [in] head : struct dbSysHead * * @param [in] fid : long 文件标识 * @param [in] pos : long 文件起始地址 * @param [in] legnth : long 读取的长度 * @param [out] des : void * 空指针,用于接受读取的字符 * @return int * * @author tianzhenwu * @date 2015/10/20 **/ int rdFile( struct dbSysHead *head, int bufferID, long fid, long pos, long length, void *des) { int i; int idx; long staPage,endPage; long pnt; long rSta,rEnd; long pageMap; char *tmp; idx = queryFileID(head,fid); if( idx<0 ) { isAvail(NULL,"rdFile",ARRAY); } if( (pos+length) > SIZE_PER_PAGE * head->desc.fileDesc[idx].filePageNum ){ // 注意:SIZE_PER_PAGE * head->desc.fileDesc[i].filePageNum 可能溢出 isAvail(NULL,"rdFile",BOUND); } // 这里没有必要malloc一块临时的内存区,这样浪费时间。应该直接把数据写到des tmp = (char *)malloc( length+1 ); isAvail( tmp, "rdFile", MALLOC ); staPage = pos/SIZE_PER_PAGE; endPage = (pos+length-1)/SIZE_PER_PAGE; pnt = 0; for( i=staPage; i<(endPage+1); i++ ) { rSta = (pos+pnt) - ( (pos+pnt)/SIZE_PER_PAGE ) * SIZE_PER_PAGE; rEnd = ( (i+1)*SIZE_PER_PAGE>(pos+length)) ? ((pos+length) - ((pos+length)/SIZE_PER_PAGE)*SIZE_PER_PAGE) : SIZE_PER_PAGE ; pageMap = mapPage( head, fid, i); readInPage( head, bufferID, pageMap, rSta, rEnd - rSta, tmp+pnt ); pnt += (rEnd-rSta); } memcpy( des, tmp, length); free(tmp); return 0; }
int init_database(struct dbSysHead *head) { initSys(head); head->fpdesc = fopen(DBMS_DAT, "rb+"); isAvail(head->fpdesc, "main", FOPEN); return 0; }
/** * @brief 从一页中任意位置读入字符 * * @param [in] head : struct dbSysHead * * @param [in] pgID : long 页号 * @param [in] pos : long 页内起始地址 * @param [in] legnth : long 读取的长度 * @param [out] des : void * 空指针,用于接受读取的字符 * @return int * * @author tianzhenwu * @date 2015/10/20 **/ int readInPage( struct dbSysHead *head, int bufferID, long pgID,long pos,long length, void *des ) { int nPage; if( pos + length > SIZE_PER_PAGE ) { isAvail(NULL,"readInPage",PAGE_BOUND); } nPage = reqPage( head, bufferID, pgID ); memcpy( des, (head->buff[bufferID]).data[nPage]+pos, length ); return 0; }
/** * @brief 往一页中任意位置写入字符 * * @param [in] head : struct dbSysHead * * @param [in] pgID : long 页号 * @param [in] pos : long 页内起始地址 * @param [in] legnth : long 读取的长度 * @param [out] des : void * 空指针,用于传递要写入的字符 * @return int * * @author tianzhenwu * @date 2015/10/20 **/ int writeInPage( struct dbSysHead *head, int bufferID, long pgID, long pos, long length, void *des ) { int nPage; if( pos + length > SIZE_PER_PAGE ) { isAvail(NULL,"writeInPage",PAGE_BOUND); } nPage = reqPage(head, bufferID, pgID); memcpy( (head->buff[bufferID]).data[nPage]+pos, des, length ); head->buff[bufferID].map[nPage].edit = P_EDIT; return 0; }
bool Movie::leaseCopy() { if (isAvail()) { m_avail--; //m_rentees.push_back(a_customer); return true; } else { cout << "Not able to lease copy" << endl; } return false; }
/** * @brief 往一个文件中任意位置写入任意长度的字符,若超过文件长度,则会自动扩展文件长度 * * @param [in] head : struct dbSysHead * * @param [in] fid : long 文件标识 * @param [in] pos : long 文件起始地址 * @param [in] legnth : long 写入的长度 * @param [out] des : void * 空指针,用于传递要写入的字符 * @return int * * @author tianzhenwu * @date 2015/10/20 **/ int wtFile( struct dbSysHead *head, int bufferID, long fid, long pos, long length, void *des) { int i; int idx; int extpage; long staPage,endPage; long pnt; long rSta,rEnd; long pageMap; char *tmp; idx = queryFileID(head,fid); if( idx<0 ) { isAvail(NULL,"wtFile",ARRAY); } if( (pos+length) > SIZE_PER_PAGE * head->desc.fileDesc[idx].filePageNum ){ // 注意:SIZE_PER_PAGE * head->desc.fileDesc[i].filePageNum 可能溢出 extpage = (pos+length) / SIZE_PER_PAGE - head->desc.fileDesc[idx].filePageNum + 1; extendFileSpace( head, fid, extpage ); } tmp = (char *)malloc( length+1 ); isAvail( tmp, "wtFile", MALLOC ); memcpy( tmp, des, length ); staPage = pos/SIZE_PER_PAGE; endPage = (pos+length-1)/SIZE_PER_PAGE; pnt = 0; for( i=staPage; i<(endPage+1); i++ ) { rSta = (pos+pnt) - ( (pos+pnt)/SIZE_PER_PAGE ) * SIZE_PER_PAGE; rEnd = ( (i+1)*SIZE_PER_PAGE>(pos+length)) ? ((pos+length) - ((pos+length)/SIZE_PER_PAGE)*SIZE_PER_PAGE) : SIZE_PER_PAGE ; pageMap = mapPage( head, fid, i); writeInPage( head, bufferID, pageMap, rSta, rEnd - rSta, tmp+pnt ); pnt += (rEnd-rSta); } free(tmp); return 0; }
/** * @brief 若第一次运行程序,则初始化系统,并把初始化的信息写入到文件中。 * * @return int * * @author linzhixia * @date 2013/11/6 **/ int creaSysHead() { FILE *fp; struct dbSysHead sysHead; char ch; fp = fopen( DBMS_DAT, "wb" ); isAvail( fp, "creaSysHead", FOPEN ); rewind( fp ); fseek( fp, BITMAP_ADDR+SIZE_BIT_MAP+SIZE_DATA_SPACE, SEEK_SET ); ch = '\0'; fwrite( &ch, sizeof(char), 1, fp ); /* 这里把参数写死了,其实用配置文件的方式初始化更好。 */ sysHead.desc.sizeOfFile = SIZE_DATA_SPACE; sysHead.desc.sizePerPage = SIZE_PER_PAGE; sysHead.desc.totalPage = ( SIZE_DATA_SPACE ) / ( SIZE_PER_PAGE ); sysHead.desc.bitMapAddr = BITMAP_ADDR ; sysHead.desc.sizeBitMap = sysHead.desc.totalPage / 8; //byte sysHead.desc.pageAvai = ( SIZE_DATA_SPACE ) / ( SIZE_PER_PAGE ); sysHead.desc.dataAddr = DATA_ADDR; sysHead.desc.iNodeNum = 0; sysHead.desc.iNodeAddr = INODE_ADDR; sysHead.desc.iNodeCur = 0; sysHead.desc.curfid = FIRST_FID; sysHead.desc.curFileNum = 0; memset(sysHead.desc.fileDesc, 0, sizeof(struct FileDesc)*MAX_FILE_NUM); rewind(fp); fwrite( &(sysHead.desc), sizeof(struct SysDesc), 1, fp); sysHead.bitMap = (unsigned long *)malloc( sysHead.desc.sizeBitMap ); memset( sysHead.bitMap, -1, sysHead.desc.sizeBitMap ); rewind(fp); fseek( fp, sysHead.desc.bitMapAddr, SEEK_SET ); fwrite( sysHead.bitMap, 1, sysHead.desc.sizeBitMap, fp ); free(sysHead.bitMap); fclose(fp); return 0; }
/** * @brief 显示系统的bitmap * * @param [in] head : struct dbSysHead * * @param [int] start : int 要查询bitMap的起始页面号 * @param [int] end : int 要查询bitMap的终止页面号 * @return int * * @author linzhixia * @date 2013/11/6 **/ int showBitMap(struct dbSysHead *head, long start, long end) { long i; int count; int page; int pos; if (end > (*head).desc.totalPage) { isAvail(NULL, "showBitMap", DEFAULT); } for (count = 0, i = start; i<end; i++) { page = i / (8 * sizeof(long)); pos = i - 8 * sizeof(long)*page + 1; printf("%d", getBit(*((head->bitMap) + page), pos)); count++; if (count % 16 == 0) printf("\t"); } printf("\n"); return 0; }
void* malloc(long bytes) { //Debug::printf("malloc(%d)\n",bytes); if (bytes == 0) return (void*) array; int ints = ((bytes + 3) / 4) + 2; if (ints < 4) ints = 4; int p = avail; sanity(p); void* res = 0; while ((p != 0) && (res == 0)) { if (!isAvail(p)) { //Debug::panic("block @ %d is not available\n",p); } int sz = size(p); if (sz >= ints) { remove(p); int extra = sz - ints; if (extra >= 4) { makeTaken(p,ints); //Debug::printf("idx = %d, sz = %d, ptr = %p\n",p,ints,&array[p+1]); makeAvail(p+ints,extra); } else { makeTaken(p,sz); //Debug::printf("idx = %d, sz = %d, ptr = %p\n",p,sz,&array[p+1]); } res = &array[p+1]; } else { p = next1(p); } } if (res == 0) { //Debug::panic("heap is full, bytes=0x%x",bytes); } return res; }
/** * @brief Equal Filter based on index * * @param [in] head : struct dbSysHead * * @param [in] fileID : long * @param [in] attributeName : char* * @param [in] value : char* * @param [in] temp_datadic : relation* // * @return int //filter results, # in temp_datadic * * @author weiyu * @date 2015/12/13 **/ int indexScanEqualFilter(struct dbSysHead * head, int fileID, char* attributeName, char* value, relation * temp_data_dic){ //find empty temp_datadic for filter results int new_relation ; for (int i = 0; i < MAX_FILE_NUM; i++) { if (strcmp(temp_data_dic[i].getRelationName(),"") == 0) { new_relation = i; // cout<<"new relation id: "<<new_relation<<endl; temp_data_dic[new_relation].init("temp_datadict","XXX"); break; } } if (new_relation == MAX_FILE_NUM) { cout<<"no temp datadict for use!"<<endl; return -3; } int my_buffer_id_ ; int i; for (i = 0 ; i < BUFF_NUM; i++) { if (head->buff[i].emptyOrnot == true) { my_buffer_id_ = i; head->buff[i].emptyOrnot = false; // ready for writein // std::cout<<"bufferID: "<<i<<std::endl; break; } } if (i == BUFF_NUM) { cout<<"No Buffer Can be Used!"<<endl; return -1; } int idx; idx = queryFileID(head, fileID); if( idx<0 ) { isAvail(NULL,"createIndexOn",ARRAY); } int rec_len_ = head->redef[idx].getRecordLength(); temp_data_dic[new_relation] = head->redef[idx]; //wrong, need to wait class copy temp_data_dic[new_relation].fileID = -my_buffer_id_; //negative number for temp datadict, value is for which buffer attribute tempAttr; tempAttr = head->redef[idx].getAttributeByName(attributeName); int offset = tempAttr.getRecordDeviation(); int type = tempAttr.getType(); if(type != INT){ printf("The attribute is not INT type. Cannot scan by index.\n"); return -1; } //read the scanned table according to the temp_data_dict int pos; int tmpvalue = atoi(value); pos = searchByColumnAndValue(head,fileID,attributeName,tmpvalue); int hitRecordCount = 0; if(pos ==-1){ //do nothing int a; } else{ hitRecordCount = 1; // printf("pos:::%d\n",pos); char* one_Row_ = (char *)malloc(sizeof(char)*rec_len_); rdFile( head, 0, fileID, pos, rec_len_,one_Row_); //printf("**************************reading from index:\n"); //getOneRecord(one_Row_, &(head->redef[idx])); Buffer t(head, -2); if(false == t.AppendBuffer(one_Row_, rec_len_)){ t.writeBufferPage(t.filehead,my_buffer_id_ ,t.data_, t.current_size_); t.pageID++; if (t.pageID == SIZE_BUFF) { std::cout<<"this buffer full"<<std::endl; } memset(t.data_, 0, SIZE_PER_PAGE); memcpy(t.data_, one_Row_, rec_len_); t.pointer_ = t.data_+rec_len_; t.current_size_ = rec_len_; } t.writeBufferPage(t.filehead,my_buffer_id_ ,t.data_, t.current_size_); free(one_Row_); } temp_data_dic[new_relation].changeRecordNum(hitRecordCount); return new_relation; }