public override bool Sync() { // Sync source IsChanged = FDataStream.Sync() | FBinSizeStream.Sync(); if (IsChanged) { int dataLength = FDataStream.Length; int binSizeLength = FBinSizeStream.Length; int binSizeSum = 0; foreach (var binSize in FBinSizeStream) { binSizeSum += SpreadUtils.NormalizeBinSize(dataLength, binSize); } int binTimes = SpreadUtils.DivByBinSize(dataLength, binSizeSum); binTimes = binTimes > 0 ? binTimes : 1; Length = binTimes * binSizeLength; var binSizeBuffer = MemoryPool <int> .GetArray(); try { using (var binSizeReader = FBinSizeStream.GetCyclicReader()) { var numSlicesToWrite = Length; var offsetIntoDataStream = 0; while (numSlicesToWrite > 0) { var numSlicesToRead = Math.Min(numSlicesToWrite, binSizeBuffer.Length); binSizeReader.Read(binSizeBuffer, 0, numSlicesToRead); var offset = Length - numSlicesToWrite; for (int i = offset; i < offset + numSlicesToRead; i++) { var binSize = SpreadUtils.NormalizeBinSize(dataLength, binSizeBuffer[i - offset]); var innerStream = this[i] as InnerStream; // Inner stream will use cyclic reader when offset + length > length of data stream. innerStream.Offset = offsetIntoDataStream; innerStream.Length = binSize; offsetIntoDataStream += binSize; } numSlicesToWrite -= numSlicesToRead; } } } finally { MemoryPool <int> .PutArray(binSizeBuffer); } } return(base.Sync()); }
public override bool Sync() { // Sync source IsChanged = FBinSizeStream.Sync() | FDataStream.Sync(); if (IsChanged) { // Normalize bin size and compute sum int dataStreamLength = FDataStream.Length; int binSizeSum = 0; foreach (var binSize in FBinSizeStream) { binSizeSum += SpreadUtils.NormalizeBinSize(dataStreamLength, binSize); } int binTimes = SpreadUtils.DivByBinSize(dataStreamLength, binSizeSum); binTimes = binTimes > 0 ? binTimes : 1; Length = binTimes * FBinSizeStream.Length; using (var binSizeReader = FBinSizeStream.GetCyclicReader()) using (var dataReader = FDataStream.GetCyclicReader()) { for (int i = 0; i < Length; i++) { var spread = Buffer[i]; var stream = spread.Stream; var binSize = SpreadUtils.NormalizeBinSize(dataStreamLength, binSizeReader.Read()); spread.SliceCount = binSize; switch (binSize) { case 0: break; case 1: stream.Buffer[0] = dataReader.Read(); break; default: dataReader.Read(stream.Buffer, 0, binSize); break; } // Mark the stream as changed stream.IsChanged = true; } } } return(base.Sync()); }