Пример #1
0
        private void WriteDataCore(IChannel ch, TextWriter writer, IDataView data,
                                   out string argsLoader, out long count, out int min, out int max, params int[] cols)
        {
            _host.AssertValue(ch);
            ch.AssertValue(writer);
            ch.AssertValue(data);
            ch.AssertNonEmpty(cols);

            // Determine the active columns and whether there is header information.
            bool[] active = new bool[data.Schema.ColumnCount];
            for (int i = 0; i < cols.Length; i++)
            {
                ch.Check(0 <= cols[i] && cols[i] < active.Length);
                ch.Check(data.Schema.GetColumnType(cols[i]).ItemType.RawKind != 0);
                active[cols[i]] = true;
            }

            bool hasHeader = false;

            if (_outputHeader)
            {
                for (int i = 0; i < cols.Length; i++)
                {
                    if (hasHeader)
                    {
                        continue;
                    }
                    var type = data.Schema.GetColumnType(cols[i]);
                    if (!type.IsVector)
                    {
                        hasHeader = true;
                        continue;
                    }
                    if (!type.IsKnownSizeVector)
                    {
                        continue;
                    }
                    var typeNames = data.Schema.GetMetadataTypeOrNull(MetadataUtils.Kinds.SlotNames, cols[i]);
                    if (typeNames != null && typeNames.VectorSize == type.VectorSize && typeNames.ItemType.IsText)
                    {
                        hasHeader = true;
                    }
                }
            }

            using (var cursor = data.GetRowCursor(i => active[i]))
            {
                var pipes = new ValueWriter[cols.Length];
                for (int i = 0; i < cols.Length; i++)
                {
                    pipes[i] = ValueWriter.Create(cursor, cols[i], _sepChar);
                }

                // REVIEW: This should be outside the cursor creation.
                string header = CreateLoaderArguments(data.Schema, pipes, hasHeader, ch);
                argsLoader = header;
                if (_outputSchema)
                {
                    WriteSchemaAsComment(writer, header);
                }

                double rowCount = data.GetRowCount(true) ?? double.NaN;
                using (var pch = !_silent ? _host.StartProgressChannel("TextSaver: saving data") : null)
                {
                    long stateCount = 0;
                    var  state      = new State(this, writer, pipes, hasHeader);
                    if (pch != null)
                    {
                        pch.SetHeader(new ProgressHeader(new[] { "rows" }), e => e.SetProgress(0, stateCount, rowCount));
                    }
                    state.Run(cursor, ref stateCount, out min, out max);
                    count = stateCount;
                    if (pch != null)
                    {
                        pch.Checkpoint(stateCount);
                    }
                }
            }
        }