public static bool FastEquals <T>(this ReadOnlySpan <T> left, ReadOnlySpan <T> right) where T : unmanaged => FastCompare.Equals(left, right);
/// <summary> /// Copies a <paramref name="source"/> file to a <paramref name="destination"/> splitting it into segments each sized <paramref name="splitSize"/> /// </summary> /// <param name="source">Source <see cref="FileInfo"/> to copy</param> /// <param name="destination">Destination <see cref="FileInfo"/> to copy to</param> /// <param name="splitSize">Size of split segments</param> /// <param name="onWrite">Action will be called everytime theres an advance in bytes with the number of bytes as parameter, to track progress. Can be null.</param> public static void Copy(FileInfo source, FileInfo destination, long splitSize, Action <long>?onWrite = null) { var sourceSplit = new SplitFile(source, splitSize); var destSplit = new SplitFile(destination, splitSize); int bound; if (sourceSplit.SplitInfos.Length > destSplit.SplitInfos.Length) { // If source is bigger than destination copy from source at last destination pos to end bound = destSplit.SplitInfos.Length; SplitInfo infoSource = sourceSplit.SplitInfos[bound]; using var sourceStream = new FileStream(sourceSplit.File.FullName, FileMode.Open, FileAccess.Read, FileShare.Read); using var destStream = new FileStream(destSplit.File.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); sourceStream.Position = infoSource.StartIndex; destStream.Position = infoSource.StartIndex; int len = (int)(source.Length - infoSource.StartIndex); StreamCopy(sourceStream, destStream, len, onWrite); } else if (sourceSplit.SplitInfos.Length < destSplit.SplitInfos.Length || sourceSplit.SplitInfos[^ 1].Length < destSplit.SplitInfos[^ 1].Length) { // If destination is bigger than source throw away the diff at the end (set length of dest to src) bound = sourceSplit.SplitInfos.Length; using var destStream = new FileStream(destSplit.File.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); destStream.SetLength(source.Length); } else { // they are the same length w/e bound = sourceSplit.SplitInfos.Length; } // loop to bound, check each split for equality and copy over if needed Parallel.For(0, bound, (i) => { SplitInfo infoSource = sourceSplit.SplitInfos[i]; SplitInfo infoDest = destSplit.SplitInfos[i]; using var sourceStream = new FileStream(sourceSplit.File.FullName, FileMode.Open, FileAccess.Read, FileShare.Read); using var destStream = new FileStream(destSplit.File.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); sourceStream.Position = infoSource.StartIndex; destStream.Position = infoSource.StartIndex; // if they are not the same length or not equal copy from src if (infoSource.Length != infoDest.Length || !FastCompare.Equals(sourceStream, destStream, infoSource.Length)) { sourceStream.Position = infoSource.StartIndex; destStream.Position = infoSource.StartIndex; StreamCopy(sourceStream, destStream, infoSource.Length, onWrite); } else { onWrite?.Invoke(infoSource.Length); } }); }
private static void AssertEqual(Stream left, Stream right, int len) => Assert.IsTrue(FastCompare.Equals(left, right, len));
public static bool FastEquals <T>(this T[] left, T[] right) where T : unmanaged => FastCompare.Equals(left, right);