예제 #1
0
        public void Evaluate(int SpreadMax)
        {
            FOutputStreams.SetLengthBy(FInputStream);

            var buffer = MemoryPool <T> .GetArray();

            try
            {
                var outputStreamsLength = FOutputStreams.Length;

                using (var reader = FInputStream.GetCyclicReader())
                {
                    int i = 0;
                    foreach (var outputStream in FOutputStreams)
                    {
                        int numSlicesToWrite = Math.Min(outputStream.Length, buffer.Length);

                        reader.Position = i++;
                        using (var writer = outputStream.GetWriter())
                        {
                            while (!writer.Eos)
                            {
                                reader.Read(buffer, 0, numSlicesToWrite, outputStreamsLength);
                                writer.Write(buffer, 0, numSlicesToWrite);
                            }
                        }
                    }
                }
            }
            finally
            {
                MemoryPool <T> .PutArray(buffer);
            }
        }
예제 #2
0
파일: ZipNode.cs 프로젝트: VRaul/vvvv-sdk
        public void Evaluate(int SpreadMax)
        {
            int inputStreamsLength   = FInputStreams.Length;
            int maxInputStreamLength = FInputStreams.GetMaxLength();

            FOutputStream.Length = maxInputStreamLength * inputStreamsLength;

            var buffer = MemoryPool <T> .GetArray();

            try
            {
                using (var writer = FOutputStream.GetWriter())
                {
                    int numSlicesToRead = Math.Min(maxInputStreamLength, buffer.Length);
                    int i = 0;
                    foreach (var inputStream in FInputStreams)
                    {
                        writer.Position = i++;
                        using (var reader = inputStream.GetCyclicReader())
                        {
                            while (!writer.Eos)
                            {
                                reader.Read(buffer, 0, numSlicesToRead);
                                writer.Write(buffer, 0, numSlicesToRead, inputStreamsLength);
                            }
                        }
                    }
                }
            }
            finally
            {
                MemoryPool <T> .PutArray(buffer);
            }
        }
예제 #3
0
        public unsafe void Evaluate(int spreadMax)
        {
            spreadMax = StreamUtils.GetSpreadMax(FInputStreams, FFormats, FByteOrder);
            FOutputStreams.ResizeAndDispose(spreadMax, () => new MemoryStream());
            var inputBuffer = MemoryPool <double> .GetArray();

            try
            {
                using (var inputReader = FInputStreams.GetCyclicReader())
                    using (var formatReader = FFormats.GetCyclicReader())
                        using (var byteOrderReader = FByteOrder.GetCyclicReader())
                        {
                            foreach (MemoryStream outputStream in FOutputStreams)
                            {
                                var inputStream  = inputReader.Read();
                                var formatStream = formatReader.Read();
                                var byteOrder    = byteOrderReader.Read();
                                if (formatStream.Length == 1)
                                {
                                    var format = formatStream.Single();
                                    ConvertAllAtOnce(inputStream, outputStream, inputBuffer, format, byteOrder);
                                }
                                else
                                {
                                    ConvertOneByOne(inputStream, outputStream, formatStream, byteOrder);
                                }
                            }
                        }
                FOutputStreams.Flush(true);
            }
            finally
            {
                MemoryPool <double> .PutArray(inputBuffer);
            }
        }
예제 #4
0
        public void Read(IntPtr pv, int cb, IntPtr pcbRead)
        {
            var buffer = MemoryPool <byte> .GetArray();

            try
            {
                var totalBytesRead = 0;
                while (totalBytesRead < cb)
                {
                    var bytesToRead = Math.Min(buffer.Length, cb - totalBytesRead);
                    var bytesRead   = this.source.Read(buffer, 0, bytesToRead);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    iop.Marshal.Copy(buffer, 0, pv + totalBytesRead, bytesRead);
                    totalBytesRead += bytesRead;
                }
                iop.Marshal.WriteInt32(pcbRead, totalBytesRead);
            }
            finally
            {
                MemoryPool <byte> .PutArray(buffer);
            }
        }
예제 #5
0
파일: Zip.cs 프로젝트: timpernagel/vvvv-sdk
        public void Evaluate(int SpreadMax)
        {
            if (!Prepare())
            {
                return;
            }

            IEnumerable <IInStream <T> > inputStreams;
            int inputStreamsLength;
            var inputStreams_ = FInputContainer.IOObject;

            if (FAllowEmptySpreads)
            {
                inputStreams       = inputStreams_.Where(s => s.Length > 0);
                inputStreamsLength = inputStreams.Count();
            }
            else
            {
                inputStreams       = inputStreams_;
                inputStreamsLength = inputStreams_.Length;
            }
            int maxInputStreamLength = inputStreams.GetMaxLength();

            var outputStream = FOutputContainer.IOObject;

            outputStream.Length = maxInputStreamLength * inputStreamsLength;

            if (outputStream.Length > 0)
            {
                var buffer = MemoryPool <T> .GetArray();

                try
                {
                    using (var writer = outputStream.GetWriter())
                    {
                        int numSlicesToRead = Math.Min(maxInputStreamLength, buffer.Length);
                        int i = 0;
                        foreach (var inputStream in inputStreams)
                        {
                            writer.Position = i++;
                            using (var reader = inputStream.GetCyclicReader())
                            {
                                while (!writer.Eos)
                                {
                                    reader.Read(buffer, 0, numSlicesToRead);
                                    writer.Write(buffer, 0, numSlicesToRead, inputStreamsLength);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    MemoryPool <T> .PutArray(buffer);
                }
            }
        }
예제 #6
0
        public void CopyTo(win32.IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
        {
            if (!this.source.CanRead)
            {
                throw new NotSupportedException("Source stream doesn't support reading.");
            }
            using (var destination = new ComStream(pstm))
            {
                if (!destination.CanWrite)
                {
                    throw new NotSupportedException("Destination stream doesn't support writing.");
                }
                var buffer = MemoryPool <byte> .GetArray();

                try
                {
                    var totalBytesRead    = 0L;
                    var totalBytesWritten = 0L;
                    var chunkLength       = buffer.Length;
                    if (cb < chunkLength)
                    {
                        chunkLength = (int)cb;
                    }
                    while (totalBytesWritten < cb)
                    {
                        // Read
                        var bytesRead = this.source.Read(buffer, 0, chunkLength);
                        if (bytesRead == 0)
                        {
                            break;
                        }
                        totalBytesRead += bytesRead;
                        // Write
                        var previousPosition = destination.Position;
                        destination.Write(buffer, 0, bytesRead);
                        var bytesWritten = destination.Position - previousPosition;
                        if (bytesWritten == 0)
                        {
                            break;
                        }
                        totalBytesWritten += bytesWritten;

                        if (bytesRead != bytesWritten)
                        {
                            break;
                        }
                    }
                    iop.Marshal.WriteInt64(pcbRead, totalBytesRead);
                    iop.Marshal.WriteInt64(pcbWritten, totalBytesWritten);
                }
                finally
                {
                    MemoryPool <byte> .PutArray(buffer);
                }
            }
        }
예제 #7
0
        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());
        }
예제 #8
0
        public void Evaluate(int SpreadMax)
        {
            // Early exit - important for expensive types like strings and streams.
            if (!Prepare())
            {
                return;
            }

            var inputStreams = FInputContainer.IOObject;
            var outputStream = FOutputContainer.IOObject;

            var outputLength = inputStreams.GetLengthSum();

            outputStream.Length         = outputLength;
            FOutputBinSizeStream.Length = inputStreams.Length;

            var buffer = MemoryPool <T> .GetArray();

            try
            {
                using (var writer = outputStream.GetWriter())
                    using (var binSizeWriter = FOutputBinSizeStream.GetWriter())
                    {
                        foreach (var inputStream in inputStreams)
                        {
                            using (var reader = inputStream.GetReader())
                            {
                                var numSlicesToRead = reader.Length;
                                binSizeWriter.Write(numSlicesToRead);
                                if (numSlicesToRead == 1)
                                {
                                    writer.Write(reader.Read());
                                }
                                else
                                {
                                    while (numSlicesToRead > 0)
                                    {
                                        var numSlicesRead = reader.Read(buffer, 0, buffer.Length);
                                        writer.Write(buffer, 0, numSlicesRead);
                                        numSlicesToRead -= numSlicesRead;
                                    }
                                }
                            }
                        }
                    }
            }
            finally
            {
                MemoryPool <T> .PutArray(buffer);
            }
        }
예제 #9
0
        public override bool Sync()
        {
            IsChanged = FInStream.Sync();
            if (IsChanged)
            {
                var buffer = MemoryPool <Matrix4x4> .GetArray();

                try
                {
                    var anySliceChanged = this.Length != FInStream.Length;
                    this.Length = FInStream.Length;

                    using (var reader = FInStream.GetReader())
                        using (var writer = this.GetWriter())
                        {
                            while (!reader.Eos)
                            {
                                var offset        = reader.Position;
                                int numSlicesRead = reader.Read(buffer, 0, buffer.Length);
                                if (!anySliceChanged)
                                {
                                    for (int i = 0; i < numSlicesRead; i++)
                                    {
                                        var previousSlice = this.Buffer[offset + i];
                                        var newSlice      = buffer[i];
                                        if (newSlice != previousSlice)
                                        {
                                            anySliceChanged = true;
                                            break;
                                        }
                                    }
                                }
                                writer.Write(buffer, 0, numSlicesRead);
                            }
                        }

                    IsChanged = anySliceChanged;
                }
                finally
                {
                    MemoryPool <Matrix4x4> .PutArray(buffer);
                }
            }
            return(base.Sync());
        }
예제 #10
0
        public void Evaluate(int SpreadMax)
        {
            var outputLength = FInputStreams.GetLengthSum();

            FOutputStream.Length        = outputLength;
            FOutputBinSizeStream.Length = FInputStreams.Length;

            var buffer = MemoryPool <T> .GetArray();

            try
            {
                using (var writer = FOutputStream.GetWriter())
                    using (var binSizeWriter = FOutputBinSizeStream.GetWriter())
                    {
                        foreach (var inputStream in FInputStreams)
                        {
                            using (var reader = inputStream.GetReader())
                            {
                                var numSlicesToRead = reader.Length;
                                binSizeWriter.Write(numSlicesToRead);
                                if (numSlicesToRead == 1)
                                {
                                    writer.Write(reader.Read());
                                }
                                else
                                {
                                    while (numSlicesToRead > 0)
                                    {
                                        var numSlicesRead = reader.Read(buffer, 0, buffer.Length);
                                        writer.Write(buffer, 0, numSlicesRead);
                                        numSlicesToRead -= numSlicesRead;
                                    }
                                }
                            }
                        }
                    }
            }
            finally
            {
                MemoryPool <T> .PutArray(buffer);
            }
        }
예제 #11
0
        public void Evaluate(int SpreadMax)
        {
            Prepare();

            var inputStream   = FInputContainer.IOObject;
            var outputStreams = FOutputContainer.IOObject;

            outputStreams.SetLengthBy(inputStream);

            if (inputStream.IsChanged || outputStreams.IsChanged)
            {
                var buffer = MemoryPool <T> .GetArray();

                try
                {
                    var outputStreamsLength = outputStreams.Length;

                    using (var reader = inputStream.GetCyclicReader())
                    {
                        int i = 0;
                        foreach (var outputStream in outputStreams)
                        {
                            int numSlicesToWrite = Math.Min(outputStream.Length, buffer.Length);

                            reader.Position = i++;
                            using (var writer = outputStream.GetWriter())
                            {
                                while (!writer.Eos)
                                {
                                    reader.Read(buffer, 0, numSlicesToWrite, outputStreamsLength);
                                    writer.Write(buffer, 0, numSlicesToWrite);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    MemoryPool <T> .PutArray(buffer);
                }
            }
        }
예제 #12
0
        public void Write(IntPtr pv, int cb, IntPtr pcbWritten)
        {
            var buffer = MemoryPool <byte> .GetArray();

            try
            {
                var totalBytesWritten = 0;
                while (totalBytesWritten < cb)
                {
                    var bytesToWrite = Math.Min(buffer.Length, cb - totalBytesWritten);
                    iop.Marshal.Copy(pv, buffer, 0, bytesToWrite);
                    this.source.Write(buffer, 0, bytesToWrite);
                    totalBytesWritten += bytesToWrite;
                }
                iop.Marshal.WriteInt32(pcbWritten, totalBytesWritten);
            }
            finally
            {
                MemoryPool <byte> .PutArray(buffer);
            }
        }
        public void Evaluate(int spreadMax)
        {
            if (this.FFilenameIn.IsChanged || this.FReset[0])
            {
                string path = this.FFilenameIn[0];
                if (File.Exists(path))
                {
                    this.FReader = new StreamReader(path);
                }
                FEof[0] = false;
            }

            if (this.FDoRead[0] == true && this.FReader != null)
            {
                spreadMax = StreamUtils.GetSpreadMax(FFormats, FByteOrder);
                FOutputs.ResizeAndDismiss(spreadMax, () => new MemoryIOStream <double>());
                var buffer = MemoryPool <double> .GetArray();

                try
                {
                    using (var formatReader = FFormats.GetCyclicReader())
                        using (var byteOrderReader = FByteOrder.GetCyclicReader())
                        {
                            foreach (MemoryIOStream <double> outputStream in FOutputs)
                            {
                                var formatStream = formatReader.Read();
                                var byteOrder    = byteOrderReader.Read();
                                ConvertOneByOne(this.FReader.BaseStream, outputStream, formatStream, byteOrder);
                            }
                        }
                    FOutputs.Flush(true);
                }
                finally
                {
                    MemoryPool <double> .PutArray(buffer);
                }
            }
        }
예제 #14
0
        public void Evaluate(int spreadMax)
        {
            // The final output length is known in advance
            Output.Length = spreadMax;

            // Whether or not new slices should be initialized with true
            var bangOnCreate = BangOnCreateIn.SliceCount > 0 ? BangOnCreateIn[0] : false;

            // Fetch readers and writers
            var inputReader     = Input.GetReader();
            var lastInputReader = FLastInput.GetReader();
            var lastInputWriter = FLastInput.GetDynamicWriter();
            var outputWriter    = Output.GetWriter();

            // In case of very low spread counts this saves a few ticks
            if (spreadMax < 16)
            {
                var slicesToWrite   = spreadMax;
                var inputLength     = inputReader.Length;
                var lastInputLength = lastInputReader.Length;
                var minLength       = Math.Min(inputLength, lastInputLength);
                for (int i = 0; i < minLength; i++)
                {
                    var input     = inputReader.Read();
                    var lastInput = lastInputReader.Read();
                    var changed   = !FComparer.Equals(input, lastInput);
                    outputWriter.Write(changed);
                    lastInputWriter.Write(CopySlice(input));
                }
                for (int i = lastInputLength; i < inputLength; i++)
                {
                    var changed = bangOnCreate;
                    outputWriter.Write(changed);
                    var input = inputReader.Read();
                    lastInputWriter.Write(CopySlice(input));
                }
            }
            else
            {
                // Fetch the buffers to work with from the pool
                var inputBuffer = MemoryPool <T> .GetArray();

                var lastInputBuffer = MemoryPool <T> .GetArray();

                var outputBuffer = MemoryPool <bool> .GetArray();

                try
                {
                    var slicesToWrite = spreadMax;
                    while (slicesToWrite > 0)
                    {
                        // Read the input
                        var inputReadCount = inputReader.Read(inputBuffer, 0, inputBuffer.Length);
                        // Read the input from the previous frame
                        var lastInputReadCount = lastInputReader.Read(lastInputBuffer, 0, lastInputBuffer.Length);
                        // Calculate min and max read counts
                        var minCount = Math.Min(inputReadCount, lastInputReadCount);
                        var maxCount = Math.Max(inputReadCount, lastInputReadCount);
                        // Do the equality check for all the slices where values from
                        // the previous frame are available
                        for (int i = 0; i < minCount; i++)
                        {
                            outputBuffer[i] = !FComparer.Equals(inputBuffer[i], lastInputBuffer[i]);
                        }
                        // Set the output for new slices to the value of bang on create
                        for (int i = minCount; i < maxCount; i++)
                        {
                            outputBuffer[i] = bangOnCreate;
                        }
                        // Write the result
                        outputWriter.Write(outputBuffer, 0, maxCount);
                        // Store the input values for the next frame
                        CopySlices(inputBuffer, inputReadCount);
                        lastInputWriter.Write(inputBuffer, 0, inputReadCount);
                        // Decrease the number of slices we still need to look at
                        slicesToWrite -= maxCount;
                    }
                }
                finally
                {
                    // Put the buffers back in the pool
                    MemoryPool <T> .PutArray(inputBuffer);

                    MemoryPool <T> .PutArray(lastInputBuffer);

                    MemoryPool <bool> .PutArray(outputBuffer);
                }
            }

            // Dispose the readers and writers
            inputReader.Dispose();
            lastInputReader.Dispose();
            lastInputWriter.Dispose();
            outputWriter.Dispose();
        }
예제 #15
0
        //called when data for any output pin is requested
        public void Evaluate(int spreadMax)
        {
            FOutput.Length = StreamUtils.GetMaxLength(FInput, FOffset, FCount);

            var inputBuffer = MemoryPool <IInStream <T> > .GetArray();

            var offsetBuffer = MemoryPool <int> .GetArray();

            var countBuffer = MemoryPool <int> .GetArray();

            try
            {
                using (var inputReader = FInput.GetCyclicReader())
                    using (var offsetReader = FOffset.GetCyclicReader())
                        using (var countReader = FCount.GetCyclicReader())
                            using (var outputWriter = FOutput.GetWriter())
                            {
                                var numSlicesToWrite = FOutput.Length;
                                while (numSlicesToWrite > 0)
                                {
                                    var blockSize = Math.Min(numSlicesToWrite, inputBuffer.Length);
                                    inputReader.Read(inputBuffer, 0, blockSize);
                                    offsetReader.Read(offsetBuffer, 0, blockSize);
                                    countReader.Read(countBuffer, 0, blockSize);

                                    for (int i = 0; i < blockSize; i++)
                                    {
                                        var source       = inputBuffer[i];
                                        var sourceLength = source.Length;
                                        if (sourceLength > 0)
                                        {
                                            var offset = offsetBuffer[i];
                                            var count  = countBuffer[i];

                                            if (offset < 0 || offset >= sourceLength)
                                            {
                                                offset = VMath.Zmod(offset, sourceLength);
                                            }
                                            if (count < 0)
                                            {
                                                source = source.Reverse();
                                                count  = -count;
                                                offset = sourceLength - offset;
                                            }
                                            // offset and count are positive now
                                            if (offset + count > sourceLength)
                                            {
                                                source = source.Cyclic();
                                            }

                                            inputBuffer[i] = source.GetRange(offset, count);
                                        }
                                    }

                                    numSlicesToWrite -= outputWriter.Write(inputBuffer, 0, blockSize);
                                }
                            }
            }
            finally
            {
                MemoryPool <IInStream <T> > .PutArray(inputBuffer);

                MemoryPool <int> .PutArray(offsetBuffer);

                MemoryPool <int> .PutArray(countBuffer);
            }
        }
예제 #16
0
        public override void Flush(bool force = false)
        {
            var buffer = MemoryPool <T> .GetArray();

            var binSizeBuffer = MemoryPool <int> .GetArray();

            try
            {
                FBinSizeStream.Length = Length;

                int dataStreamLength = 0;
                using (var binSizeWriter = FBinSizeStream.GetWriter())
                {
                    var numSlicesBuffered = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        var length = Buffer[i]?.Length ?? 0;
                        binSizeBuffer[numSlicesBuffered++] = length;
                        dataStreamLength += length;
                        if (numSlicesBuffered == binSizeBuffer.Length)
                        {
                            binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                            numSlicesBuffered = 0;
                        }
                    }
                    if (numSlicesBuffered > 0)
                    {
                        binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                    }
                }

                FDataStream.Length = dataStreamLength;
                using (var dataWriter = FDataStream.GetWriter())
                {
                    bool anyChanged        = force || IsChanged;
                    var  numSlicesBuffered = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        var stream = Buffer[i];
                        if (stream != null)
                        {
                            anyChanged |= stream.IsChanged;
                            if (anyChanged)
                            {
                                using (var reader = stream.GetReader())
                                {
                                    switch (reader.Length)
                                    {
                                    case 0:
                                        break;

                                    case 1:
                                        buffer[numSlicesBuffered++] = reader.Read();
                                        WriteIfBufferIsFull(dataWriter, buffer, ref numSlicesBuffered);
                                        break;

                                    default:
                                        while (!reader.Eos)
                                        {
                                            numSlicesBuffered += reader.Read(buffer, numSlicesBuffered, buffer.Length - numSlicesBuffered);
                                            WriteIfBufferIsFull(dataWriter, buffer, ref numSlicesBuffered);
                                        }
                                        break;
                                    }
                                }
                                // Reset the changed flags
                                var flushable = stream as IFlushable;
                                if (flushable != null)
                                {
                                    flushable.Flush(force);
                                }
                            }
                            else
                            {
                                dataWriter.Position += stream.Length;
                            }
                        }
                    }
                    if (numSlicesBuffered > 0)
                    {
                        dataWriter.Write(buffer, 0, numSlicesBuffered);
                    }
                }
            }
            finally
            {
                MemoryPool <int> .PutArray(binSizeBuffer);

                MemoryPool <T> .PutArray(buffer);
            }

            FBinSizeStream.Flush(force);
            FDataStream.Flush(force);

            base.Flush(force);
        }
예제 #17
0
            public override void Flush(bool force = false)
            {
                var buffer = MemoryPool <T> .GetArray();

                var binSizeBuffer = MemoryPool <int> .GetArray();

                try
                {
                    FBinSizeStream.Length = Length;

                    int dataStreamLength = 0;
                    using (var binSizeWriter = FBinSizeStream.GetWriter())
                    {
                        var numSlicesBuffered = 0;
                        for (int i = 0; i < Length; i++)
                        {
                            var stream = Buffer[i].Stream;
                            binSizeBuffer[numSlicesBuffered++] = stream.Length;
                            dataStreamLength += stream.Length;
                            if (numSlicesBuffered == binSizeBuffer.Length)
                            {
                                binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                                numSlicesBuffered = 0;
                            }
                        }
                        if (numSlicesBuffered > 0)
                        {
                            binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                        }
                    }

                    FDataStream.Length = dataStreamLength;
                    using (var dataWriter = FDataStream.GetWriter())
                    {
                        bool anyChanged = force || IsChanged;
                        for (int i = 0; i < Length; i++)
                        {
                            var spread = Buffer[i];
                            anyChanged |= spread.IsChanged;
                            if (anyChanged)
                            {
                                var stream = spread.Stream;
                                switch (stream.Length)
                                {
                                case 0:
                                    break;

                                case 1:
                                    dataWriter.Write(stream.Buffer[0]);
                                    break;

                                default:
                                    dataWriter.Write(stream.Buffer, 0, stream.Length);
                                    break;
                                }
                                // Reset the changed flags
                                stream.Flush(force);
                            }
                            else
                            {
                                dataWriter.Position += spread.SliceCount;
                            }
                        }
                    }
                }
                finally
                {
                    MemoryPool <int> .PutArray(binSizeBuffer);

                    MemoryPool <T> .PutArray(buffer);
                }

                FDataStream.Flush();
                FBinSizeStream.Flush();

                base.Flush();
            }
예제 #18
0
        public override void Flush(bool force = false)
        {
            var buffer = MemoryPool <T> .GetArray();

            var binSizeBuffer = MemoryPool <int> .GetArray();

            try
            {
                FBinSizeStream.Length = Length;

                int dataStreamLength = 0;
                using (var binSizeWriter = FBinSizeStream.GetWriter())
                {
                    var numSlicesBuffered = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        var array = Buffer[i];
                        if (array != null)
                        {
                            binSizeBuffer[numSlicesBuffered++] = array.Count;
                            dataStreamLength += array.Count;
                        }
                        else
                        {
                            binSizeBuffer[numSlicesBuffered++] = 0;
                        }

                        if (numSlicesBuffered == binSizeBuffer.Length)
                        {
                            binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                            numSlicesBuffered = 0;
                        }
                    }
                    if (numSlicesBuffered > 0)
                    {
                        binSizeWriter.Write(binSizeBuffer, 0, numSlicesBuffered);
                    }
                }

                FDataStream.Length = dataStreamLength;
                using (var dataWriter = FDataStream.GetWriter())
                {
                    bool anyChanged        = force || IsChanged;
                    var  numSlicesBuffered = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        var array = Buffer[i];
                        if (array != null)
                        {
                            switch (array.Count)
                            {
                            case 0:
                                break;

                            case 1:
                                buffer[numSlicesBuffered++] = array[0];
                                WriteIfBufferIsFull(dataWriter, buffer, ref numSlicesBuffered);
                                break;

                            default:
                                var sourceIndex = 0;
                                while (sourceIndex < array.Count)
                                {
                                    var chunkLength = Math.Min(array.Count - sourceIndex, buffer.Length - numSlicesBuffered);
                                    array.CopyTo(sourceIndex, buffer, numSlicesBuffered, chunkLength);
                                    sourceIndex       += chunkLength;
                                    numSlicesBuffered += chunkLength;
                                    WriteIfBufferIsFull(dataWriter, buffer, ref numSlicesBuffered);
                                }
                                break;
                            }
                        }
                    }
                    if (numSlicesBuffered > 0)
                    {
                        dataWriter.Write(buffer, 0, numSlicesBuffered);
                    }
                }
            }
            finally
            {
                MemoryPool <int> .PutArray(binSizeBuffer);

                MemoryPool <T> .PutArray(buffer);
            }

            FBinSizeStream.Flush(force);
            FDataStream.Flush(force);

            base.Flush(force);
        }
예제 #19
0
파일: Select.cs 프로젝트: vnmone/vvvv-sdk
        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);
                            }
                        }
        }