public static List <Block <byte> > GenerateParityData(List <Block <byte> > dataBlocks, int parityBlockCount) { int dataLengthInsideBlock = dataBlocks.First().Data.Length; var parityMatrix = CreateParityOnlyMatrix(dataBlocks, parityBlockCount); var parityDataList = new List <Block <byte> >(); for (int i = 0; i < parityBlockCount; i++) { parityDataList.Add(new Block <byte>() { Data = new byte[dataLengthInsideBlock] }); } for (int i = 0; i < dataLengthInsideBlock; i++) { var data = new List <Field>(); foreach (var dataBlock in dataBlocks) { data.Add(new Field(dataBlock.Data[i])); } var toArray = data.ToArray(); var vector = new CoolVectorField(toArray); var parityData = parityMatrix * vector; for (int y = 0; y < parityDataList.Count; y++) { parityDataList[y].Data[i] = parityData.Data[y].Value; } } return(parityDataList); }
public static void GoParStuff() { //usage example Field f1 = new Field(15); Field f2 = new Field(8); Field f3 = f1 + f2; Console.WriteLine(f3); var f4 = f3 - f2; Console.WriteLine(f4); //var v1 = new CoolVector(1, 2, 3); //var v2 = new CoolVector(2, 1, 3); //var ar2 = new int[,] { // { 1, 2, 3 }, // { 4, 5, 6 }, // { 7, 8, 9 } //}; //var matrix = new Matrix(ar2); //var matrix2 = new Matrix(new int[,] { // { 2 }, // { 1 }, // { 3 } //}); //var result = matrix * v2; //Console.WriteLine(result); //var result2 = matrix * matrix2; //Console.WriteLine(result2); // 10 // 3 var ar1 = new int[, ] { { 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1 }, { 1, 2, 3, 4, 5 } }; var matrixField = new MatrixField(ar1); var dataForField = new MatrixField(new int[, ] { { 10 }, { 5 }, { 8 }, { 13 }, { 2 } }); var dataForField2 = new CoolVectorField( 10, 5, 8, 13, 2 ); var result3 = matrixField * dataForField2; Console.WriteLine(result3); int parityBlocks = 2; var data = new List <Block <byte> >() { new Block <byte>() { Data = new byte[] { 10 } }, new Block <byte>() { Data = new byte[] { 5 } }, new Block <byte>() { Data = new byte[] { 8 } }, new Block <byte>() { Data = new byte[] { 13 } }, new Block <byte>() { Data = new byte[] { 2 } }, }; var parMatrix = ParityAlgorithm.CreateParityMatrix(data, parityBlocks); var parMatrixOnly = ParityAlgorithm.CreateParityOnlyMatrix(data, parityBlocks); Console.WriteLine(); Console.Write(parMatrix); Console.WriteLine(); Console.Write(parMatrixOnly); var recoveryData = ParityAlgorithm.GenerateParityData(data, parityBlocks); Console.WriteLine(string.Join(Environment.NewLine, recoveryData.Select(t => string.Join(",", t.Data)))); //var totalData = data.Concat(recoveryData).ToList(); //data[0].Data = null; data[1].Data = null; //data[2].Data = null; //data[3].Data = null; //data[4].Data = null; //recoveryData[0].Data = null; recoveryData[1].Data = null; ParityAlgorithm.RecoverData(data, recoveryData, parityBlocks); //ParityAlgorithm.RecoverDataV2(data, recoveryData, parityBlocks); var missing = new MatrixField(new int[, ] { { 1 }, { 1 }, { 1 }, { 1 }, { 1 }, { 1 }, { 1 } }); }
public static List <Block <byte> > RecoverData(List <Block <byte> > dataBlocks, List <Block <byte> > recoveryBlocks, int parityBlockCount) { var combinedData = dataBlocks.Concat(recoveryBlocks).ToList(); var combinedDataWithoutMissingData = combinedData.Where(t => t.Data != null).ToList(); int dataLengthInsideBlock = combinedData.First(t => t.Data != null).Data.Length; var parMatrix = ParityAlgorithm.CreateParityMatrix(dataBlocks, parityBlockCount); //var parMatrixOnly = ParityAlgorithm.CreateParityOnlyMatrix(dataBlocks, parityBlockCount); var missingDataElements = new List <int>(); var missingRows = new List <Field[]>(); var nonMissingRows = new List <Field[]>(); for (int i = 0; i < combinedData.Count; i++) { var dataBlock = combinedData[i]; if (dataBlock.Data == null) { missingDataElements.Add(i); missingRows.Add(parMatrix.Array[i]); } else { nonMissingRows.Add(parMatrix.Array[i]); } } if (missingDataElements.Count > parityBlockCount) { throw new InvalidOperationException("Can't recover this data as too much blocks are damaged"); } //var subspace = new MatrixField(new int[,] { // { 0, 0, 1, 0, 0 }, // { 0, 0, 0, 1, 0 }, // }); //If there's more repair data then we need, from all the blocks, just take the amount of data blocks var rowsNeeded = nonMissingRows.Take(dataBlocks.Count).ToArray(); var subspace = new MatrixField(rowsNeeded); Console.WriteLine($"Subspace:\n\r{subspace}"); var inverse = subspace.InverseRuben(); var inverse2 = subspace.Inverse; Console.WriteLine($"Inverse:\n\r{inverse}"); if (inverse2 != inverse) { Console.WriteLine("NU"); } foreach (var dataBlock in dataBlocks) { if (dataBlock.Data == null) { dataBlock.Data = new byte[dataLengthInsideBlock]; } } for (int i = 0; i < dataLengthInsideBlock; i++) { var data = new List <Field>(); //If there's more repair data then we need, from all the blocks, just take the amount of data blocks foreach (var dataBlock in combinedDataWithoutMissingData.Take(dataBlocks.Count)) { data.Add(new Field(dataBlock.Data[i])); } var toArray = data.ToArray(); var vector = new CoolVectorField(toArray); var res = inverse * vector; //Console.WriteLine($"Recovered data:\n\r{res}"); for (int y = 0; y < res.Length; y++) { dataBlocks[y].Data[i] = res.Data[y].Value; } } return(dataBlocks); }