public static void AssignFrom <T>(this IOutStream <T> outStream, IEnumerable <T> source) { using (var writer = outStream.GetDynamicWriter()) foreach (var entry in source) { writer.Write(entry); } }
public void Evaluate(int spreadMax) { // Should any of the inputs do not have any data exit early if (spreadMax == 0) { LeftOutStream.Length = 0; RightOutStream.Length = 0; return; } // In case nothing changed also do an early exit - important if T is a string or a reference type if (!InputStream.IsChanged && !IndexStream.IsChanged) { return; } // Grab buffers and reader/writer using (var buffer = MemoryPool <T> .GetBuffer()) using (var reader = InputStream.GetReader()) using (var leftWriter = LeftOutStream.GetDynamicWriter()) using (var rightWriter = RightOutStream.GetDynamicWriter()) { foreach (var index in IndexStream) { // Set reader to its initial position reader.Position = 0; // Write everything up to the given index to the left output int numSlicesToRead; // split at 0 could mean all to the left or all to the right // for now let's put all to the right if (index >= 0) { numSlicesToRead = Math.Min(index, InputStream.Length); } else { numSlicesToRead = Math.Max(InputStream.Length + index, 0); } while (numSlicesToRead > 0) { var numSlicesREAD = reader.Read(buffer, 0, Math.Min(numSlicesToRead, buffer.Length)); leftWriter.Write(buffer, 0, numSlicesREAD); numSlicesToRead -= numSlicesREAD; } // Write whatever remains to the right output while (!reader.Eos) { var numSlicesRead = reader.Read(buffer, 0, buffer.Length); rightWriter.Write(buffer, 0, numSlicesRead); } } } }
#pragma warning restore #endregion fields & pins //called when data for any output pin is requested public void Evaluate(int SpreadMax) { FInput.Sync(); FVec.Sync(); FBin.Sync(); FSelect.Sync(); if (FInput.IsChanged || FVec.IsChanged || FBin.IsChanged || FSelect.IsChanged) { if (FInput.Length > 0 && FVec.Length > 0 && FBin.Length > 0 && FSelect.Length > 0) { int vecSize = Math.Max(1, FVec.GetReader().Read()); spread.Sync(FInput, vecSize, FBin, FSelect.Length); using (var selReader = FSelect.GetCyclicReader()) using (var outputWriter = FOutput.GetDynamicWriter()) using (var formerIdWriter = FFormer.GetDynamicWriter()) { int offset = 0; for (int b = 0; b < spread.Count; b++) { var data = spread[b]; int binSize = data.Length / vecSize; int sel = selReader.Read(); if (sel > 0 && binSize > 0) { int[] ids = new int[binSize]; for (int i = 0; i < binSize; i++) { ids[i] = offset + i; } for (int s = 0; s < sel; s++) { outputWriter.Write(data, 0, data.Length); formerIdWriter.Write(ids, 0, ids.Length); } } offset += binSize; } } } else { FOutput.Length = FFormer.Length = 0; } } }
public void Evaluate(int spreadMax) { // Check if any inputs changed (important for string) if (!StreamUtils.AnyChanged(FDataIn, FSelectIn)) { return; } spreadMax = StreamUtils.GetSpreadMax(FDataIn, FSelectIn); // Early exit if (spreadMax == 0) { FDataOut.Length = 0; FFormerSliceOut.Length = 0; return; } // In case nothing changed also do an early exit - important if T is a string or a reference type if (!FDataIn.IsChanged && !FSelectIn.IsChanged) { return; } // Fetch readers and writers using (var dataReader = FDataIn.GetCyclicReader()) using (var selectReader = FSelectIn.GetCyclicReader()) using (var dataWriter = FDataOut.GetDynamicWriter()) using (var formerSliceWriter = FFormerSliceOut.GetDynamicWriter()) { // Grab buffers from pool var dataInBuffer = MemoryPool <T> .GetArray(); var dataOutBuffer = MemoryPool <T> .GetArray(); var selectBuffer = MemoryPool <int> .GetArray(); var sliceBuffer = MemoryPool <int> .GetArray(); try { var numSlicesToRead = spreadMax; var offset = 0; var formerSlice = 0; while (numSlicesToRead > 0) { var blockSize = Math.Min(StreamUtils.BUFFER_SIZE, numSlicesToRead); dataReader.Read(dataInBuffer, 0, blockSize); selectReader.Read(selectBuffer, 0, blockSize); // This loop iterates through the input data for (int i = 0; i < blockSize; i++) { var data = dataInBuffer[i]; var select = selectBuffer[i]; // This loop replicates the input data on the output select times for (int j = 0; j < select; j++) { // Buffer result data dataOutBuffer[offset] = data; sliceBuffer[offset] = formerSlice; offset++; // Write data out if buffer is full if (offset == StreamUtils.BUFFER_SIZE) { dataWriter.Write(dataOutBuffer, 0, StreamUtils.BUFFER_SIZE); formerSliceWriter.Write(sliceBuffer, 0, StreamUtils.BUFFER_SIZE); offset = 0; } } formerSlice++; } numSlicesToRead -= blockSize; } // Write any buffered output data left if (offset > 0) { dataWriter.Write(dataOutBuffer, 0, offset); formerSliceWriter.Write(sliceBuffer, 0, offset); } } finally { MemoryPool <T> .PutArray(dataInBuffer); MemoryPool <T> .PutArray(dataOutBuffer); MemoryPool <int> .PutArray(selectBuffer); MemoryPool <int> .PutArray(sliceBuffer); } } }