位示图磁盘管理模拟实现算法
分配和回收转换公式
3.1 转换公式的四种情况
1.行列号从0开始,盘块号从0开始
2.行列号从0开始,盘块号从1开始
3.行列号从1开始,盘块号从0开始
4.行列号从1开始,盘块号从1开始
提示:
(1)/为整除,%为取余
(2)位示图每个位可以取0或1,下面表格中的内容不代表位示图的取值,而是代表对应位的位置编号,即行号列号盘块号。每个单元格内容的格式如下:
(3)为了方便说明,假设下面的位示图每行都只有4个位
盘块号( 行号,列号)
3.1.1 行列号从0开始,盘块号从0开始
如表3.1.1:
位 字 第0列 第1列 第2列 第3列
第0行 0(0,0) 1(0,1) 2(0,2) 3(0,3)
第1行 4(1,0) 5(1,1) 6(1,2) 7(1,3)
第2行 8(2,0) 9(2,1) 10(2,2) 11(2,3)
第…行 … … … …
表3.1.1
此种情况最好计算,类似于二维数组的行列下标与元素位置之间的转换
分配时,行列号转换为盘块号
盘块号 = 行号 ∗ 行位数 + 列号
回收时,盘块号转换为行列号:
行号 = 盘块号 / 行位数
列号 = 盘块号 % 行位数
3.1.2 行列号从0开始,盘块号从1开始
如表3.1.2:
位 字 第0列 第1列 第2列 第3列
第0行 1(0,0) 2(0,1) 3(0,2) 4(0,3)
第1行 5(1,0) 6(1,1) 7(1,2) 8(1,3)
第2行 9(2,0) 10(2,1) 11(2,2) 12(2,3)
第…行 … … … …
表3.1.2
相对于第一种情况,盘块号多了1,所以:
分配时,相对于第一种情况,计算后盘块号再加一
盘块号 = 行号 ∗ 行位数 + 列号 + 1
回收时,相对于第一种情况,计算前盘块号先减一
行号 = (盘块号−1) / 行位数
列号 = (盘块号 − 1) % 行位数
3.1.3 行列号从1开始,盘块号从0开始
如表3.1.3:
位 字 第1列 第2列 第3列 第4列
第1行 0(1,1) 1(1,2) 2(1,3) 3(1,4)
第2行 4(2,1) 5(2,2) 6(2,3) 7(2,4)
第3行 8(3,1) 9(3,2) 10(3,3) 11(3,4)
第…行 … … … …
表3.1.3
相对于第一种情况,行列号多了1,所以:
分配时,相对于第一种情况,计算前行列号先减一
盘块号= == (行号 − 1) ∗ 行位数 + 列号 − 1
回收时,相对于第一种情况,计算后行列号再加一
行号 = 盘块号 / 行位数 + 1
列号 = 盘块号 % 行位数 + 1
3.1.4 行列号从1开始,盘块号从1开始
如表3.1.4:
位 字 第1列 第2列 第3列 第4列
第1行 1(1,1) 2(1,2) 3(1,3) 4(1,4)
第2行 5(2,1) 6(2,2) 7(2,3) 8(2,4)
第3行 9(3,1) 10(3,2) 11(3,3) 12(3,4)
第…行 … … … …
表3.1.4
相对于第一种情况,盘块号、行列号都多了1,所以:分配时,相对于第一种情况,计算前行列号先减一,计算后盘块号再加一
盘块号 = (行号 − 1) * 行位数 + (列号 − 1) + 1
盘块号 = (行号 - 1) * 行位数 + 列号
回收时,相对于第一种情况,计算前盘块号先减一,计算后行列号再加一
行号 = (盘块号 — 1) / 行位数 + 1
列号 = (盘块号 —1) % 行位数 + 1
``
代码总和:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class bitmap extends JFrame implements ActionListener {
JTable table;
JScrollPane sp1,sp2;
JTextArea ta;
JLabel l1,l2,l3,l4,l5;
JTextField tf1,tf2,tf3;
JButton b1,b2,b3,b4;
JPanel p1,p2,p3,p4,p5,p6,p7;
String data[][];
String colum[];
int sp [];//存放相对可用块
int used[];//存放相对已用块
int A,H;//A为可用快,H为已用块
public static void main(String [] args){
new bitmap();
}
public void init() { //功能:初始化
int k;
for(int i=0;i<30;i++)
for(int j=0;j<16;j++) {
k = (int)(Math. random()*2);//0与1两数字中进行随机
data[i][j]=""+k;
table.setValueAt(""+k,i,j);
}
}
public bitmap() {
// TODO Auto-generated constructor stub
super("位示图管理磁盘空间的分配与回收算法模拟实现");
data=new String[30][16];
colum =new String[16];
sp=new int[480];
used=new int[480];
A=0;
H=0;
for(int i=0;i<16;i++) {
colum[i]=""+i;
}
table = new JTable(data,colum);
sp1 = new JScrollPane(table);
tf1 = new JTextField(6);
tf2 = new JTextField(6);
tf3 = new JTextField(8);
ta = new JTextArea(10,20);
sp2 = new JScrollPane(ta);
p1 = new JPanel(new BorderLayout());
p2 = new JPanel(new FlowLayout());
p3 = new JPanel(new BorderLayout());
p4 = new JPanel(new FlowLayout());
p5 = new JPanel(new FlowLayout());
p6 = new JPanel(new BorderLayout());
p7 = new JPanel(new FlowLayout());
l1 = new JLabel("位示图");
b1 = new JButton("位示图初始化");
b1. addActionListener(this);
b2 = new JButton("回收全部磁盘块");
b2. addActionListener(this);
p2.add(b1);
p2. add(b2);
p1.add(l1, "North");
p1. add(sp1, "Center");
p1.add(p2 ,"South");
l2 = new JLabel("运行状况: ");
l5 = new JLabel("空闲块数量: ");
p7.add(l5);
p7.add(tf3);
p3.add(l2, "North");
p3. add(p7,"South");
p3. add(sp2,"Center");
l3 = new JLabel("请输入需要分配的块数: ");
l4 = new JLabel("请输入要回收的盘块号: ");
b3 = new JButton("确认分配");
b3.addActionListener(this);
b4= new JButton("确认回收");
b4. addActionListener(this);
p4.add(l3);p4. add(tf1);
p4. add(b3);p5.add(l4);
p5. add(tf2);
p5. add(b4);
p6. add(p4 ,"North");
p6. add(p5, "Center");
this.setLayout(new BorderLayout());
this. add(p1, "West");
this.add(p3,"Center");
this. add(p6, "South");
this. pack();
this . setVisible(true);
}
public void getavail() //功能:得出可用块号与不可用块号的集合
{
int a;
int b=0,c=0;
A= 0;
H=0;
for(int i=0;i<30;i++)
for(int j=0;j<16;j++) {
if(data[i][j].equals("0")) {
a=i*16+j;//得到相对块号
sp[b]=a;//写入可用块集合
A++;
b++;
}else{
a=i*16+j;//得到相对块号
used[c]=a;
H++;
c++;//写入不可用块号 集合
}
}
}
public void allrec(){//全部收回
ta.setText("");
String str= "收回结果:\n";
for(int i=0;i<H;i++) {
int a = used[i]/16;
int b = used[i]%16/4;
int c = used[i]%16%4;
data[a][4*b+c]="0";
table.setValueAt("0",a,4*b+c);//位示图相应位置零
str+="柱面"+a+"--磁道"+b+"--扇区"+c+"--盘块号"+used[i]+"\n";
used[i]=0;//位示图相应位置置零
}
for(int i=0;i<30;i++)
for(int j=0;j<16;j++)
{
table.setValueAt("0",i,j);
}
H=0;
getavail();
ta.append(str);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==b1) {
init();
getavail();
String str6=""+A;
ta.append("初始化完成\n");
tf3.setText(str6);
}
else if(e.getSource()==b2) {
if(A==480) {
ta.setText("");
String str7="没有资源可回收";
ta.append(str7);
}else {
allrec();
}
String str8=""+A;
tf3.setText(str8);
}
else if(e.getSource()==b3) {
int n;
System.out.println(tf1.getText());
n=Integer.parseInt(tf1.getText());
tf1.setText("");
if(A<n) {
ta.setText("");
String str1="空闲块不足";
ta. append(str1);
JOptionPane.showMessageDialog(null, "空闲块不足","提示",JOptionPane.PLAIN_MESSAGE);
return;
}
else {
int j,k;
ta.setText("");
String str= "分配结果\n" ;
int x=H;
for(int i=0;i<n;i++) {
j = sp[1]/16;
k = sp[1]-j*16;
used[x+1]=sp[1];//可用块相对地址转为已用块相对地址
data[j][k]="1";
table. setValueAt("1",j,k);//将位示图对应位置写1
str+="桂面"+sp[i]/16+"--磁道"+(sp[i]%16)/4+"-- 扇区"+(sp[i]%16)%4+"--盘块号: "+sp[i]+" \n";
A--;
H++;
}
for(int t=0;t<A;t++) {
sp[t]=sp[t+n];//删除可用块中的已用块
}
ta. append(str);
}
String str2=""+A;
tf3.setText(str2);
tf1. setText("");
}
else if(e. getSource()==b4) {
int num;
num=Integer.parseInt(tf2.getText());
ta.setText("");
String str="";
int j,k=0;
int a=num/16;//柱面
int b=num%16/4;//磁道
int c=num%16%4;//扇区
if(data[a][4*b+c].equals("0")){
JOptionPane.showInternalMessageDialog(null, "不可回收空闲块","提示",JOptionPane.PLAIN_MESSAGE);
//tf2.setText(" ");
System.out.println("不可回收");
return;
}else {
data[a][4*b+c]="0";
table.setValueAt("0",a,4*b+c);
str+="柱面"+a+"磁道"+b+"扇区"+c+"盘快号"+num+"\n";
A++;
H--;
for(int i=0;i<H;i++) {
if(used[i]==num) {
k=i;
break;
}
}
for( j=k;j<H;j++)
{
used[j]=used[j+1];//将回收的块号从以用中删除
ta.append("回收结果:\n");
ta.append(str);
}
}
getavail();
String str5=""+A;
tf3.setText(str5);
tf2.setText("");
}
}
}