internal DataViewRow GetStatefulRows(DataViewRow input, IRowToRowMapper mapper, IEnumerable <DataViewSchema.Column> activeColumns, List <StatefulRow> rows)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(activeColumns, nameof(activeColumns));

            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper compositeMapper)
            {
                innerMappers = compositeMapper.InnerMappers;
            }

            var activeIndices = new HashSet <int>(activeColumns.Select(c => c.Index));

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.Count; ++c)
                {
                    bool wantsActive = activeIndices.Contains(c);
                    bool isActive    = input.IsColumnActive(input.Schema[c]);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema[c].Name}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, activeColumns);
                if (row is StatefulRow statefulRow)
                {
                    rows.Add(statefulRow);
                }
                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new IEnumerable <DataViewSchema.Column> [innerMappers.Length];

            deps[deps.Length - 1] = activeColumns;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                deps[i - 1] = innerMappers[i].GetDependencies(deps[i]);
            }

            DataViewRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows);
                if (result is StatefulRow statefulResult)
                {
                    rows.Add(statefulResult);
                }
            }
            return(result);
        }
예제 #2
0
        internal DataViewRow GetStatefulRows(DataViewRow input, IRowToRowMapper mapper, Func <int, bool> active, List <StatefulRow> rows)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(active, nameof(active));

            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper compositeMapper)
            {
                innerMappers = compositeMapper.InnerMappers;
            }

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.Count; ++c)
                {
                    bool wantsActive = active(c);
                    bool isActive    = input.IsColumnActive(c);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema[c].Name}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, active);
                if (row is StatefulRow statefulRow)
                {
                    rows.Add(statefulRow);
                }
                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new Func <int, bool> [innerMappers.Length];

            deps[deps.Length - 1] = active;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                var inputCols = innerMappers[i].OutputSchema.Where(c => deps[i](c.Index));
                var cols      = innerMappers[i].GetDependencies(inputCols).ToArray();
                deps[i - 1] = c => cols.Length > 0 ? cols.Any(col => col.Index == c) : false;
            }

            DataViewRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows);
                if (result is StatefulRow statefulResult)
                {
                    rows.Add(statefulResult);
                }
            }
            return(result);
        }
        internal virtual void PredictionEngineCore(IHostEnvironment env, DataViewConstructionUtils.InputRow <TSrc> inputRow, IRowToRowMapper mapper, bool ignoreMissingColumns,
                                                   SchemaDefinition inputSchemaDefinition, SchemaDefinition outputSchemaDefinition, out Action disposer, out IRowReadableAs <TDst> outputRow)
        {
            var cursorable = TypedCursorable <TDst> .Create(env, new EmptyDataView(env, mapper.Schema), ignoreMissingColumns, outputSchemaDefinition);

            var outputRowLocal = mapper.GetRow(_inputRow, col => true, out disposer);

            outputRow = cursorable.GetRow(outputRowLocal);
        }
        internal IRow GetStatefulRows(IRow input, IRowToRowMapper mapper, Func <int, bool> active,
                                      List <IStatefulRow> rows, out Action disposer)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(active, nameof(active));

            disposer = null;
            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper)
            {
                innerMappers = ((CompositeRowToRowMapper)mapper).InnerMappers;
            }

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.ColumnCount; ++c)
                {
                    bool wantsActive = active(c);
                    bool isActive    = input.IsColumnActive(c);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema.GetColumnName(c)}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, active, out disposer);
                if (row is IStatefulRow)
                {
                    rows.Add((IStatefulRow)row);
                }

                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new Func <int, bool> [innerMappers.Length];

            deps[deps.Length - 1] = active;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                deps[i - 1] = innerMappers[i].GetDependencies(deps[i]);
            }

            IRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                Action localDisp;
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows, out localDisp);
                if (result is IStatefulRow)
                {
                    rows.Add((IStatefulRow)result);
                }

                if (localDisp != null)
                {
                    if (disposer == null)
                    {
                        disposer = localDisp;
                    }
                    else
                    {
                        disposer = localDisp + disposer;
                    }
                    // We want the last disposer to be called first, so the order of the addition here is important.
                }
            }

            return(result);
        }
 /// <summary>
 /// Extension method.
 /// </summary>
 /// <param name="rowMapper"></param>
 /// <param name="input"></param>
 /// <param name="activeColumns"></param>
 /// <returns></returns>
 public static DataViewRow GetRow(this IRowToRowMapper rowMapper, DataViewRow input, params DataViewSchema.Column[] activeColumns)
 => rowMapper.GetRow(input, activeColumns);