Example #1
0
        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);
        }
Example #2
0
        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 }
            });
        }
Example #3
0
        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);
        }