实验四文件系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int hashfile_findrec(int fd,int keyoffset,int keylen,void *buf) { struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int addr=hash(keyoffset,keylen,buf,hfh.total_rec_num); int offset=sizeof(struct HashFileHeader)+addr*(hfh.reclen+sizeof(struct CFTag)); if(lseek(fd,offset,SEEK_SET)==-1) return -1; struct CFTag tag;

参考代码
• • • • HashFile.h HashFile.c 测试程序jtRecord.h 测试程序jtRecord.c
HashFile.h
#include <unistd.h> #define COLLISIONFACTOR 0.5 //Hash函数冲突 因子 struct HashFileHeader { int sig; //Hash文件印鉴 int reclen; //记录长度 int total_rec_num; //总记录数 int current_rec_num; //当前记录数 };
int hashfile_write(int fd,int keyoffset,int keylen,void *buf) { return hashfile_saverec(fd,keyoffset,keylen,buf); //return -1; } int hashfile_delrec(int fd,int keyoffset,int keylen,void *buf) { int offset; offset=hashfile_findrec(fd,keyoffset,keylen,buf); if(offset!=-1) { struct CFTag tag; read(fd,&tag,sizeof(struct CFTag)); tag.free=0; //置空闲标志 lseek(fd,offset,SEEK_SET); write(fd,&tag,sizeof(struct CFTag)); struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int addr=hash(keyoffset,keylen,buf,hfh.total_rec_num); offset=sizeof(struct HashFileHeader)+addr*(hfh.reclen+sizeof(struct CFTag)); if(lseek(fd,offset,SEEK_SET)==-1) return -1;
实验四 文件系统——Hash结构 文件
• • • • • • • 实验目的 实验内容 实验准备 实验设计 参考代码 实验结果 思考题
实验目的
• 理解Linux文件系统的内部技术,掌握 Linux与文件有关的系统调用命令,并在此 基础上建立面向随机检索的hash结构文件。 • Linux系统保持UNIX文件系统的风格,提 供流式文件界面,这种结构具有简洁灵活 的特点,但并不直接支持记录式文件和关 键字检索。本实验是在Linux文件系统基础 上,设计一组库函数,以提供对随机检索 的支持。
free(p); p=NULL; offset+=hfh.reclen+sizeof(struct CFTag); if(lseek(fd,offset,SEEK_SET)==-1) return -1; read(fd,&tag,sizeof(struct CFTag)); goto recfree; } } } int hashfile_saverec(int fd,int keyoffset,int keylen,void *buf) { if(checkHashFileFull(fd)) { return -1; } struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int addr=hash(keyoffset,keylen,buf,hfh.total_rec_num); int offset=sizeof(struct HashFileHeader)+addr*(hfh.reclen+sizeof(struct CFTag)); if(lseek(fd,offset,SEEK_SET)==-1) return -1;

实验设计
• 由于在Linux系统核心之外模拟实现hash文件, 有关hash文件的说明信息不能保存在inode中, 而只能记录在文件的头部。这些信息包括hash文 件标志、记录大小、文件长度、记录数量等。 可以根据hash文件核心算法设计内部函数,包括 记录的保存、查找、删除等,在此基础上实现 读、写等常规操作。
else return -1;
} int hashfile_close(int fd) { return close(fd); } int hashfile_read(int fd,int keyoffset,int keylen,void *buf) { struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int offset=hashfile_findrec(fd,keyoffset,keylen,buf); if(o43;sizeof(struct CFTag),SEEK_SET); return read(fd,buf,hfh.reclen); } else { return -1; } }
while((*p1==*p2)&&(j<keylen)) { p1++; p2++; j++; } if(j==keylen) { free(p); p=NULL; return (offset); //找到,返回偏移值 } else { if(addr==hash(keyoffset,keylen,p,hfh.total_rec_num)) { count--; //hash值相等而key值不等 if(count==0) { free(p); p=NULL; return -1; //不存在 } }
read(fd,&tag,sizeof(struct CFTag)); char count=tag.collision; if(count==0) return -1; //不存在 recfree: if(tag.free==0) { offset+=hfh.reclen+sizeof(struct CFTag); if(lseek(fd,offset,SEEK_SET)==-1) return -1; read(fd,&tag,sizeof(struct CFTag)); goto recfree; } else { char *p=(char*)malloc(hfh.reclen*sizeof(char)); read(fd,p,hfh.reclen); //printf("Record is {%d,%s}\n",((struct jtRecord*)p)->key,((struct jtRecord*)p)->other); char *p1,*p2; p1=(char*)buf+keyoffset; p2=p+keyoffset; int j=0;
read(fd,&tag,sizeof(struct CFTag)); tag.collision--; //冲突记数减1 lseek(fd,offset,SEEK_SET); // write(fd,&tag,sizeof(struct CFTag)); hfh.current_rec_num--; //当前记录数减1 lseek(fd,0,SEEK_SET); write(fd,&hfh,sizeof(struct HashFileHeader)); } else { return -1; } }
} close(fd); return rtn; } else { close(fd); return -1; } } int hashfile_open(const char *filename,int flags, mode_t mode) { int fd=open(filename,flags,mode); struct HashFileHeader hfh; if(read(fd,&hfh,sizeof(struct HashFileHeader))!=-1) { lseek(fd,0,SEEK_SET); if(hfh.sig==31415926) return fd; else return -1; }
实验内容
• 参考教材中hash文件构造算法,设计一组 hash文件函数,包括hash文件创建、打开、 关闭、读、写等。 • 编写一个测试程序,通过记录保存、查找、 删除等操作,检查上述hash文件是否实现 相关功能。
实验准备
• 教程Hash文件核心算法,包括记录保存、记 录查找、记录删除等。 教程Linux系统有关文件的系统调用命令: creat,open,close,read,write,lseek。
struct CFTag { char collision; //冲突计数 char free; //空闲标志 }; int hashfile_creat(const char *filename,mode_t mode,int reclen,int recnum); //int hashfile_open(const char *filename,int flags); int hashfile_open(const char *filename,int flags, mode_t mode); int hashfile_close(int fd); int hashfile_read(int fd,int keyoffset,int keylen,void *buf); int hashfile_write(int fd,int keyoffset,int keylen,void *buf); int hashfile_delrec(int fd,int keyoffset,int keylen,void *buf); int hashfile_findrec(int fd,int keyoffset,int keylen,void *buf); int hashfile_saverec(int fd,int keyoffset,int keylen,void *buf); int hash(int keyoffset,int keylen,void *buf,int recnum); int checkHashFileFull(int fd); int readHashFileHeader(int fd,struct HashFileHeader *hfh )
HashFile.c
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include "HashFile.h"
int hashfile_creat(const char *filename,mode_t mode,int reclen,int total_rec_num) { struct HashFileHeader hfh; int fd; int rtn; char *buf; int i=0; hfh.sig=31415926; hfh.reclen=reclen; hfh.total_rec_num=total_rec_num; hfh.current_rec_num=0; //fd=open(filename,mode); fd=creat(filename,mode); if(fd!=-1) { rtn=write(fd,&hfh,sizeof(struct HashFileHeader)); //lseek(fd,sizeof(struct HashFileHeader),SEEK_SET); if(rtn!=-1) { buf=(char*)malloc((reclen+sizeof(struct CFTag))*total_rec_num); memset(buf,0,(reclen+sizeof(struct CFTag))*total_rec_num); rtn=write(fd,buf,(reclen+sizeof(struct CFTag))*total_rec_num); free(buf);
相关文档
最新文档