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);
예제 #2
0
        /// <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);
예제 #4
0
        /// <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)));
            }
            }
        }