public override void Process(K key, V value) { // If the key or value is null we don't need to proceed if (key == null || value == null) { log.Warn($"Skipping record due to null key or value. key=[{key}] value=[{value}] topic=[{Context.Topic}] partition=[{Context.Partition}] offset=[{Context.Offset}]"); return; } ValueAndTimestamp <V> oldAggAndTimestamp = store.Get(key); V oldAgg, newAgg; long newTimestamp; if (oldAggAndTimestamp == null) { oldAgg = default; newAgg = value; newTimestamp = Context.Timestamp; } else { oldAgg = oldAggAndTimestamp.Value; newAgg = reducer.Apply(oldAgg, value); newTimestamp = Math.Max(Context.Timestamp, oldAggAndTimestamp.Timestamp); } store.Put(key, ValueAndTimestamp <V> .Make(newAgg, newTimestamp)); tupleForwarder.MaybeForward(key, newAgg, sendOldValues ? oldAgg : default, newTimestamp);
/// <summary> /// Dispatch action to reducers which will then apply the actions. /// Also, notifies about state change by firing StageChanged event. /// </summary> /// <typeparam name="TAction">Type of action that needs to be applied to current state.</typeparam> /// <param name="action"> /// Instance of `Action` that needs to be applied to current state of Store. /// Applying an action may transform a state into new state. /// </param> public void Dispatch <TAction>(TAction action) { var previousState = _state; var nextState = _reducer.Apply(_state, action); if (!nextState.Equals(previousState)) { _state = nextState; StateChanged?.Invoke(this, new EventArgs()); } }
public override void Process(K key, Change <V> value) { // the keys should never be null if (key == null) { throw new StreamsException($"Record key for KTable reduce operator with state {queryableStoreName} should not be null."); } ValueAndTimestamp <V> oldAggAndTimestamp = store.Get(key); V oldAgg = oldAggAndTimestamp != null ? oldAggAndTimestamp.Value : default; V intermediateAgg; long newTimestamp = Context.Timestamp; // first try to remove the old value if (oldAggAndTimestamp != null && value.OldValue != null && oldAgg != null) { intermediateAgg = substractor.Apply(oldAgg, value.OldValue); newTimestamp = Math.Max(Context.Timestamp, oldAggAndTimestamp.Timestamp); } else { intermediateAgg = oldAgg; } // then try to add the new value V newAgg; if (value.NewValue != null) { if (intermediateAgg == null) { newAgg = value.NewValue; } else { newAgg = adder.Apply(intermediateAgg, value.NewValue); } if (oldAggAndTimestamp != null) { newTimestamp = Math.Max(Context.Timestamp, oldAggAndTimestamp.Timestamp); } } else { newAgg = intermediateAgg; } // update the store with the new value store.Put(key, ValueAndTimestamp <V> .Make(newAgg, newTimestamp)); tupleForwarder.MaybeForward(key, newAgg, sendOldValues ? oldAgg : default, newTimestamp);
/// <summary> /// Reducer function to support undo/redo. /// </summary> /// <param name="previousState">Current state stored in <see cref="Store{TState}"/> object.</param> /// <param name="action">Action to be applied to state.</param> /// <returns>New state after applying action.</returns> public UndoableState <TState> Apply(UndoableState <TState> previousState, object action) { TState present; switch (action) { case Undo undoAction: if (previousState.Past.Count > 0) { List <TState> past = previousState.Past.ToList(); List <TState> future = previousState.Future.ToList(); present = past.Last(); future.Add(previousState.Present); past.RemoveAt(past.Count - 1); return(new UndoableState <TState>(present, new ReadOnlyCollection <TState>(past), new ReadOnlyCollection <TState>(future))); } return(previousState); case Redo redoAction: if (previousState.Future.Count > 0) { List <TState> past = previousState.Past.ToList(); List <TState> future = previousState.Future.ToList(); present = future.Last(); past.Add(previousState.Present); future.RemoveAt(future.Count - 1); return(new UndoableState <TState>(present, new ReadOnlyCollection <TState>(past), new ReadOnlyCollection <TState>(future))); } return(previousState); default: { List <TState> past = previousState.Past.ToList(); List <TState> future = new List <TState>(); past.Add(previousState.Present); present = _innerReducer.Apply(previousState.Present, action); return(new UndoableState <TState>(present, new ReadOnlyCollection <TState>(past), new ReadOnlyCollection <TState>(future))); } } }