/// <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]); } }