2008-04-07

UNIX磁盘空间管理算法

#include
#include
#include

#define NO -1

struct size{//每一个磁盘块都有一个数组,该数组包含10个元素,当该磁盘快成为当前组的第一个时,用于存放下一组的信息
int blocl[10];
};

struct blocd{//定义组,每组有10个磁盘块
struct size a[10];//用于在空闲磁盘块号链中存放磁盘块号
}block[40];

struct File{
int fileblocd[100];//用于记录分别分配给文件的磁盘块号,每个文件最多占有100个磁盘快
}file[5];

struct SqStack{ //定义一个记录磁盘块号的堆栈
int *base;
int *top; //指向栈顶元素
int stacksize;
int s_nfree; //记录栈中现有磁盘块数的变量
}s_free;

void InitStack(SqStack &S){
S.base = (int *)malloc(10 * sizeof(int));
if(!S.base)
exit(OVERFLOW);
S.top = S.base - 1;
S.stacksize = 10;
S.s_nfree = 0;
}

void Push(SqStack &S, int e){
S.top ++;
*S.top = e;
S.s_nfree ++;
}

int Pop(SqStack &S){
int e = *S.top;
S.top --;
S.s_nfree --;
return e;
}

int label;//用来记录当前磁盘块的绝对名字
int nextLabel;//用来记录下一个磁盘块的绝对名字

//完成空闲磁盘块号堆栈、空闲磁盘块号队列及记录文件占用磁盘块状态的file结构数组
void init(){
int i,j,k;

//初始化空闲磁盘块号队列
for(i = 0;i <>
for(j = 0;j <>
if(i == 0){ //第0组中每个磁盘块内的数组中的每个元素都是NO
for(k = 0;k <>
block[i].a[j].blocl[k] = NO;
}
else{ //其他组中,除第0个磁盘块外,其他磁盘块的数组中的每个元素都是NO
if(j == 0){
for(k = 9;k >= 0;k --){
block[i].a[j].blocl[k] = label;
label --;
}
}
else{
for(k = 0;k <>
block[i].a[j].blocl[k] = NO;
}
}
}
j = j - 1;
label = i * 10 + j;
}

//初始化空闲磁盘块号堆栈
int tmp[10];
InitStack(s_free);
for(i = 0;i <>
tmp[i] = label;
label --;
} //循环结束时,label为下一组的最后一个元素的绝对名字
for(i = 9;i >= 0;i --)
Push(s_free,tmp[i]);

//初始化文件占用磁盘块状态
for(i = 0;i <>
for(j = 0;j <>
file[i].fileblocd[j] = NO;
}
}

int getLine(int name){
int line = name/10;
return line;
}

int getCount(int name){
int count = fmod(name,10);
return count;
}

void keepStackFull(int name){
int line = getLine(name);
int count = getCount(name);
int temp[10],i;

for(i = 0;i <>
temp[i] = block[line].a[count].blocl[i];
Push(s_free,temp[i]);
}

}

void keepStackEmpty(int nextName){
int line = getLine(nextName);
int count = getCount(nextName);

int temp[10],i,j;
for(i = 0;i <>
temp[i] = Pop(s_free);
for(i = 0,j = 9;i <>
block[line].a[count].blocl[i] = temp[j];

}

//fileno为文件序号,用于指定需要分配的文件;blockd为所需要磁盘块数目
void alloc(int fileno,int blockd){
int i;
for(i = 0;i <>
if(s_free.s_nfree == 0)
keepStackFull(label);
label = Pop(s_free);
file[fileno].fileblocd[i] = label;
}
}

void free(int fileno){
int i = 0;
do{
label = file[fileno].fileblocd[i];

if(s_free.s_nfree == 10){
//if(fmod(label,10) != 0)
//keepStackEmpty(nextLabel);
//else
keepStackEmpty(label);
}

Push(s_free,label);
file[fileno].fileblocd[i] = NO;
nextLabel = file[fileno].fileblocd[i+1];
i ++;
}while(nextLabel != NO);
}

//设置打印格式
void print(){
int i = 0,j,k,num;
printf("............................................................................\n");
printf("Free block : \n");
int st[10];
int line,count;
if(s_free.s_nfree != 0){
while(s_free.s_nfree != 0){
st[i] = Pop(s_free);
i ++;
}
}
else{
j = 9;
line = getLine(label);
count = getCount(label);
while(j >= 0){
st[i] = block[line].a[count].blocl[j];
i ++;
j --;
}
}


num = i;
for(i = num - 1;i >= 0;i --)
Push(s_free,st[i]);
for(i = 0;i <>
printf(" %3d ",st[i]);
putchar('\n');

line = getLine(st[num-1]);
count = getCount(st[num-1]);
do{
for(i = 9;i >= 0;i --)
printf(" %3d ",block[line].a[count].blocl[i]);
putchar('\n');
st[num - 1] = block[line].a[count].blocl[0];
line = getLine(st[num-1]);
count = getCount(st[num-1]);
}while(block[line].a[count].blocl[0] != NO);
printf("............................................................................\n");
printf("File : \n");
for(i = 0;i <>
printf("file[%d] :",i);
j = 0;
k = 0;
do{
if(file[i].fileblocd[j] == NO){
printf(" NULL");
break;
}
else{
printf(" %3d ",file[i].fileblocd[j]);
nextLabel = file[i].fileblocd[j+1];
j ++;
k ++;
if(fmod(k,10) == 0){
putchar('\n');
printf(" ");
}
}
}while(nextLabel != NO);
putchar('\n');
}
printf("............................................................................\n");
}

void main(){
init();
printf("初始化 : \n");
print();

int i,s;
char c,null;
int count_f = 0,count_h = 0;
step:
do{
printf("请输入待分配的文件的序号 : \n");
scanf("%d",&i);
null = getchar();
printf("请输入待分配的文件的所需的磁盘块数目 : \n");
judge:
scanf("%d",&s);
null = getchar();
alloc(i,s);
print();
if(s > 100){
printf("请重新输入文件所需的磁盘块数目 : ");
goto judge;
}
count_f = count_f + 1;
if(count_h > 0)
count_h = count_h - 1;
if(count_f == 5){
printf("已经有5个文件存在,达到最大值 . :-(\n");
break;
}
printf("分配 ? y or n ?\n");
c = getchar();
}while(c == 'y');

do{
printf("请输入待回收的文件的序号 : \n");
scanf("%d",&i);
null = getchar();
free(i);
print();
count_h = count_h + 1;
count_f = count_f - 1;
if(count_h == 5 || count_f == 0){
printf("已经没有文件存在,无法删除. :-(\n");
break;
}
printf("回收 ? y or n ?\n");
c = getchar();
null = getchar();
}while(c == 'y');
printf("分配 ? y or n ?\n");
c = getchar();

if(c == 'y')
goto step;
printf("感谢使用 by 052226 .:-)\n");
}