/// <summary>
        /// Atomically updates the field of the given object managed by this
        /// updater with the results of applying the given function to the
        /// current and given values, returning the updated value. The
        /// function should be side-effect-free, since it may be re-applied
        /// when attempted updates fail due to contention among threads.  The
        /// function is applied with the current value as its first argument,
        /// and the given update as the second argument.
        /// </summary>
        /// <param name="obj"> An object whose field to get and set </param>
        /// <param name="x"> the update value </param>
        /// <param name="accumulatorFunction"> a side-effect-free function of two arguments </param>
        /// <returns> the updated value
        /// @since 1.8 </returns>
        public V AccumulateAndGet(T obj, V x, BinaryOperator <V> accumulatorFunction)
        {
            V prev, next;

            do
            {
                prev = Get(obj);
                next = accumulatorFunction.Apply(prev, x);
            } while (!CompareAndSet(obj, prev, next));
            return(next);
        }
Exemple #2
0
        /// <summary>
        /// Atomically updates the current value with the results of
        /// applying the given function to the current and given values,
        /// returning the previous value. The function should be
        /// side-effect-free, since it may be re-applied when attempted
        /// updates fail due to contention among threads.  The function
        /// is applied with the current value as its first argument,
        /// and the given update as the second argument.
        /// </summary>
        /// <param name="x"> the update value </param>
        /// <param name="accumulatorFunction"> a side-effect-free function of two arguments </param>
        /// <returns> the previous value
        /// @since 1.8 </returns>
        public V GetAndAccumulate(V x, BinaryOperator <V> accumulatorFunction)
        {
            V prev, next;

            do
            {
                prev = Get();
                next = accumulatorFunction.Apply(prev, x);
            } while (!CompareAndSet(prev, next));
            return(prev);
        }
        /// <summary>
        /// Atomically updates the element at index {@code i} with the
        /// results of applying the given function to the current and
        /// given values, returning the updated value. The function should
        /// be side-effect-free, since it may be re-applied when attempted
        /// updates fail due to contention among threads.  The function is
        /// applied with the current value at index {@code i} as its first
        /// argument, and the given update as the second argument.
        /// </summary>
        /// <param name="i"> the index </param>
        /// <param name="x"> the update value </param>
        /// <param name="accumulatorFunction"> a side-effect-free function of two arguments </param>
        /// <returns> the updated value
        /// @since 1.8 </returns>
        public E AccumulateAndGet(int i, E x, BinaryOperator <E> accumulatorFunction)
        {
            long offset = CheckedByteOffset(i);
            E    prev, next;

            do
            {
                prev = GetRaw(offset);
                next = accumulatorFunction.Apply(prev, x);
            } while (!CompareAndSetRaw(offset, prev, next));
            return(next);
        }
Exemple #4
0
        private static IElementValue EvaluateExpression(IList <Element> data, IObjectResolver dc)
        {
            if (data.Count == 0)
            {
                return(null);
            }
            Stack <IElementValue> output = new Stack <IElementValue>();

            for (int j = 0; j < data.Count; j++)
            {
                Element element = data[j];
                switch (element.Type)
                {
                case TokenType.BinaryOperator:
                    ElementBinaryOperator binaryElement  = (ElementBinaryOperator)element;
                    BinaryOperator        binaryOperator = (BinaryOperator)binaryElement.Operator;
                    IElementValue         b2             = output.Pop();
                    IElementValue         b1             = output.Pop();
                    IElementValue         binaryOutput   = binaryOperator.Apply(b1, b2);
                    output.Push(binaryOutput);
                    break;

                case TokenType.UnitaryOperator:
                    ElementUnitaryOperator unitaryElement  = (ElementUnitaryOperator)element;
                    UnitaryOperator        unitaryOperator = (UnitaryOperator)unitaryElement.Operator;
                    IElementValue          u1            = output.Pop();
                    IElementValue          unitaryOutput = unitaryOperator.Apply(u1);
                    output.Push(unitaryOutput);
                    break;

                case TokenType.Function:
                    ElementFunction  functionElement  = (ElementFunction)element;
                    FunctionOperator functionOperator = (FunctionOperator)functionElement.Operator;
                    IElementValue[]  paramVals        = new IElementValue[functionElement.Parameters.Count];
                    for (int paramIndex = 0; paramIndex < functionElement.Parameters.Count; paramIndex++)
                    {
                        paramVals[paramIndex] = EvaluateExpression(functionElement.Parameters[paramIndex], dc);
                    }
                    IElementValue functionOutput = functionOperator.Apply(paramVals);
                    output.Push(functionOutput);
                    break;

                case TokenType.DecimalLiteral:
                case TokenType.IntegerLiteral:
                case TokenType.StringLiteral:
                case TokenType.BooleanLiteral:
                case TokenType.Selector:
                    output.Push((IElementValue)element);
                    break;

                case TokenType.OpenParenthesis:
                    int             parenthesis         = 1;
                    IList <Element> parenthesisElements = new List <Element>();
                    for (j = j + 1; j < data.Count; j++)
                    {
                        Element parenthesisElement = data[j];
                        if (parenthesisElement.Type == TokenType.OpenParenthesis)
                        {
                            parenthesis++;
                        }
                        else if (parenthesisElement.Type == TokenType.CloseParenthesis)
                        {
                            parenthesis--;
                            if (parenthesis == 0)
                            {
                                IElementValue parenthesisOutput = EvaluateExpression(parenthesisElements, dc);
                                output.Push(parenthesisOutput);
                                break;
                            }
                        }
                        else
                        {
                            parenthesisElements.Add(parenthesisElement);
                        }
                    }
                    break;

                case TokenType.TernaryIf:
                    IElementValue ternaryIfValue = output.Pop();
                    if (ternaryIfValue.Type != TokenType.BooleanLiteral)
                    {
                        throw new ELException("Condition is not boolean.");
                    }
                    bool            condition       = (bool)ternaryIfValue.Value;
                    IList <Element> ternaryElements = new List <Element>();
                    bool            elseReached     = false;
                    for (j = j + 1; j < data.Count; j++)
                    {
                        Element conditionValue = data[j];
                        if (conditionValue.Type == TokenType.TernaryElse)
                        {
                            elseReached = true;
                        }
                        if (condition == true)
                        {
                            if (elseReached == true)
                            {
                                j = data.Count;
                                break;
                            }
                            ternaryElements.Add(conditionValue);
                        }
                        else
                        {
                            if (elseReached == true)
                            {
                                ternaryElements.Add(conditionValue);
                            }
                        }
                    }
                    IElementValue ternaryOutput = EvaluateExpression(ternaryElements, dc);
                    output.Push(ternaryOutput);
                    break;

                case TokenType.Variable:
                    StringBuilder variableStr = new StringBuilder();
                    string        expression;
                    expression = ((ElementVariable)element).Expression;
                    variableStr.Append(expression);
                    bool variableBoundryHit = false;
                    bool end = false;
                    while (j + 1 < data.Count && end == false)
                    {
                        switch (data[j + 1].Type)
                        {
                        case TokenType.Variable:
                            if (!variableBoundryHit)
                            {
                                end = true;
                                break;
                            }
                            j++;
                            variableStr.Append(((ElementVariable)data[j]).Expression);
                            variableBoundryHit = false;
                            break;

                        case TokenType.OpenBracket:
                            j++;
                            int brackets = 1;
                            variableBoundryHit = true;
                            IList <Element> bracketElements = new List <Element>();
                            for (j = j + 1; j < data.Count; j++)
                            {
                                Element bracketElement = data[j];
                                if (bracketElement.Type == TokenType.OpenBracket)
                                {
                                    brackets++;
                                }
                                else if (bracketElement.Type == TokenType.CloseBracket)
                                {
                                    brackets--;
                                    if (brackets == 0)
                                    {
                                        IElementValue bracketOutput = EvaluateExpression(bracketElements, dc);
                                        if (bracketOutput.Type != TokenType.IntegerLiteral &&
                                            bracketOutput.Type != TokenType.Selector)
                                        {
                                            throw new ELException("Integers and Selectors can only be used as brackets indexes.");
                                        }
                                        variableStr.Append("[").Append(bracketOutput.Value).Append("]");
                                        break;
                                    }
                                }
                                else
                                {
                                    bracketElements.Add(bracketElement);
                                }
                            }
                            break;

                        case TokenType.Dot:
                            j++;
                            variableBoundryHit = true;
                            variableStr.Append(".");
                            break;

                        default:
                            end = true;
                            break;
                        }
                    }

                    object        value = dc.GetVariableObject(variableStr.ToString());
                    IElementValue elementValue;
                    if (value is string)
                    {
                        elementValue = new ElementLiteral(TokenType.StringLiteral, value);
                    }
                    else if (value is bool)
                    {
                        elementValue = new ElementLiteral(TokenType.BooleanLiteral, value);
                    }
                    else if (value is int)
                    {
                        elementValue = new ElementLiteral(TokenType.IntegerLiteral, value);
                    }
                    else if (value is double || value is float || value is decimal)
                    {
                        elementValue = new ElementLiteral(TokenType.DecimalLiteral, Convert.ToDouble(value));
                    }
                    else
                    {
                        elementValue = new ElementLiteral(TokenType.Object, value);
                    }
                    output.Push(elementValue);
                    break;
                }
            }
            if (output.Count != 1)
            {
                throw new ELException("Error evaluating expression");
            }
            return((IElementValue)output.Pop());
        }