| File: DataDebuggerPreview.cs | Web Access |
| Project: src\src\Microsoft.ML.Data\Microsoft.ML.Data.csproj (Microsoft.ML.Data) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Runtime; namespace Microsoft.ML.Data { /// <summary> /// This class represents an eager 'preview' of a <see cref="IDataView"/>. /// </summary> public sealed class DataDebuggerPreview { private static readonly FuncInstanceMethodInfo1<DataDebuggerPreview, DataViewRow, int, Action<RowInfo, List<object>>> _makeSetterMethodInfo = FuncInstanceMethodInfo1<DataDebuggerPreview, DataViewRow, int, Action<RowInfo, List<object>>>.Create(target => target.MakeSetter<int>); internal static class Defaults { public const int MaxRows = 100; } public DataViewSchema Schema { get; } public ImmutableArray<ColumnInfo> ColumnView { get; } public ImmutableArray<RowInfo> RowView { get; } internal DataDebuggerPreview(IDataView data, int maxRows = Defaults.MaxRows) { Contracts.CheckValue(data, nameof(data)); Contracts.CheckParam(maxRows >= 0, nameof(maxRows)); Schema = data.Schema; int n = data.Schema.Count; var rows = new List<RowInfo>(); var columns = new List<object>[n]; for (int i = 0; i < columns.Length; i++) columns[i] = new List<object>(); using (var cursor = data.GetRowCursorForAllColumns()) { var setters = new Action<RowInfo, List<object>>[n]; for (int i = 0; i < n; i++) setters[i] = Utils.MarshalInvoke(_makeSetterMethodInfo, this, data.Schema[i].Type.RawType, cursor, i); int count = 0; while (count < maxRows && cursor.MoveNext()) { var curRow = new RowInfo(n); for (int i = 0; i < setters.Length; i++) setters[i](curRow, columns[i]); rows.Add(curRow); count++; } } RowView = rows.ToImmutableArray(); ColumnView = Enumerable.Range(0, n).Select(c => new ColumnInfo(data.Schema[c], columns[c].ToArray())).ToImmutableArray(); } public override string ToString() => $"{Schema.Count} columns, {RowView.Length} rows"; private Action<RowInfo, List<object>> MakeSetter<T>(DataViewRow row, int col) { var column = row.Schema[col]; var getter = row.GetGetter<T>(column); Action<RowInfo, List<object>> result = (rowInfo, list) => { T value = default; getter(ref value); rowInfo.Values[col] = new KeyValuePair<string, object>(column.Name, value); // Call getter again on another buffer, since we store it in two places. value = default; getter(ref value); list.Add(value); }; return result; } public sealed class RowInfo { [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)] public KeyValuePair<string, object>[] Values { get; } public override string ToString() => $"{Values.Length} columns"; internal RowInfo(int n) { Values = new KeyValuePair<string, object>[n]; } } public sealed class ColumnInfo { public DataViewSchema.Column Column { get; } public object[] Values { get; } public override string ToString() => $"{Column.Name}: {Column.Type}"; internal ColumnInfo(DataViewSchema.Column column, object[] values) { Column = column; Values = values; } } } }