public NodeStateTable <ImmutableArray <TInput> > UpdateStateTable(DriverStateTable.Builder builder, NodeStateTable <ImmutableArray <TInput> > previousTable, CancellationToken cancellationToken) { // grab the source inputs var sourceTable = builder.GetLatestStateTableForNode(_sourceNode); // Semantics of a batch transform: // Batches will always exist (a batch of the empty table is still []) // There is only ever one input, the batch of the upstream table // - Output is cached when upstream is all cached // - Added when the previous table was empty // - Modified otherwise var source = sourceTable.Batch(); // update the table var newTable = previousTable.ToBuilder(); if (!sourceTable.IsCached || !newTable.TryUseCachedEntries()) { if (!newTable.TryModifyEntry(source, _comparer)) { newTable.AddEntry(source, EntryState.Added); } } return(newTable.ToImmutableAndFree()); }
public NodeStateTable <TOutput> UpdateStateTable(DriverStateTable.Builder builder, NodeStateTable <TOutput> previousTable, CancellationToken cancellationToken) { // grab the source inputs var sourceTable = builder.GetLatestStateTableForNode(_sourceNode); if (sourceTable.IsCached) { if (builder.DriverState.TrackIncrementalSteps) { return(previousTable.CreateCachedTableWithUpdatedSteps(sourceTable, _name)); } return(previousTable); } // Semantics of a transform: // Element-wise comparison of upstream table // - Cached or Removed: no transform, just use previous values // - Added: perform transform and add // - Modified: perform transform and do element wise comparison with previous results var newTable = builder.CreateTableBuilder(previousTable, _name); foreach (var entry in sourceTable) { var inputs = newTable.TrackIncrementalSteps ? ImmutableArray.Create((entry.Step !, entry.OutputIndex)) : default;
public NodeStateTable <TOutput> UpdateStateTable(DriverStateTable.Builder graphState, NodeStateTable <TOutput> previousTable, CancellationToken cancellationToken) { var sourceTable = graphState.GetLatestStateTableForNode(_source); if (sourceTable.IsCached) { return(previousTable); } var nodeTable = previousTable.ToBuilder(); foreach (var entry in sourceTable) { if (entry.state == EntryState.Removed) { nodeTable.RemoveEntries(); } else if (entry.state != EntryState.Cached || !nodeTable.TryUseCachedEntries()) { // we don't currently handle modified any differently than added at the output // we just run the action and mark the new source as added. In theory we could compare // the diagnostics and sources produced and compare them, to see if they are any different // than before. var sourcesBuilder = ArrayBuilder <GeneratedSourceText> .GetInstance(); var diagnostics = DiagnosticBag.GetInstance(); SourceProductionContext context = new SourceProductionContext(sourcesBuilder, diagnostics, cancellationToken); try { _action(context, entry.item); nodeTable.AddEntry((sourcesBuilder.ToImmutable(), diagnostics.ToReadOnly()), EntryState.Added); } finally { sourcesBuilder.Free(); diagnostics.Free(); } } } return(nodeTable.ToImmutableAndFree()); }
public NodeStateTable <TOutput> UpdateStateTable(DriverStateTable.Builder graphState, NodeStateTable <TOutput> previousTable, CancellationToken cancellationToken) { string stepName = Kind == IncrementalGeneratorOutputKind.Source ? WellKnownGeneratorOutputs.SourceOutput : WellKnownGeneratorOutputs.ImplementationSourceOutput; var sourceTable = graphState.GetLatestStateTableForNode(_source); if (sourceTable.IsCached) { if (graphState.DriverState.TrackIncrementalSteps) { return(previousTable.CreateCachedTableWithUpdatedSteps(sourceTable, stepName)); } return(previousTable); } var nodeTable = graphState.CreateTableBuilder(previousTable, stepName); foreach (var entry in sourceTable) { var inputs = nodeTable.TrackIncrementalSteps ? ImmutableArray.Create((entry.Step !, entry.OutputIndex)) : default;
public NodeStateTable <ImmutableArray <TInput> > UpdateStateTable(DriverStateTable.Builder builder, NodeStateTable <ImmutableArray <TInput> > previousTable, CancellationToken cancellationToken) { // grab the source inputs var sourceTable = builder.GetLatestStateTableForNode(_sourceNode); // Semantics of a batch transform: // Batches will always exist (a batch of the empty table is still []) // There is only ever one input, the batch of the upstream table // - Output is cached when upstream is all cached // - Added when the previous table was empty // - Modified otherwise // update the table var newTable = builder.CreateTableBuilder(previousTable, _name); // If this execution is tracking steps, then the source table should have also tracked steps or be the empty table. Debug.Assert(!newTable.TrackIncrementalSteps || (sourceTable.HasTrackedSteps || sourceTable.IsEmpty)); var stopwatch = SharedStopwatch.StartNew(); var batchedSourceEntries = sourceTable.Batch(); var sourceValues = batchedSourceEntries.SelectAsArray(sourceEntry => sourceEntry.State != EntryState.Removed, sourceEntry => sourceEntry.Item); var sourceInputs = newTable.TrackIncrementalSteps ? batchedSourceEntries.SelectAsArray(sourceEntry => (sourceEntry.Step !, sourceEntry.OutputIndex)) : default;
public NodeStateTable <TOutput> UpdateStateTable(DriverStateTable.Builder builder, NodeStateTable <TOutput> previousTable, CancellationToken cancellationToken) { // grab the source inputs var sourceTable = builder.GetLatestStateTableForNode(_sourceNode); if (sourceTable.IsCached) { return(previousTable); } // Semantics of a transform: // Element-wise comparison of upstream table // - Cached or Removed: no transform, just use previous values // - Added: perform transform and add // - Modified: perform transform and do element wise comparison with previous results var newTable = previousTable.ToBuilder(); foreach (var entry in sourceTable) { if (entry.state == EntryState.Removed) { newTable.RemoveEntries(); } else if (entry.state != EntryState.Cached || !newTable.TryUseCachedEntries()) { // generate the new entries var newOutputs = _func(entry.item, cancellationToken); if (entry.state != EntryState.Modified || !newTable.TryModifyEntries(newOutputs, _comparer)) { newTable.AddEntries(newOutputs, EntryState.Added); } } } return(newTable.ToImmutableAndFree()); }
public NodeStateTable <ImmutableArray <TInput> > UpdateStateTable(DriverStateTable.Builder builder, NodeStateTable <ImmutableArray <TInput> > previousTable, CancellationToken cancellationToken) { // grab the source inputs var sourceTable = builder.GetLatestStateTableForNode(_sourceNode); // Semantics of a batch transform: // Batches will always exist (a batch of the empty table is still []) // There is only ever one input, the batch of the upstream table // - Output is cached when upstream is all cached // - Added when the previous table was empty // - Modified otherwise // update the table var newTable = builder.CreateTableBuilder(previousTable, _name, _comparer); // If this execution is tracking steps, then the source table should have also tracked steps or be the empty table. Debug.Assert(!newTable.TrackIncrementalSteps || (sourceTable.HasTrackedSteps || sourceTable.IsEmpty)); var stopwatch = SharedStopwatch.StartNew(); var(sourceValues, sourceInputs) = GetValuesAndInputs(sourceTable, previousTable, newTable); if (previousTable.IsEmpty) { newTable.AddEntry(sourceValues, EntryState.Added, stopwatch.Elapsed, sourceInputs, EntryState.Added); } else if (!sourceTable.IsCached || !newTable.TryUseCachedEntries(stopwatch.Elapsed, sourceInputs)) { if (!newTable.TryModifyEntry(sourceValues, _comparer, stopwatch.Elapsed, sourceInputs, EntryState.Modified)) { newTable.AddEntry(sourceValues, EntryState.Added, stopwatch.Elapsed, sourceInputs, EntryState.Added); } } return(newTable.ToImmutableAndFree()); }