UVA 509 RAID! (模拟)
509 RAID技术
RAID (Redundant Array of Inexpensive Disks) is a technique which uses multiple disks to store data.
磁盘阵列技术是一种使用多磁盘存储数据的技术
By storing the data on more than one disk, RAID is more fault tolerant than storing data on a single disk.
通过在多个磁盘上存储数据,RAID技术相比在单一磁盘上存储数据有着更好的容错。
If there is a problem with one of the disks, the system can still recover the original data provided that the remaining disks do not have corresponding problems.
如果其中一个磁盘出错,系统仍然能够通过剩下的没有被影响的磁盘恢复数据
One approach to RAID breaks data into blocks and stores these blocks on all but one of the disks.
RAID的一种方式就是把数据切分成块,放在一个一个的磁盘中
The remaining disk is used to store the [parity information] for the data blocks.
多出来的磁盘用来存储数据块的[奇偶校验信息]
This scheme uses vertical parity in which bits in a given position in data blocks
are exclusive ORed to form the corresponding parity bit.
这个方案使用竖直排列奇偶校验,
The parity block moves between the disks, starting at the first disk, and moving
to the next one in order.
这个奇偶校验块夹在磁盘中间,从第一个磁盘开始,下一次放到相邻的另一块。
For instance, if there were five disks and 28 data blocks were stored on them,
they would be arranged as follows:
例如如果有5个磁盘和28个数据块存储在5个磁盘上,他们会按照以下方式排列:
Disk 1 Disk 2 Disk 3 Disk 4 Disk 5
Parityfor 1-4 Data block 1 Data block 2 Data block 3 Data block 4
Datablock 5 Parity for 5-8 Datablock 6 Data block 7 Data block 8
Datablock 9 Datablock 10 Parityfor 9-12 Datablock 11 Datablock 12
Datablock 13 Datablock 14 Datablock 15 Parityfor13-16 Datablock 16
Datablock17 Datablock18 Datablock19 Datablock20 Parityfor 17-20
Parityfor 21-24 Data block 21 Data block 22 Data block 23 Data block 24
Data block 25 Parity for 25-28 Data block 26 Data block 27 Data block 28
With this arrangement of disks, a block size of two bits and even parity, the
hexadecimal sample data 6C7A79EDFC (01101100 01111010 01111001 11101101 11111100
in binary) would be stored as://忽略奇偶校验位
Disk 1 Disk 2 Disk 3 Disk 4 Disk 5
00 01 10 11 00
01 10 11 10 10
01 11 01 10 01
11 10 11 11 01
11 11 11 00 11
If a block becomes unavailable, its information can still be retrieved using the
information on the other disks.
如果一个块没用了,他的信息能够通过存储在其他盘上的数据中读取
For example, if the first bit of the first block of disk 3 becomes unavailable,
it can be reconstructed using the corresponding parity and data bits from the
other four disks.
例如,如果磁盘3的第一个块的第一位不可用了,他能通过相关的奇偶校验和其他四个磁盘的
数据重新构建
We know that
our sample system uses even parity:
我们的样例系统使用偶校验位
0 ⊕ 0⊕? ⊕ 1 ⊕ 0 = 0
So the missing bit must be 1.
An arrangement of disks is invalid if a parity error is detected,
一个磁盘阵列是不可用的:如果一个奇偶校验处错误发生了。
or if any data block cannot be reconstructed because two or more disks are unavailable for that block.
或者任何数据块都不能重新构建,因为有两个或者更多的磁盘关于那个数据块没用了
Write a program to report errors and recover information from RAID disks.
写一个程序报导错误或者恢复磁盘的信息。
Input
输入:
The input consists of several disk sets.
输入几个磁盘集合
Each disk set has 3 parts.
每个磁盘包括三个部分:
The first part of the disk set contains three integers on one line:
第一部分包括三个整数:
the first integer d, 2 ≤ d ≤ 6, is the number of disks, the second integer s, 1 ≤ s ≤ 64, is the size of each block in bits, and the third integer b, 1 ≤ b ≤ 100, is the total number of data and parity blocks on each disk.
第一个整数d , d>=2&&d<=6 表示磁盘的数量
第二个整数s , s>=1&&s<=64 表示每个块的大小(单位是bit)
第三个整数b , b>=1&&b<=100 每个磁盘能够容纳的数据块和奇偶校验块的总量
The second part of the disk set is a single letter on a line,
第二个部分是一个字母
either ‘E’ signifying even parity or ‘O’ signifying odd parity.
E表示偶校验,O表示奇校验.
The third part of the disk set contains d lines, one for each disk, each holding
s × b characters representing the bits on the disk, with the most significant bits
first.
第三个部分包括d行,每一行对应一个磁盘
每行有s*b个字符表示磁盘上的bits
Each bit will be specified as ‘0’ or ‘1’ if it holds valid data, or ‘x’ if that bit is unavailable.
可用的位使用0和1表示,不可用的位使用x表示
The end of input will be a disk set with d = 0.
输入的末尾使用d = 0结束
There will be no other data for this set which should not be processed.
输入都是合法的
Output
输出:
For each disk set in the input, display the number of the set and whether the set
is valid or invalid.
输出这个磁盘集合是否有效
If the set is valid, display the recovered data bits in hexadecimal.
如果这个磁盘集合是有效的,用16进制恢复数据
If necessary, add extra ‘0’ bits at the end of the recovered data so the number of bits is always a multiple of 4. All output shall be appropriately labeled.
如果有必要,0
Sample Input
5 2 5
E
0001011111
0110111011
1011011111
1110101100
0010010111
3 2 5
E
0001111111
0111111011
xx11011111
3 5 1
O
11111
11xxx
x1111
0
Sample Output
Disk set 1 is valid, contents are: 6C7A79EDFC
Disk set 2 is invalid.
Disk set 3 is valid, contents are: FFC
//11111 11111 00 为了变成4的倍数在末尾额外添加0
输入:
磁盘数d,每个块能够存储的位数b,每个磁盘能够存储的块数s
输入每个磁盘存储的数据位(b*s)
输出:
磁盘是否有用
没有输出invalid
有用输出磁盘阵列的16进制表示法
首先判定磁盘阵列是否是有效的
如果无效直接输出
如果有效,恢复数据然后按照16进制的方式输出
判定磁盘是否有效:
1.奇偶校验可能有错
2.如果要恢复的数据多于1个磁盘损坏就是无法恢复的
1^0 = 1
0^0 = 0
1^1 = 0
1^x1^x2^0 = 0
1^1^1^0 = 1
1^1^0^0 = 0
1^0^1^0 = 0
1^0^0^0 = 1
x1 = 1 x2 = 0
x1 = 0 x2 = 1
这样x1和x2就无法唯一确定了
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int d,s,b; char g[12][105][70]; int even;//采用的校验格式 int check(){ //每一行 选定一位 然后所有列进行异或 进行奇偶校验 //1^0=1 0^0=0; int i,k,j,cnt; int temp; int hPro[12][70];//标记第几行第几位是有故障的 memset(hPro,0,sizeof(hPro)); for(i=0;i<b;i++){ for(k=0;k<s;k++){//校验过程中可能遇到损坏,如果有损坏超过两个就可以返回失败了 temp = 0; cnt = 0; for(j=0;j<d;j++){ if(g[i][j][k]=='x'){ hPro[i][k] = 1; cnt++; if(cnt==2) return 1;//同一位出错两次就无法恢复了 }else{ temp = temp^(g[i][j][k]-48); } } if(hPro[i][k]==1) continue;//如果这一位是有故障的,先跳过 if(!(temp==0&&even||temp==1&&!even)) return 2;//就校验位有问题 } } int pos; for(i=0;i<b;i++){ for(k=0;k<s;k++){ if(hPro[i][k]){ temp = 0; for(j=0;j<d;j++){ if(g[i][j][k]=='x'){ pos = j; }else{ temp = temp^(g[i][j][k]-48); } } if(temp==0){ if(even) g[i][pos][k] = '0'; else g[i][pos][k]='1'; }else{ if(even) g[i][pos][k] = '1'; else g[i][pos][k] = '0'; } } } } return 0; } void print(){ int i,j,k; for(i=0;i<b;i++){ for(j=0;j<d;j++){ for(k=0;k<s;k++){ cout<<g[i][j][k]; } cout<<" "; } cout<<endl; } } char conv[17] = "0123456789ABCDEF"; int main() { //#define LOCAL #ifdef LOCAL freopen("in","r",stdin); freopen("out","w",stdout); #endif int i,j,k; int Case = 1; //输入dsb while(cin>>d&&d){ cout<<"Disk set "<<Case++<<" "; cin>>s>>b; //输入校验格式 char c; cin>>c; if(c=='E') even = 1; else even = 0; //输入磁盘阵列 for(j=0;j<d;j++){ for(i=0;i<b;i++){ for(k=0;k<s;k++){ cin>>g[i][j][k]; } } } //print(); int flag = check(); //cout<<flag<<endl; if(flag) cout<<"is invalid."<<endl; else{ cout<<"is valid, contents are: "; int sum; int cnt; //16进制打印 cnt = 0; sum = 0; for(i=0;i<b;i++){ for(j=0;j<d;j++){ //奇偶校验块 i%d if(j==i%d) continue; else{ for(k=0;k<s;k++){ sum = sum*2+(g[i][j][k]-48); //cout<<sum<<endl; cnt++; if(cnt==4){ cout<<conv[sum]; sum = 0; cnt = 0; } } } } } if(cnt==0) ; else{//不够四位需要添加0凑成4位 for(int ff=cnt+1;ff<=4;ff++){ sum = sum*2+0; } cout<<conv[sum]; } cout<<endl; } } return 0; }

浙公网安备 33010602011771号