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) { 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 <T> UpdateStateTable(DriverStateTable.Builder graphState, NodeStateTable <T> previousTable, CancellationToken cancellationToken) { var stopwatch = SharedStopwatch.StartNew(); var inputItems = _getInput(graphState); TimeSpan elapsedTime = stopwatch.Elapsed; // create a mutable hashset of the new items we can check against HashSet <T> itemsSet = new HashSet <T>(_inputComparer); foreach (var item in inputItems) { var added = itemsSet.Add(item); Debug.Assert(added); } var builder = graphState.CreateTableBuilder(previousTable, _name, _comparer); // We always have no inputs steps into an InputNode, but we track the difference between "no inputs" (empty collection) and "no step information" (default value) var noInputStepsStepInfo = builder.TrackIncrementalSteps ? ImmutableArray <(IncrementalGeneratorRunStep, int)> .Empty : 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 <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()); }