/// <summary> /// Repair the broken streams specified in the array, needs originalParityCount and reparationIndizes. /// </summary> /// <param name="streams">Streams with equal sizes.</param> /// <param name="originalParityCount">Original parity count.</param> /// <param name="reparationIndizes">Reparation indizes.</param> public static void Repair(Stream[] streams, int originalParityCount, byte[] reparationIndizes) { int allCount = streams.Length; int parityCount = originalParityCount; ECC.ReedSolomon rs = new ECC.ReedSolomon(parityCount); rs.CacheQ(allCount, reparationIndizes); long streamLength = streams[0].Length; Parallel.For(0, (int)Math.Ceiling((double)streamLength / (double)maxBufferSize), iii => { int bufferSize = maxBufferSize; if (streamLength - iii * maxBufferSize < bufferSize) { bufferSize = (int)(streamLength - iii * maxBufferSize); } byte[][] buffers = new byte[streams.Length][]; for (int i = 0; i < streams.Length; i++) { buffers[i] = new byte[bufferSize]; lock (streams[i]) { streams[i].Position = iii * maxBufferSize; streams[i].Read(buffers[i], 0, buffers[i].Length); } } #region COMMENTED faster? /* * for (int i = 0; i < streams.Length; i++) * { * buffers[i] = new byte[bufferSize]; * * //bool doIt = true; * for(int j = 0; j<reparationIndizes.Length; j++){ * if(reparationIndizes[j] == i) * { * goto supercontinue; * //doIt = false; * //break; * } * } * //if(!doIt){ * // continue; * //} * lock(streams[i]){ * streams[i].Position = iii * maxBufferSize; * streams[i].Read(buffers[i], 0, buffers[i].Length); * } * supercontinue:; * * } */ #endregion byte[][] outbuf = new byte[bufferSize][]; for (int i = 0; i < bufferSize; i++) { byte[] msg = new byte[allCount]; for (int j = 0; j < allCount; j++) { msg[j] = buffers[j][i]; } rs.Decode(msg, reparationIndizes, true); outbuf[i] = msg; } byte[][] outbuf2 = new byte[allCount][]; for (int i = 0; i < allCount; i++) { outbuf2[i] = new byte[bufferSize]; } for (int i = 0; i < bufferSize; i++) { for (int j = 0; j < allCount; j++) { outbuf2[j][i] = outbuf[i][j]; } } for (int r = 0; r < reparationIndizes.Length; r++) { int i = reparationIndizes[r]; lock (streams[i]) { streams[i].Position = iii * maxBufferSize; streams[i].Write(outbuf2[i], 0, outbuf2[i].Length); } } } ); }