Пример #1
0
 public Task UpdateParity(bool force, UpdateParityStatus status, CancellationToken token)
 {
     return(Task.Run(() => updateParityAsyncInternal(force, status, token), token));
 }
Пример #2
0
        private void updateParityAsyncInternal(bool force, UpdateParityStatus status, CancellationToken token)
        {
            if (!force && !DataModified && ParityWritten)
            {
                return;
            }

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

            using (var p = new Parity(dataClustersPerTrack, parityClustersPerTrack, bytesPerCluster / 2)) {
                int    codewordExponent = dataClustersPerTrack + parityClustersPerTrack - 1;
                byte[] emptyCluster     = null;
                int    clustersComplete = -1;
                foreach (var absoluteClusterNumber in DataClusters)
                {
                    ClusterState state = _fileSystem.GetClusterState(absoluteClusterNumber);
                    if (!state.IsSystem())
                    {
                        if ((state & ClusterState.Unwritten) != 0)
                        {
                            if (emptyCluster == null)
                            {
                                EmptyCluster c = new EmptyCluster(absoluteClusterNumber);
                                _fileSystem.ClusterIO.Save(c);
                                emptyCluster = new byte[bytesPerCluster];
                                c.Save(emptyCluster, 0);
                            }
                            p.Calculate(emptyCluster, 0, codewordExponent);
                            state &= ~ClusterState.Unwritten;
                            _fileSystem.SetClusterState(absoluteClusterNumber, state);
                        }
                        else
                        {
                            Cluster c = new Cluster(absoluteClusterNumber, bytesPerCluster);
                            _fileSystem.ClusterIO.Load(c);
                            byte[] bytes = new byte[bytesPerCluster];
                            c.Save(bytes, 0);
                            p.Calculate(bytes, 0, codewordExponent);
                        }
                    }

                    clustersComplete++;
                    status.Cluster = clustersComplete;
                    codewordExponent--;
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                }

                for (int i = 0; i < parityClustersPerTrack; i++)
                {
                    ParityCluster c     = new ParityCluster(_fileSystem.BlockSize, _trackNumber, i);
                    byte[]        bytes = new byte[bytesPerCluster];
                    p.GetParity(bytes, 0, parityClustersPerTrack - 1 - i);
                    c.Data.Set(0, bytes);
                    _fileSystem.ClusterIO.Save(c);
                    _fileSystem.SetClusterState(c.ClusterAddress, ClusterState.Parity);

                    clustersComplete++;
                    status.Cluster = clustersComplete;
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                }
            }

            // Update states after the parity is modified in case there is an error
            foreach (var i in DataClusters)
            {
                ClusterState state = _fileSystem.GetClusterState(i) & (~ClusterState.Modified);
                _fileSystem.SetClusterState(i, state);
            }
            _fileSystem.Flush();
        }