00001
00002
00003
00004
00005 #include <iostream>
00006 #include <stdlib.h>
00007 #include <sys/time.h>
00008
00009 #define P(X) do { std::cerr << #X"=" << X << std::endl; std::cerr.flush(); } while(0)
00010
00011 const int gMaxErrors = 4;
00012
00013 class ECorrSimulator
00014 {
00015 public:
00016 int numBlocks;
00017 int numErrors;
00018 bool *pBlockFaults;
00019
00020 ECorrSimulator(const int blocks, int errors)
00021 {
00022 numBlocks = blocks;
00023 numErrors = errors;
00024 pBlockFaults = new bool[blocks];
00025 int i;
00026 for (i=0; i<blocks; ++i) pBlockFaults[i]=false;
00027 while ( errors > 0 ) {
00028 int rblk = random()%blocks;
00029 if (!pBlockFaults[rblk]) {
00030 pBlockFaults[rblk]=true;
00031 --errors;
00032 }
00033 }
00034 }
00035
00036 ~ECorrSimulator() { delete pBlockFaults; }
00037
00038 bool hasErrors() { return numErrors > 0; }
00039
00040
00041
00042
00043 bool stripeCorrect(const int stripeSkip, const int stripeLen)
00044 {
00045 bool haveCorrected=false;
00046 int pos=0, next_pos=-1, checkedBlocks=0, i;
00047 while ( checkedBlocks < numBlocks ) {
00048 next_pos=pos;
00049 int error_count=0;
00050 for (i=0; i<stripeLen; ++i) {
00051 if (pBlockFaults[next_pos]) ++error_count;
00052 next_pos = (next_pos + stripeSkip) % numBlocks;
00053 ++checkedBlocks;
00054 }
00055 if ( (0<error_count) && (error_count<gMaxErrors) ) {
00056
00057 numErrors -= error_count;
00058 next_pos=pos;
00059 for (i=0; i<stripeLen; ++i) {
00060 pBlockFaults[next_pos] = false;
00061 next_pos = (next_pos + stripeSkip) % numBlocks;
00062 }
00063 haveCorrected = true;
00064 }
00065 pos=next_pos;
00066 }
00067 return haveCorrected;
00068 }
00069
00070
00071
00072 void doubleStripeCorrect(const int stripeLen) {
00073 bool changes=true;
00074 while (changes) {
00075 changes = stripeCorrect(5,stripeLen);
00076 changes = changes || stripeCorrect(7,stripeLen);
00077 }
00078 }
00079 };
00080
00081 double probCorr(const int numBlocks, const int numErrors, const int stripeLen)
00082 {
00083 const int n=numBlocks/stripeLen;
00084 P(exp(-n*pow(numErrors*1.0/n,3.8)/45));
00085 int i, cntErr=0;
00086 for (i=0; i<1000; ++i) {
00087 ECorrSimulator sim(numBlocks, numErrors);
00088 sim.stripeCorrect(3,stripeLen);
00089 if (sim.hasErrors()) ++cntErr;
00090 }
00091 return 1-double(cntErr)/i;
00092 }
00093
00094 double probDoubleCorr(const int numBlocks, const int numErrors, const int stripeLen)
00095 {
00096 int i, cntErr=0;
00097 for (i=0; i<1000; ++i) {
00098 ECorrSimulator sim(numBlocks, numErrors);
00099 sim.doubleStripeCorrect(stripeLen);
00100 if (sim.hasErrors()) ++cntErr;
00101 }
00102 return 1-double(cntErr)/i;
00103 }
00104
00105 int main()
00106 {
00107 struct timeval tv; gettimeofday(&tv,NULL);
00108 srandom(tv.tv_sec-tv.tv_usec);
00109
00110 P(probCorr(100000,320,100));
00111 P(probCorr(100000,320,249));
00112 P(probCorr(10000,50,100));
00113 P(probDoubleCorr(10000,50,100));
00114 P(probDoubleCorr(10000,50,200));
00115 P(probCorr(20000,100,100));
00116 P(probCorr(10000,40,200));
00117 P(probCorr(1250000,100,100));
00118 P(probCorr(1250000,200,100));
00119 P(probCorr(1250000,500,100));
00120 P(probCorr(1250000,1000,100));
00121 P(probCorr(1250000,2000,100));
00122 P(probCorr(1250000,3000,100));
00123 P(probCorr(1250000,4000,100));
00124 P(probCorr(1250000,5000,100));
00125 P(probCorr(1250000,10000,100));
00126 P(probCorr(1250000,20000,100));
00127 int num_blocks=100000;
00128 int hysiz=100;
00129 double num_errs=40;
00130 double prob=1;
00131 while (prob>0.1) {
00132 prob = probCorr(num_blocks, int(num_errs), hysiz);
00133 std::cout << int(num_errs) << "\t" << 1-prob << "\n";
00134 std::cout.flush();
00135 num_errs = num_errs*pow(2.0,1.0/3);
00136 }
00137 return 0;
00138 }