コード例 #1
0
        public void Test()
        {
            var matrixField = new MatrixField(new int[, ]
            {
                { 0, 0, 1 },
                { 1, 1, 1 },
                { 1, 2, 3 }
            });

            var inverseRuben = matrixField.InverseRuben();
            var inverse      = matrixField.Inverse;

            Assert.Equal(inverse, inverseRuben);
        }
コード例 #2
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);
        }