コード例 #1
0
        /// <summary>
        /// Segment - sequence of stripes that is a multiple of (NumberOfColumns - 1),
        /// and every (NumberOfColumns - 1) stripes in the sequence have the same stripeIndexInColumn
        /// (Such sequence can be written to disk without reading the parity information first)
        /// </summary>
        public static void WriteSegment(Raid5Volume volume, DynamicDiskExtent newExtent, long firstStripeIndexInColumn, byte[] data)
        {
            List <DynamicColumn> newArray = new List <DynamicColumn>();

            newArray.AddRange(volume.Columns);
            newArray.Add(new DynamicColumn(newExtent));

            int bytesPerStripe = volume.BytesPerStripe;

            int stripesToWritePerColumn = (data.Length / bytesPerStripe) / (newArray.Count - 1);

            int dataLengthPerColumn = stripesToWritePerColumn * bytesPerStripe;

            byte[][] columnData = new byte[newArray.Count][];
            for (int index = 0; index < columnData.Length; index++)
            {
                columnData[index] = new byte[dataLengthPerColumn];
            }

            Parallel.For(0, stripesToWritePerColumn, delegate(int stripeOffsetInColumn)
            {
                long stripeIndexInColumn = firstStripeIndexInColumn + stripeOffsetInColumn;
                int parityColumnIndex    = (newArray.Count - 1) - (int)(stripeIndexInColumn % newArray.Count);

                byte[] parityData = new byte[bytesPerStripe];
                for (int stripeVerticalIndex = 0; stripeVerticalIndex < newArray.Count - 1; stripeVerticalIndex++)
                {
                    int columnIndex = (parityColumnIndex + 1 + stripeVerticalIndex) % newArray.Count;

                    long stripeOffsetInData = (stripeOffsetInColumn * (newArray.Count - 1) + stripeVerticalIndex) * bytesPerStripe;
#warning long array index
                    Array.Copy(data, (int)stripeOffsetInData, columnData[columnIndex], stripeOffsetInColumn * bytesPerStripe, bytesPerStripe);

                    parityData = Raid5Volume.XOR(parityData, columnData[columnIndex], stripeOffsetInColumn * bytesPerStripe, bytesPerStripe);
                }
                Array.Copy(parityData, 0, columnData[parityColumnIndex], stripeOffsetInColumn * bytesPerStripe, bytesPerStripe);
            });

            // write the data
            long firstSectorIndexInColumn = firstStripeIndexInColumn * volume.SectorsPerStripe;
            for (int columnIndex = 0; columnIndex < newArray.Count; columnIndex++)
            {
                newArray[columnIndex].WriteSectors(firstSectorIndexInColumn, columnData[columnIndex]);
            }
        }