Esempio n. 1
0
            public RowCursor(IChannelProvider provider, int poolRows, IRowCursor input, IRandom rand)
                : base(provider)
            {
                Ch.AssertValue(input);
                Ch.AssertValue(rand);

                Ch.Assert(_blockSize > 0);
                Ch.Assert(_bufferDepth > 0);
                Ch.Assert(poolRows > 0);

                _poolRows = poolRows;
                _input    = input;
                _rand     = rand;

                _pipeIndices = Utils.GetIdentityPermutation(_poolRows - 1 + _bufferDepth * _blockSize);

                int colLim    = Schema.ColumnCount;
                int numActive = 0;

                _colToActivesIndex = new int[colLim];
                for (int c = 0; c < colLim; ++c)
                {
                    _colToActivesIndex[c] = _input.IsColumnActive(c) ? numActive++ : -1;
                }
                _pipes   = new ShufflePipe[numActive + (int)ExtraIndex.Lim];
                _getters = new Delegate[numActive];
                for (int c = 0; c < colLim; ++c)
                {
                    int ia = _colToActivesIndex[c];
                    if (ia < 0)
                    {
                        continue;
                    }
                    _pipes[ia] = ShufflePipe.Create(_pipeIndices.Length,
                                                    input.Schema.GetColumnType(c), RowCursorUtils.GetGetterAsDelegate(input, c));
                    _getters[ia] = CreateGetterDelegate(c);
                }
                var idPipe = _pipes[numActive + (int)ExtraIndex.Id] = ShufflePipe.Create(_pipeIndices.Length, NumberType.UG, input.GetIdGetter());

                _idGetter = CreateGetterDelegate <UInt128>(idPipe);
                // Initially, after the preamble to MoveNextCore, we want:
                // liveCount=0, deadCount=0, circularIndex=0. So we set these
                // funky values accordingly.
                _pipeIndex = _circularIndex = _pipeIndices.Length - 1;
                _deadCount = -1;
                _liveCount = 1;

                // Set up the producer worker.
                _toConsume = new BufferBlock <int>();
                _toProduce = new BufferBlock <int>();
                // First request the pool - 1 + block size rows, to get us going.
                PostAssert(_toProduce, _poolRows - 1 + _blockSize);
                // Queue up the remaining capacity.
                for (int i = 1; i < _bufferDepth; ++i)
                {
                    PostAssert(_toProduce, _blockSize);
                }

                _producerTask = LoopProducerWorker();
            }
            public Row GetOutputRow(Row input, Func <int, bool> predicate, out Action disposer)
            {
                Contracts.AssertValue(input);
                Contracts.AssertValue(predicate);
                var totalColumnsCount = 1 + _outputGenericSchema.ColumnCount;
                var getters           = new Delegate[totalColumnsCount];

                if (predicate(totalColumnsCount - 1))
                {
                    getters[totalColumnsCount - 1] = _parent.Stringify
                        ? _parent.GetTextContributionGetter(input, InputRoleMappedSchema.Feature.Index, _slotNames)
                        : _parent.GetContributionGetter(input, InputRoleMappedSchema.Feature.Index);
                }

                var genericRow = _genericRowMapper.GetRow(input, GetGenericPredicate(predicate), out disposer);

                for (var i = 0; i < _outputGenericSchema.ColumnCount; i++)
                {
                    if (genericRow.IsColumnActive(i))
                    {
                        getters[i] = RowCursorUtils.GetGetterAsDelegate(genericRow, i);
                    }
                }

                return(new SimpleRow(OutputSchema, input, getters));
            }