Пример #1
0
        private void Run()
        {
            var cluster = 0;

            foreach (var clusterPoint in _dataSet)
            {
                if (clusterPoint.Visited)
                {
                    continue;
                }

                clusterPoint.Visited = true;
                var neighbours = RegionQuery(clusterPoint.Vector);

                if (neighbours.Count < _minPoints)
                {
                    clusterPoint.Noise = true;
                }
                else
                {
                    cluster++;
                    ExpandCluster(clusterPoint, neighbours, cluster);
                }
            }

            foreach (var clust in _dataSet.Where(x => !x.Noise).GroupBy(x => x.Cluster))
            {
                var vectors = clust.Select(x => x.Vector);
                DataClusters.Add(clust.Key, vectors);
            }
        }
Пример #2
0
        public bool Repair()
        {
            // We need to enforce that hashes and signatures are checked (what happens if signatures aren't?  What is not protected?  What happens?
            if (DataModified || !ParityWritten)
            {
                return(false);
            }

            int dataClustersPerTrack   = Configuration.Geometry.DataClustersPerTrack;
            int parityClustersPerTrack = Configuration.Geometry.ParityClustersPerTrack;
            int bytesPerCluster        = Configuration.Geometry.BytesPerCluster;

            List <int> errorExponents = new List <int>();

            using (var p = new Syndrome(dataClustersPerTrack, parityClustersPerTrack, bytesPerCluster / 2)) {
                int codewordExponent = dataClustersPerTrack + parityClustersPerTrack - 1;
                foreach (var absoluteClusterNumber in DataClusters)
                {
                    if (!_fileSystem.GetClusterState(absoluteClusterNumber).IsSystem())
                    {
                        Cluster c = new Cluster(absoluteClusterNumber, bytesPerCluster);
                        Console.WriteLine($"Loading cluster {absoluteClusterNumber}");
                        try {
                            _fileSystem.ClusterIO.Load(c);
                            byte[] bytes = new byte[bytesPerCluster];
                            c.Save(bytes, 0);
                            p.AddCodewordSlice(bytes, 0, codewordExponent);
                        } catch (System.IO.IOException) {
                            // We need to catch something specific to a hash failure or something.  Or force no auto check, then check manually.
                            Console.WriteLine($"Error in data cluster {absoluteClusterNumber}");
                            errorExponents.Add(codewordExponent);
                        }
                    }
                    codewordExponent--;
                }

                int parityNumber = 0;
                foreach (var absoluteClusterNumber in ParityClusters)
                {
                    ParityCluster c = new ParityCluster(_fileSystem.BlockSize, _trackNumber, parityNumber);
                    Console.WriteLine($"Loading parity cluster {absoluteClusterNumber}");
                    try {
                        _fileSystem.ClusterIO.Load(c);
                        byte[] bytes = c.Data.ToByteArray(0, bytesPerCluster);
                        p.AddCodewordSlice(bytes, 0, codewordExponent);
                    } catch (System.IO.IOException) {
                        Console.WriteLine($"Error in parity cluster {absoluteClusterNumber}");
                        errorExponents.Add(codewordExponent);
                    }
                    codewordExponent--;
                    parityNumber++;
                }

                if (errorExponents.Count == 0)
                {
                    byte[] values = new byte[bytesPerCluster];
                    for (int i = 0; i < parityClustersPerTrack; i++)
                    {
                        p.GetSyndromeSlice(values, 0, i);
                        for (int j = 0; j < bytesPerCluster; j++)
                        {
                            if (values[j] != 0)
                            {
                                return(false);
                            }
                        }
                    }
                    return(true);
                }
                else
                {
                    // Throw an exception or specify the error somehow
                    if (errorExponents.Count > parityClustersPerTrack)
                    {
                        return(false);
                    }

                    using (var r = new Repair(p, dataClustersPerTrack + parityClustersPerTrack, errorExponents)) {
                        byte[] bytes        = new byte[bytesPerCluster];
                        int[]  dataClusters = DataClusters.ToArray();
                        int    index        = 0;
                        foreach (var e in errorExponents)
                        {
                            r.Correction(index++, bytes, 0);
                            if (e < parityClustersPerTrack)
                            {
                                // it is a parity cluster
                                ParityCluster c = new ParityCluster(_fileSystem.BlockSize, _trackNumber, parityClustersPerTrack - 1 - e);
                                c.Data.Set(0, bytes);
                                Console.WriteLine($"Repairing parity {c.ClusterAddress} at {c.AbsoluteAddress}");
                                _fileSystem.ClusterIO.Save(c);
                            }
                            else
                            {
                                // Need to do this without creating a cluster, since that will change the signature
                                int     i = dataClustersPerTrack + parityClustersPerTrack - 1 - e;
                                Cluster c = new Cluster(dataClusters[i], bytesPerCluster);
                                c.Load(bytes, 0);
                                Console.WriteLine($"Repairing data {c.ClusterAddress} at {c.AbsoluteAddress}");
                                _fileSystem.ClusterIO.Save(c);
                            }
                        }
                    }

                    return(true);
                }
            }
        }