Ejemplo n.º 1
0
        public void CacheUsesCachedValuesAfterTheyAreComputed()
        {
            var computeCounts = new Dictionary <int, int>();

            object factory(int value)
            {
                if (!computeCounts.ContainsKey(value))
                {
                    computeCounts[value] = 0;
                }

                ++computeCounts[value];
                return(computeCounts[value]);
            }

            var projection = Projection.CacheOnFirstUse(3, Projection.CreateUsingFuncAdaptor(factory));

            Assert.AreEqual(1, projection[0]);
            Assert.AreEqual(1, projection[0]);
            Assert.AreEqual(1, projection[0]);

            Assert.AreEqual(1, projection[1]);
            Assert.AreEqual(1, projection[1]);
            Assert.AreEqual(1, projection[1]);

            Assert.AreEqual(1, projection[2]);
            Assert.AreEqual(1, projection[2]);
            Assert.AreEqual(1, projection[2]);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var messages = tableData.QueryOutput <IReadOnlyList <IDiagnosticMessage> >(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngDmesgDataCooker.Identifier, nameof(LTTngDmesgDataCooker.DiagnosticMessages)));

            if (messages.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("MessagesByTimestamp")
            {
                Columns = new[]
                {
                    messageColumn,
                    TableConfiguration.PivotColumn,
                    TableConfiguration.GraphColumn,
                    timestampColumn
                },
            };

            config.AddColumnRole(ColumnRole.StartTime, timestampColumn);
            config.AddColumnRole(ColumnRole.EndTime, timestampColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(messages.Count);

            table.AddColumn(messageColumn, Projection.CreateUsingFuncAdaptor((i) => messages[i].Message));
            table.AddColumn(timestampColumn, Projection.CreateUsingFuncAdaptor((i) => messages[i].Timestamp));
        }
        public void DynamicTitleProjection_NameIsConstantReturnsFalse()
        {
            var projection = Projection.CreateUsingFuncAdaptor <int, string>(i => i.ToString());

            var metadata = new ColumnMetadata(this.ColumnGuid, "default", projection, "test column");

            Assert.IsFalse(metadata.IsNameConstant);
        }
        public void DynamicTitleProjection_ProjectorIsExposed()
        {
            var projection = Projection.CreateUsingFuncAdaptor <int, string>(i => i.ToString());

            var metadata = new ColumnMetadata(this.ColumnGuid, "default", projection, "test column");

            Assert.AreSame(projection, metadata.NameProjection);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var threads = tableData.QueryOutput <IReadOnlyList <IThread> >(
                DataOutputPath.Create(LTTngThreadDataCooker.CookerPath + "/Threads"));

            if (threads.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("ThreadsByProcessId")
            {
                Columns = new[]
                {
                    processIdColumn,
                    threadIdColumn,
                    commandColumn,
                    TableConfiguration.PivotColumn,
                    threadExecTimeColumn,
                    threadReadyTimeColumn,
                    threadRunningTimeColumn,
                    threadSleepTimeColumn,
                    threadDiskSleepTimeColumn,
                    threadWaitingTimeColumn,
                    threadIdleTimeColumn,
                    TableConfiguration.GraphColumn,
                    threadStartTimeColumn,
                    threadExitTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, threadStartTimeColumn);
            config.AddColumnRole(ColumnRole.EndTime, threadExitTimeColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(threads.Count);

            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ThreadId));
            table.AddColumn(processIdColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ProcessId));
            table.AddColumn(commandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Command));
            table.AddColumn(threadExecTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExecTime));
            table.AddColumn(threadReadyTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyTime));
            table.AddColumn(threadRunningTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExecTime + threads[i].ReadyTime));
            table.AddColumn(threadSleepTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SleepTime));
            table.AddColumn(threadDiskSleepTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].DiskSleepTime));
            table.AddColumn(threadWaitingTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SleepTime + threads[i].DiskSleepTime));
            table.AddColumn(threadStoppedTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].StoppedTime));
            table.AddColumn(threadParkedTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ParkedTime));
            table.AddColumn(threadIdleTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].IdleTime));
            table.AddColumn(threadStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].StartTime));
            table.AddColumn(threadExitTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExitTime));
            table.AddColumn(threadLifespanColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ExitTime - threads[i].StartTime));
        }
Ejemplo n.º 6
0
        public void AddColumnReturnsBuilder()
        {
            var column = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            Assert.AreEqual(this.Sut, this.Sut.AddColumn(column));
        }
Ejemplo n.º 7
0
        public void ReplaceColumnOldNullThrows()
        {
            var column = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            Assert.ThrowsException <ArgumentNullException>(
                () => this.Sut.ReplaceColumn(null, column));
        }
Ejemplo n.º 8
0
        public void AddColumnAdds()
        {
            var column = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            this.Sut.AddColumn(column);

            Assert.IsTrue(this.Sut.Columns.Contains(column));
        }
Ejemplo n.º 9
0
        public void ComposeWithProjectionComposesCorrectly()
        {
            var f = Projection.CreateUsingFuncAdaptor <int, DateTime>(i => DateTime.FromFileTime(i));
            var g = Projection.CreateUsingFuncAdaptor <DateTime, string>(x => x.ToString());

            var argument = 23;
            var expected = g[f[argument]];

            var sut    = f.Compose(g);
            var actual = sut[argument];

            Assert.AreEqual(expected, actual);
        }
Ejemplo n.º 10
0
        public void ReplaceColumnWithSelfNoOps()
        {
            var column = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            this.Sut.AddColumn(column);
            this.Sut.ReplaceColumn(column, column);

            Assert.AreEqual(1, this.Sut.Columns.Count);
            Assert.AreEqual(column, this.Sut.Columns.Single());
        }
        public void DynamicTitleProjection_NameAlwaysReturnsDefaultValue()
        {
            var projection = Projection.CreateUsingFuncAdaptor <int, string>(i => i.ToString());

            var metadata = new ColumnMetadata(
                this.ColumnGuid,
                "default",
                projection,
                "test column");

            for (var i = 0; i < 1000; ++i)
            {
                Assert.AreEqual("default", metadata.Name);
            }
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var syscalls = tableData.QueryOutput <IReadOnlyList <ISyscall> >(
                DataOutputPath.Create(LTTngSyscallDataCooker.CookerPath + '/' + nameof(LTTngSyscallDataCooker.Syscalls)));

            if (syscalls.Count == 0)
            {
                return;
            }

            var defaultConfig = new TableConfiguration("Individual Syscalls")
            {
                Columns = new[]
                {
                    syscallNumberColumn,
                    TableConfiguration.PivotColumn,
                    syscallNameColumn,
                    syscallDurationColumn,
                    syscallArgumentsColumn,
                    syscallReturnValueColumn,
                    syscallThreadIdColumn,
                    syscallCommandColumn,
                    syscallProcessIdColumn,
                    TableConfiguration.GraphColumn,
                    syscallStartTimeColumn,
                    syscallEndTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            defaultConfig.AddColumnRole(ColumnRole.StartTime, syscallStartTimeColumn);
            defaultConfig.AddColumnRole(ColumnRole.EndTime, syscallEndTimeColumn);

            var table = tableBuilder.AddTableConfiguration(defaultConfig)
                        .SetDefaultTableConfiguration(defaultConfig)
                        .SetRowCount(syscalls.Count);

            table.AddColumn(syscallNameColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].Name));
            table.AddColumn(syscallThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ThreadId));
            table.AddColumn(syscallProcessIdColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ProcessId));
            table.AddColumn(syscallCommandColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ProcessCommand));
            table.AddColumn(syscallNumberColumn, Projection.CreateUsingFuncAdaptor((i) => i + 1));
            table.AddColumn(syscallStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].StartTime));
            table.AddColumn(syscallEndTimeColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].EndTime));
            table.AddColumn(syscallDurationColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].EndTime - syscalls[i].StartTime));
            table.AddColumn(syscallReturnValueColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].ReturnValue));
            table.AddColumn(syscallArgumentsColumn, Projection.CreateUsingFuncAdaptor((i) => syscalls[i].Arguments));
        }
Ejemplo n.º 13
0
        public void CacheDoesNotInvokeProjectionOnCreation()
        {
            var invoked = false;

            object factory(int value)
            {
                invoked = true;
                return(value);
            };

            var projection = Projection.CacheOnFirstUse(
                3,
                Projection.CreateUsingFuncAdaptor(factory));

            Assert.IsFalse(invoked);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var fileEvents = tableData.QueryOutput <IReadOnlyList <IFileEvent> >(
                DataOutputPath.Create(LTTngDiskDataCooker.CookerPath + '/' + nameof(LTTngDiskDataCooker.FileEvents)));

            if (fileEvents.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("EventsBySyscallType")
            {
                Columns = new[]
                {
                    fileEventNameColumn,
                    TableConfiguration.PivotColumn,
                    fileEventThreadIdColumn,
                    fileEventProcessIdColumn,
                    fileEventCommandColumn,
                    fileEventFilePathColumn,
                    fileEventSizeColumn,
                    fileEventDurationColumn,
                    TableConfiguration.GraphColumn,
                    fileEventStartTimeColumn,
                    fileEventEndTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            config.AddColumnRole(ColumnRole.StartTime, fileEventStartTimeColumn);
            config.AddColumnRole(ColumnRole.EndTime, fileEventEndTimeColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(fileEvents.Count);

            table.AddColumn(fileEventNameColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].Name));
            table.AddColumn(fileEventThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ThreadId));
            table.AddColumn(fileEventProcessIdColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ProcessId));
            table.AddColumn(fileEventCommandColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].ProcessCommand));
            table.AddColumn(fileEventFilePathColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].Filepath));
            table.AddColumn(fileEventStartTimeColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].StartTime));
            table.AddColumn(fileEventEndTimeColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].EndTime));
            table.AddColumn(fileEventDurationColumn, Projection.CreateUsingFuncAdaptor((i) => fileEvents[i].EndTime - fileEvents[i].StartTime));
            table.AddColumn(fileEventSizeColumn, new FileActivitySizeProjection(Projection.CreateUsingFuncAdaptor((i) => fileEvents[i])));
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var moduleEvents = tableData.QueryOutput <IReadOnlyList <IModuleEvent> >(
                DataOutputPath.Create(LTTngModuleDataCooker.CookerPath + '/' + nameof(LTTngModuleDataCooker.ModuleEvents)));

            if (moduleEvents.Count == 0)
            {
                return;
            }

            var defaultConfig = new TableConfiguration("Module Events")
            {
                Columns = new[]
                {
                    moduleNameColumn,
                    eventTypeColumn,
                    TableConfiguration.PivotColumn,
                    instructionPointerColumn,
                    refCountColumn,
                    threadIdColumn,
                    processIdColumn,
                    commandColumn,
                    TableConfiguration.GraphColumn,
                    timestampColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            defaultConfig.AddColumnRole(ColumnRole.StartTime, timestampColumn);
            defaultConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);

            var table = tableBuilder.AddTableConfiguration(defaultConfig)
                        .SetDefaultTableConfiguration(defaultConfig)
                        .SetRowCount(moduleEvents.Count);

            table.AddColumn(eventTypeColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].EventType));
            table.AddColumn(moduleNameColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ModuleName));
            table.AddColumn(instructionPointerColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].InstructionPointer));
            table.AddColumn(refCountColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].RefCount));
            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ThreadId));
            table.AddColumn(processIdColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ProcessId));
            table.AddColumn(commandColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].ProcessCommand));
            table.AddColumn(timestampColumn, Projection.CreateUsingFuncAdaptor((i) => moduleEvents[i].Time));
        }
Ejemplo n.º 16
0
        public void PrepopulatedCacheInvokesUpfrontForEachValue()
        {
            var invokedWith = new List <int>();

            object factory(int value)
            {
                invokedWith.Add(value);
                return(value);
            };

            var projection = Projection.PrepopulatedCache(
                3,
                Projection.CreateUsingFuncAdaptor(factory));

            Assert.AreEqual(3, invokedWith.Count);
            Assert.IsTrue(invokedWith.Contains(0));
            Assert.IsTrue(invokedWith.Contains(1));
            Assert.IsTrue(invokedWith.Contains(2));
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var contextSwitches = tableData.QueryOutput <ProcessedEventData <IContextSwitch> >(
                DataOutputPath.Create("LTTng/CpuDataCooker/ContextSwitches"));

            if (contextSwitches.Count == 0)
            {
                return;
            }

            var table = tableBuilder.SetRowCount((int)contextSwitches.Count);

            table.AddColumn(oldThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchOut.ThreadId));
            table.AddColumn(oldImageNameColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchOut.ImageName));
            table.AddColumn(oldPriorityColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchOut.Priority));
            table.AddColumn(newThreadIdColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchIn.ThreadId));
            table.AddColumn(newImageNameColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchIn.ImageName));
            table.AddColumn(newPriorityColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].SwitchIn.Priority));
            table.AddColumn(timestampColumn, Projection.CreateUsingFuncAdaptor((i) => contextSwitches[(uint)i].Timestamp));
        }
Ejemplo n.º 18
0
        public void ReplaceColumnReturnsBuilder()
        {
            var columnOld = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            var columnNew = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            this.Sut.AddColumn(columnOld);
            var builder = this.Sut.ReplaceColumn(columnOld, columnNew);

            Assert.AreEqual(this.Sut, builder);
        }
Ejemplo n.º 19
0
        public void ReplaceColumnThatDoesNotExistAdds()
        {
            var columnNotThere = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            var columnNew = new BaseDataColumn <string>(
                new ColumnMetadata(Guid.NewGuid(), "name"),
                new UIHints {
                Width = 200,
            },
                Projection.CreateUsingFuncAdaptor(i => "test"));

            this.Sut.ReplaceColumn(columnNotThere, columnNew);

            Assert.AreEqual(1, this.Sut.Columns.Count);
            Assert.AreEqual(columnNew, this.Sut.Columns.Single());
        }
        internal static void BuildMetadataTable(ITableBuilder tableBuilder, LTTngSourceParser sourceParser, ITableConfigurationsSerializer serializer)
        {
            ITableBuilderWithRowCount table = tableBuilder.SetRowCount(sourceParser.TraceStats.Count);

            IReadOnlyList <string> eventNames = sourceParser.TraceStats.Keys.ToList();

            var eventNameProjection       = Projection.CreateUsingFuncAdaptor(x => eventNames[x]);
            var traceStatsProjection      = eventNameProjection.Compose(eventName => sourceParser.TraceStats[eventName]);
            var eventCountProjection      = traceStatsProjection.Compose(traceStats => traceStats.EventCount);
            var payloadBitCountProjection = traceStatsProjection.Compose(traceStats => (double)traceStats.PayloadBitCount / 8);

            table.AddColumn(
                new DataColumn <string>(
                    EventNameConfiguration,
                    eventNameProjection));

            table.AddColumn(
                new DataColumn <ulong>(
                    CountConfiguration,
                    eventCountProjection));

            table.AddColumn(
                new DataColumn <double>(
                    TotalPayloadSizeConfiguration,
                    payloadBitCountProjection));

            var configurations = TableConfigurations.GetPrebuiltTableConfigurations(
                typeof(TraceStatsTable),
                TableDescriptor.Guid,
                serializer);

            foreach (var configuration in configurations)
            {
                tableBuilder.AddTableConfiguration(configuration);
                if (StringComparer.Ordinal.Equals(configuration.Name, configurations.DefaultConfigurationName))
                {
                    tableBuilder.SetDefaultTableConfiguration(configuration);
                }
            }
        }
Ejemplo n.º 21
0
        public void CreateUsingFuncAdaptorCreates()
        {
            var data = Enumerable.Range(0, 10).ToDictionary(
                key => key,
                value => value.ToString());

            var anonympusFunction = new Func <int, string>(x => data[x]);

            string function(int value) => data[value];

            var sut = Projection.CreateUsingFuncAdaptor(anonympusFunction);

            foreach (var kvp in data)
            {
                Assert.AreEqual(kvp.Value, sut[kvp.Key]);
            }

            sut = Projection.CreateUsingFuncAdaptor(function);

            foreach (var kvp in data)
            {
                Assert.AreEqual(kvp.Value, sut[kvp.Key]);
            }
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var threads = tableData.QueryOutput <IReadOnlyList <IExecutionEvent> >(
                DataOutputPath.ForSource(LTTngConstants.SourceId, LTTngThreadDataCooker.Identifier, nameof(LTTngThreadDataCooker.ExecutionEvents)));

            if (threads.Count == 0)
            {
                return;
            }

            const string filterIdleSamplesQuery   = "[New Thread Id]:=\"0\"";
            var          timelineByCPUTableConfig = new TableConfiguration("Timeline by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    nextPidColumn,
                    nextTidColumn,
                    TableConfiguration.PivotColumn,
                    nextCommandColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    switchInTimeColumn,
                    switchOutTimeColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            timelineByCPUTableConfig.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            timelineByCPUTableConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            timelineByCPUTableConfig.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var utilByProcessCmdTable = new TableConfiguration("Utilization by Process Id, Thread Id, Cmd")
            {
                Columns = new[]
                {
                    nextPidColumn,
                    nextTidColumn,
                    nextCommandColumn,
                    TableConfiguration.PivotColumn,
                    cpuColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    switchInTimeColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    percentCpuUsagePreset,
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessCmdTable.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            utilByProcessCmdTable.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            utilByProcessCmdTable.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var utilByCpuTable = new TableConfiguration("Utilization by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    TableConfiguration.PivotColumn,
                    nextPidColumn,
                    nextTidColumn,
                    nextCommandColumn,
                    previousStateColumn,
                    nextThreadPreviousSwitchOutTimeColumn,
                    previousTidColumn,
                    readyingPidColumn,
                    readyingTidColumn,
                    switchInTimeColumn,
                    readyTimeColumn,
                    waitTimeColumn,
                    switchedInTimeColumn,
                    priorityColumn,
                    TableConfiguration.GraphColumn,
                    percentCpuUsagePreset,
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuTable.AddColumnRole(ColumnRole.StartTime, switchInTimeColumn);
            utilByCpuTable.AddColumnRole(ColumnRole.ResourceId, cpuColumn);
            utilByCpuTable.AddColumnRole(ColumnRole.Duration, switchedInTimeColumn);

            var table = tableBuilder.AddTableConfiguration(timelineByCPUTableConfig)
                        .AddTableConfiguration(utilByProcessCmdTable)
                        .AddTableConfiguration(utilByCpuTable)
                        .SetDefaultTableConfiguration(utilByProcessCmdTable)
                        .SetRowCount(threads.Count);

            var switchInTime  = Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchInTime);
            var switchOutTime = Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchOutTime);

            table.AddColumn(cpuColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Cpu));
            table.AddColumn(nextPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextPid));
            table.AddColumn(nextTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextTid));
            table.AddColumn(previousStateColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousState));
            table.AddColumn(nextThreadPreviousSwitchOutTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextThreadPreviousSwitchOutTime));
            table.AddColumn(previousTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousTid));
            table.AddColumn(readyingPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyingPid));
            table.AddColumn(readyingTidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyingTid));
            table.AddColumn(readyTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].ReadyTime));
            table.AddColumn(waitTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].WaitTime));
            table.AddColumn(switchedInTimeColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].SwitchOutTime - threads[i].SwitchInTime));
            table.AddColumn(priorityColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].Priority));
            table.AddColumn(switchInTimeColumn, switchInTime);
            table.AddColumn(switchOutTimeColumn, switchOutTime);
            table.AddColumn(previousPidColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousPid));
            table.AddColumn(nextCommandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].NextImage));
            table.AddColumn(previousCommandColumn, Projection.CreateUsingFuncAdaptor((i) => threads[i].PreviousImage));


            // Time the thread switching in switches out
            var viewportClippedSwitchOutTimeForNextOnCpuColumn = Projection.ClipTimeToVisibleDomain.Create(switchOutTime);

            // Switch in time is the thread switching in, which is the switch out time of the thread switching out on the CPU
            var viewportClippedSwitchOutTimeForPreviousOnCpuColumn = Projection.ClipTimeToVisibleDomain.Create(switchInTime);

            IProjection <int, TimestampDelta> cpuUsageInViewportColumn = Projection.Select(
                viewportClippedSwitchOutTimeForNextOnCpuColumn,
                viewportClippedSwitchOutTimeForPreviousOnCpuColumn,
                new ReduceTimeSinceLastDiff());

            var percentCpuUsageColumn = Projection.VisibleDomainRelativePercent.Create(cpuUsageInViewportColumn);

            var cpuUsageColumn = Projection.Select(switchOutTime, switchInTime, new ReduceTimeSinceLastDiff());

            table.AddColumn(cpuUsageInViewportPreset, cpuUsageInViewportColumn);
            table.AddColumn(cpuUsagePreset, cpuUsageColumn);
            table.AddColumn(percentCpuUsagePreset, percentCpuUsageColumn);
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var diskEvents = tableData.QueryOutput <IReadOnlyList <IDiskActivity> >(
                DataOutputPath.Create(LTTngDiskDataCooker.CookerPath + '/' + nameof(LTTngDiskDataCooker.DiskActivity)));

            if (diskEvents.Count == 0)
            {
                return;
            }

            var iosByDeviceThCmdConfig = new TableConfiguration("IOs by Device, ThreadId, Command")
            {
                Columns = new[]
                {
                    deviceIdColumn,
                    deviceNameColumn,
                    threadIdColumn,
                    commandColumn,
                    TableConfiguration.PivotColumn,
                    processIdColumn,
                    filepathColumn,
                    ioTimeSumColumn,
                    sectorNumberColumn,
                    diskOffsetColumn,
                    sizeColumn,
                    errorColumn,
                    TableConfiguration.GraphColumn,
                    insertTimeColumn,
                    issueTimeColumn,
                    completeTimeColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            var ioTimesByDevFileConfig = new TableConfiguration("IOTime by Device, FilePath")
            {
                Columns = new[]
                {
                    deviceIdColumn,
                    deviceNameColumn,
                    TableConfiguration.PivotColumn,
                    filepathColumn,
                    threadIdColumn,
                    processIdColumn,
                    commandColumn,
                    sectorNumberColumn,
                    diskOffsetColumn,
                    sizeColumn,
                    errorColumn,
                    insertTimeColumn,
                    issueTimeColumn,
                    completeTimeColumn,
                    TableConfiguration.GraphColumn,
                    ioTimeAvgColumn,
                    ioTimeMaxColumn
                },
                Layout = TableLayoutStyle.GraphAndTable,
            };

            iosByDeviceThCmdConfig.AddColumnRole(ColumnRole.StartTime, insertTimeColumn);
            // config.AddColumnRole(ColumnRole.EndTime, completeTimeColumn);
            iosByDeviceThCmdConfig.AddColumnRole(ColumnRole.ResourceId, deviceIdColumn); // We have had past behavior where specifying this causes DevId 0 not to show?

            var table = tableBuilder.AddTableConfiguration(iosByDeviceThCmdConfig)
                        .AddTableConfiguration(ioTimesByDevFileConfig)
                        .SetDefaultTableConfiguration(iosByDeviceThCmdConfig)
                        .SetRowCount((int)diskEvents.Count);

            var diskActivities = Projection.CreateUsingFuncAdaptor((i) => diskEvents[i]);

            var defaultTime = default(Timestamp);


            var ioStartTimeProjection = diskActivities.Compose(da => da.InsertTime ?? defaultTime);
            var ioEndTimeProjection   = diskActivities.Compose(da => da.CompleteTime ?? defaultTime);
            var validIoTimeProjection =
                diskActivities.Compose(da => da.InsertTime.HasValue && da.CompleteTime.HasValue);

            table.AddColumn(deviceIdColumn, diskActivities.Compose(da => da.DeviceId));
            table.AddColumn(deviceNameColumn, diskActivities.Compose(da => da.DeviceName));
            table.AddColumn(filepathColumn, diskActivities.Compose(da => da.Filepath));
            table.AddColumn(threadIdColumn, diskActivities.Compose(da => da.ThreadId));
            table.AddColumn(processIdColumn, diskActivities.Compose(da => da.ProcessId));
            table.AddColumn(commandColumn, diskActivities.Compose(da => da.ProcessCommand));
            table.AddColumn(errorColumn, diskActivities.Compose(da => da.Error));
            table.AddColumn(ioTimeIsValidColumnConfiguration, validIoTimeProjection);
            table.AddColumn(sectorNumberColumn, diskActivities.Compose(da => da.SectorNumber));
            // todo:can we pick up the sector size from the trace?
            table.AddColumn(diskOffsetColumn, diskActivities.Compose(da => new Bytes(da.SectorNumber * 512)));
            table.AddColumn(insertTimeColumn, ioStartTimeProjection);
            table.AddColumn(issueTimeColumn, diskActivities.Compose(da => da.IssueTime ?? defaultTime));
            table.AddColumn(completeTimeColumn, ioEndTimeProjection);

            var diskActivitiesProj = diskActivities.Compose((da) =>
            {
                if (da.CompleteTime.HasValue)
                {
                    if (da.InsertTime.HasValue)
                    {
                        return(da.CompleteTime.Value - da.InsertTime.Value);
                    }
                }

                return(TimestampDelta.Zero);
            });

            table.AddColumn(ioTimeAvgColumn, diskActivitiesProj);

            {
                IProjection <int, Timestamp> viewportClippedStartTimeColumn =
                    Projection.ClipTimeToViewport.Create(ioStartTimeProjection);

                IProjection <int, Timestamp> viewportClippedEndTimeColumn =
                    Projection.ClipTimeToViewport.Create(ioEndTimeProjection);

                // Timestamp delta for the given disk activity during the viewport time range.
                IProjection <int, TimestampDelta> clippedTimeDeltaColumn = Projection.Select(
                    viewportClippedEndTimeColumn,
                    viewportClippedStartTimeColumn,
                    new ReduceTimeSinceLastDiff(validIoTimeProjection));

                table.AddColumn(clippedTimestampDeltaColumnConfiguration, clippedTimeDeltaColumn);

                // Percent of time consumed by the timestamp delta in the current viewport.

                /* IProjection<int, double> ioTimeWeightPercentColumn =
                 *   Projection.ClipTimeToViewport.CreatePercent(clippedTimeDeltaColumn);*/

                /// table.AddColumn(weightedIOTimeColumn, ioTimeWeightPercentColumn);
            }

            table.AddColumn(sizeColumn, new DiskActivitySizeProjection(diskActivities));

            // IOCount with no restriction on IOSize - Used to enable some of the graphs in analyzer
            table.AddColumn(countColumn, Projection.Constant <int>(1));

            // todo: should we move the Azure specific columns here?

            // IOCount when IOSize is 8KB (such as in Azure local SSD throttling)
            table.AddColumn(countColumn_IOSize8kb, diskActivities.Compose(da => da.Size.HasValue && da.Size.Value.Bytes > 0 ? Math.Ceiling((float)da.Size.Value.Bytes / (8 * 1024)) : 1));

            // IOCount when IOSize is 256KB (such as in Azure XStore throttling)
            table.AddColumn(countColumn_IOSize256kb, diskActivities.Compose(da => da.Size.HasValue && da.Size.Value.Bytes > 0 ? Math.Ceiling((float)da.Size.Value.Bytes / (256 * 1024)) : 1));  
        }
        public static void BuildTable(ITableBuilder tableBuilder, IDataExtensionRetrieval tableData)
        {
            var pathIdentifier = DataOutputPath.ForSource(PerfConstants.SourceId, PerfCpuClockDataCooker.Identifier, nameof(PerfCpuClockDataCooker.CpuClockEvents));

            var cpuClocks = tableData.QueryOutput <IReadOnlyList <ICpuClockEvent> >(pathIdentifier);

            if (cpuClocks.Count == 0)
            {
                return;
            }

            var config = new TableConfiguration("CPU Utilization")
            {
                Columns = new[]
                {
                    cpuColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    pidColumn,
                    threadIdColumn,
                    ipColumn,
                    symbolTypeColumn,
                    ipSymbolColumn,
                    idColumn,
                    weightColumn,
                    countColumn,
                    timeStampColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
            };

            config.AddColumnRole(ColumnRole.EndTime, timeStampColumn);
            config.AddColumnRole(ColumnRole.Duration, weightColumn);
            config.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var table = tableBuilder.AddTableConfiguration(config)
                        .SetDefaultTableConfiguration(config)
                        .SetRowCount(cpuClocks.Count);

            var timeStampProjection = Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Timestamp);

            table.AddColumn(cpuColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Cpu));
            table.AddColumn(ipColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip));
            table.AddColumn(symbolTypeColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip_Symbol?.SymbolType?.SymbolTypeDescription.SymbolTypeShortName));
            table.AddColumn(ipSymbolColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Ip_Symbol?.Name));
            table.AddColumn(threadIdColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Tid));
            table.AddColumn(pidColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Pid));
            table.AddColumn(idColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Id));
            table.AddColumn(perfPeriodColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Perf_Period));
            table.AddColumn(perfCallchainSizeColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Perf_Callchain_Size));
            table.AddHierarchicalColumn(callStackColumn, Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].CallStack), new ArrayAccessProvider <string>());
            table.AddColumn(timeStampColumn, timeStampProjection);

            var oneMsSample = new TimestampDelta(1000000); // 1ms for now until we can figure out weight better
            var oneNs       = new TimestampDelta(1);
            var weightProj  = Projection.Constant(oneMsSample);

            var timeStampStartProjection = Projection.CreateUsingFuncAdaptor((i) => cpuClocks[i].Timestamp - oneNs); // We will say sample lasted 1ns
            IProjection <int, Timestamp> viewportClippedStartTimeProj = Projection.ClipTimeToVisibleDomain.Create(timeStampStartProjection);
            IProjection <int, Timestamp> viewportClippedEndTimeProj   = Projection.ClipTimeToVisibleDomain.Create(timeStampProjection);

            IProjection <int, TimestampDelta> clippedWeightProj = Projection.Select(
                viewportClippedEndTimeProj,
                viewportClippedStartTimeProj,
                new ReduceTimeSinceLastDiff());

            IProjection <int, double> weightPercentProj = Projection.VisibleDomainRelativePercent.Create(clippedWeightProj);

            IProjection <int, int> countProj = SequentialGenerator.Create(
                cpuClocks.Count,
                Projection.Constant(1),
                Projection.Constant(0));

            table.AddColumn(weightColumn, weightProj);
            table.AddColumn(countColumn, countProj);
            table.AddColumn(weightPctColumn, weightPercentProj);
            table.AddColumn(startTimeCol, timeStampStartProjection);
            table.AddColumn(viewportClippedStartTimeCol, viewportClippedStartTimeProj);
            table.AddColumn(viewportClippedEndTimeCol, viewportClippedEndTimeProj);
            table.AddColumn(clippedWeightCol, clippedWeightProj);
        }
        public override void Build(ITableBuilder tableBuilder)
        {
            if (PerfDataTxtLogParsed == null || PerfDataTxtLogParsed.Count == 0)
            {
                return;
            }

            var firstPerfDataTxtLogParsed = PerfDataTxtLogParsed.First().Value;  // First Log

            // Init
            IpStackFrames        = new ConcurrentDictionary <long, StackFrame>();
            SampleThreadDict     = new ConcurrentDictionary <long, int>();
            SampleProcessDict    = new ConcurrentDictionary <long, string>();
            SampleStackWalkEvent = new ConcurrentDictionary <long, ManualResetEvent>();

            var baseProjection = Projection.CreateUsingFuncAdaptor(new Func <int, LinuxPerfScriptStackSourceSample>(i => firstPerfDataTxtLogParsed.GetLinuxPerfScriptSampleByIndex((StackSourceSampleIndex)i)));

            // Calculate sample weights
            var sampleWeights = CalculateSampleWeights(firstPerfDataTxtLogParsed);

            var oneNs      = new TimestampDelta(1);
            var weightProj = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? TimestampDelta.Zero : new TimestampDelta(Convert.ToInt64(sampleWeights[(int)s.SampleIndex] * 1000000)));

            // Constant columns
            var sampleIndex            = baseProjection.Compose(s => (long)s.SampleIndex);
            var timeStampProjection    = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? Timestamp.Zero : new Timestamp(Convert.ToInt64(s.TimeRelativeMSec * 1000000)));
            var cpuProjection          = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? -1 : s.CpuNumber);
            var countProjection        = baseProjection.Compose(s => 1);
            var ipStackFrameProjection = baseProjection.Compose(s => GetIpStackFrame(s, firstPerfDataTxtLogParsed)?.Frame);
            var ipModuleProjection     = baseProjection.Compose(s => GetIpStackFrame(s, firstPerfDataTxtLogParsed)?.Module);
            var threadIdProjection     = baseProjection.Compose(s => GetThreadId(s, firstPerfDataTxtLogParsed));
            var processProjection      = baseProjection.Compose(s => GetProcess(s, firstPerfDataTxtLogParsed));


            // For calculating cpu %
            var timeStampStartProjection = baseProjection.Compose(s => s.SampleIndex == StackSourceSampleIndex.Invalid ? Timestamp.Zero : new Timestamp(Convert.ToInt64(s.TimeRelativeMSec * 1000000)) - new TimestampDelta(Convert.ToInt64(sampleWeights[(int)s.SampleIndex] * 1000000)));
            IProjection <int, Timestamp> viewportClippedStartTimeProj = Projection.ClipTimeToVisibleDomain.Create(timeStampStartProjection);
            IProjection <int, Timestamp> viewportClippedEndTimeProj   = Projection.ClipTimeToVisibleDomain.Create(timeStampProjection);

            IProjection <int, TimestampDelta> clippedWeightProj = Projection.Select(
                viewportClippedEndTimeProj,
                viewportClippedStartTimeProj,
                new ReduceTimeSinceLastDiff());

            IProjection <int, double> weightPercentProj = Projection.VisibleDomainRelativePercent.Create(clippedWeightProj);

            IProjection <int, int> countProj = SequentialGenerator.Create(
                firstPerfDataTxtLogParsed.SampleIndexLimit,
                Projection.Constant(1),
                Projection.Constant(0));

            //
            // Table Configurations describe how your table should be presented to the user:
            // the columns to show, what order to show them, which columns to aggregate, and which columns to graph.
            // You may provide a number of columns in your table, but only want to show a subset of them by default so as not to overwhelm the user.
            // The user can still open the table properties to turn on or off columns.
            // The table configuration class also exposes four (4) columns UI explicitly recognizes: Pivot Column, Graph Column, Left Freeze Column, Right Freeze Column
            // For more information about what these columns do, go to "Advanced Topics" -> "Table Configuration" in our Wiki. Link can be found in README.md
            //

            const string filterIdleSamplesQuery = "[IP]:=\"native_safe_halt\"";

            var utilByCpuStackConfig = new TableConfiguration("Utilization by CPU, Stack")
            {
                Columns = new[]
                {
                    cpuColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    processColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    countColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByCpuStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByCpuStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByCpuConfig = new TableConfiguration("Utilization by CPU")
            {
                Columns = new[]
                {
                    cpuColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    callStackColumn,
                    processColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByCpuConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByCpuConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByCpuConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByProcessConfig = new TableConfiguration("Utilization by Process")
            {
                Columns = new[]
                {
                    processColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    callStackColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByProcessConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByProcessConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var utilByProcessStackConfig = new TableConfiguration("Utilization by Process, Stack")
            {
                Columns = new[]
                {
                    processColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            utilByProcessStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            utilByProcessStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            utilByProcessStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            var flameByProcessStackConfig = new TableConfiguration("Flame by Process, Stack")
            {
                Columns = new[]
                {
                    processColumn,
                    callStackColumn,
                    TableConfiguration.PivotColumn,
                    countColumn,
                    cpuColumn,
                    threadIdColumn,
                    instructionPointerColumn,
                    instructionPointerModuleColumn,
                    sampleNumberColumn,
                    timestampDateTimeColumn,
                    timestampColumn,
                    weightColumn,
                    TableConfiguration.GraphColumn,
                    weightPctColumn
                },
                ChartType = ChartType.Flame,
                InitialFilterShouldKeep = false,
                InitialFilterQuery      = filterIdleSamplesQuery,
            };

            flameByProcessStackConfig.AddColumnRole(ColumnRole.EndTime, timestampColumn);
            flameByProcessStackConfig.AddColumnRole(ColumnRole.Duration, weightColumn);
            flameByProcessStackConfig.AddColumnRole(ColumnRole.ResourceId, cpuColumn);

            //
            //
            //  Use the table builder to build the table.
            //  Add and set table configuration if applicable.
            //  Then set the row count (we have one row per file) and then add the columns using AddColumn.
            //
            var table = tableBuilder
                        .AddTableConfiguration(utilByCpuStackConfig)
                        .SetDefaultTableConfiguration(utilByCpuStackConfig)
                        .AddTableConfiguration(utilByCpuConfig)
                        .AddTableConfiguration(utilByProcessConfig)
                        .AddTableConfiguration(utilByProcessStackConfig)
                        .AddTableConfiguration(flameByProcessStackConfig)
                        .SetRowCount(firstPerfDataTxtLogParsed.SampleIndexLimit)
                        .AddColumn(sampleNumberColumn, sampleIndex)
                        .AddColumn(timestampColumn, timeStampProjection)
                        .AddColumn(instructionPointerColumn, ipStackFrameProjection)
                        .AddColumn(instructionPointerModuleColumn, ipModuleProjection)
                        .AddColumn(countColumn, countProjection)
                        .AddColumn(weightColumn, weightProj)
                        .AddColumn(threadIdColumn, threadIdProjection)
                        .AddColumn(processColumn, processProjection)
                        .AddColumn(weightPctColumn, weightPercentProj)
                        .AddColumn(startTimeCol, timeStampStartProjection)
                        .AddColumn(viewportClippedStartTimeCol, viewportClippedStartTimeProj)
                        .AddColumn(viewportClippedEndTimeCol, viewportClippedEndTimeProj)
                        .AddColumn(clippedWeightCol, clippedWeightProj)
                        .AddColumn(cpuColumn, cpuProjection)
            ;

            table.AddHierarchicalColumn(callStackColumn, baseProjection.Compose((i) => GetCallStack(i, firstPerfDataTxtLogParsed)), new ArrayAccessProvider <string>());
        }