Exemple #1
0
        internal double Evaluate( Cdef cdef, int row, long timestamp )
        {
            stack.Clear();

            byte[] tokens 		= cdef.Tokens;
            int[] dsIndices		= cdef.DsIndices;
            double[] constants	= cdef.Constants;

            Random autoRand = new Random();

            double x1, x2, x3;

            for ( int i = 0; i < tokens.Length; i++ )
            {
                switch ( tokens[i] )
                {
                    case TKN_CONSTANT:
                        Push( constants[i] );
                        break;

                    case TKN_DATASOURCE:
                        Push( sources[ dsIndices[i] ].Get(row) );
                        break;

                    case TKN_PLUS:
                        Push(Pop() + Pop());
                        break;

                    case TKN_MINUS:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 - x2);
                        break;

                    case TKN_MULTIPLY:
                        Push(Pop() * Pop());
                        break;

                    case TKN_DIVIDE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 / x2);
                        break;

                    case TKN_MOD:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 % x2);
                        break;

                    case TKN_SIN:
                        Push(Math.Sin(Pop()));
                        break;

                    case TKN_COS:
                        Push(Math.Cos(Pop()));
                        break;

                    case TKN_LOG:
                        Push(Math.Log(Pop()));
                        break;

                    case TKN_EXP:
                        Push(Math.Exp(Pop()));
                        break;

                    case TKN_FLOOR:
                        Push(Math.Floor(Pop()));
                        break;

                    case TKN_CEIL:
                        Push(Math.Ceiling(Pop()));
                        break;

                    case TKN_ROUND:
                        Push(Math.Round(Pop(), MidpointRounding.AwayFromZero));
                        break;

                    case TKN_POW:
                        x2 = Pop();
                        x1 = Pop();
                        Push(Math.Pow(x1, x2));
                        break;

                    case TKN_ABS:
                        Push(Math.Abs(Pop()));
                        break;

                    case TKN_SQRT:
                        Push(Math.Sqrt(Pop()));
                        break;

                    case TKN_RANDOM:
                        Push(autoRand.Next());
                        break;

                    case TKN_LT:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 < x2? 1: 0);
                        break;

                    case TKN_LE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 <= x2? 1: 0);
                        break;

                    case TKN_GT:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 > x2? 1: 0);
                        break;

                    case TKN_GE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 >= x2? 1: 0);
                        break;

                    case TKN_EQ:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 == x2? 1: 0);
                        break;

                    case TKN_IF:
                        x3 = Pop();
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 != 0 ? x2: x3);
                        break;

                    case TKN_MIN:
                        Push(Math.Min(Pop(), Pop()));
                        break;

                    case TKN_MAX:
                        Push(Math.Max(Pop(), Pop()));
                        break;

                    case TKN_LIMIT:
                        double high = Pop(), low = Pop(), val = Pop();
                        Push(val < low || val > high? Double.NaN: val);
                        break;

                    case TKN_DUP:
                        double x = Pop();
                        Push(x);
                        Push(x);
                        break;

                    case TKN_EXC:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x2);
                        Push(x1);
                        break;

                    case TKN_POP:
                        Pop();
                        break;

                    case TKN_UN:
                        Push(Double.IsNaN(Pop())? 1: 0);
                        break;

                    case TKN_UNKN:
                        Push(Double.NaN);
                        break;

                    case TKN_NOW:
                        Push(Util.Time);
                        break;

                    case TKN_TIME:
                        Push(timestamp);
                        break;

                    case TKN_PI:
                        Push(Math.PI);
                        break;

                    case TKN_E:
                        Push(Math.E);
                        break;

                    case TKN_AND:
                        x2 = Pop();
                        x1 = Pop();
                        Push((x1 != 0 && x2 != 0)? 1: 0);
                        break;

                    case TKN_OR:
                        x2 = Pop();
                        x1 = Pop();
                        Push((x1 != 0 || x2 != 0)? 1: 0);
                        break;

                    case TKN_XOR:
                        x2 = Pop();
                        x1 = Pop();
                        Push(((x1 != 0 && x2 == 0) || (x1 == 0 && x2 != 0))? 1: 0);
                        break;

                    case TKN_SAMPLES:
                        Push (cdef.SampleCount);
                        break;

                    case TKN_STEP:
                        Push( step );
                        break;
                }
            }

            if (stack.Count != 1)
                throw new RrdException("RPN error, invalid stack length");

            return Pop();
        }
        internal double Evaluate( Cdef cdef, int row, long timestamp )
        {
            stack.Clear();

            byte[] tokens 		= cdef.Tokens;
            int[] dsIndices		= cdef.DsIndices;
            double[] constants	= cdef.Constants;

            Random autoRand = new Random();

            double x1, x2, x3;

            for ( int i = 0; i < tokens.Length; i++ )
            {
                switch ( tokens[i] )
                {
                    case TKN_CONSTANT:
                        Push( constants[i] );
                        break;

                    case TKN_DATASOURCE:
                        Push( sources[ dsIndices[i] ].Get(row) );
                        break;

                    case TKN_PLUS:
                        Push(Pop() + Pop());
                        break;

                    case TKN_MINUS:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 - x2);
                        break;

                    case TKN_MULTIPLY:
                        Push(Pop() * Pop());
                        break;

                    case TKN_DIVIDE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 / x2);
                        break;

                    case TKN_MOD:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 % x2);
                        break;

                    case TKN_SIN:
                        Push(Math.Sin(Pop()));
                        break;

                    case TKN_COS:
                        Push(Math.Cos(Pop()));
                        break;

                    case TKN_LOG:
                        Push(Math.Log(Pop()));
                        break;

                    case TKN_EXP:
                        Push(Math.Exp(Pop()));
                        break;

                    case TKN_FLOOR:
                        Push(Math.Floor(Pop()));
                        break;

                    case TKN_CEIL:
                        Push(Math.Ceiling(Pop()));
                        break;

                    case TKN_ROUND:
                        Push(Math.Round(Pop(), MidpointRounding.AwayFromZero));
                        break;

                    case TKN_POW:
                        x2 = Pop();
                        x1 = Pop();
                        Push(Math.Pow(x1, x2));
                        break;

                    case TKN_ABS:
                        Push(Math.Abs(Pop()));
                        break;

                    case TKN_SQRT:
                        Push(Math.Sqrt(Pop()));
                        break;

                    case TKN_RANDOM:
                        Push(autoRand.Next());
                        break;

                    case TKN_LT:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 < x2? 1: 0);
                        break;

                    case TKN_LE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 <= x2? 1: 0);
                        break;

                    case TKN_GT:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 > x2? 1: 0);
                        break;

                    case TKN_GE:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 >= x2? 1: 0);
                        break;

                    case TKN_EQ:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 == x2? 1: 0);
                        break;

                    case TKN_IF:
                        x3 = Pop();
                        x2 = Pop();
                        x1 = Pop();
                        Push(x1 != 0 ? x2: x3);
                        break;

                    case TKN_MIN:
                        Push(Math.Min(Pop(), Pop()));
                        break;

                    case TKN_MAX:
                        Push(Math.Max(Pop(), Pop()));
                        break;

                    case TKN_LIMIT:
                        double high = Pop(), low = Pop(), val = Pop();
                        Push(val < low || val > high? Double.NaN: val);
                        break;

                    case TKN_DUP:
                        double x = Pop();
                        Push(x);
                        Push(x);
                        break;

                    case TKN_EXC:
                        x2 = Pop();
                        x1 = Pop();
                        Push(x2);
                        Push(x1);
                        break;

                    case TKN_POP:
                        Pop();
                        break;

                    case TKN_UN:
                        Push(Double.IsNaN(Pop())? 1: 0);
                        break;

                    case TKN_UNKN:
                        Push(Double.NaN);
                        break;

                    case TKN_NOW:
                        Push(Util.Time);
                        break;

                    case TKN_TIME:
                        Push(timestamp);
                        break;

                    case TKN_PI:
                        Push(Math.PI);
                        break;

                    case TKN_E:
                        Push(Math.E);
                        break;

                    case TKN_AND:
                        x2 = Pop();
                        x1 = Pop();
                        Push((x1 != 0 && x2 != 0)? 1: 0);
                        break;

                    case TKN_OR:
                        x2 = Pop();
                        x1 = Pop();
                        Push((x1 != 0 || x2 != 0)? 1: 0);
                        break;

                    case TKN_XOR:
                        x2 = Pop();
                        x1 = Pop();
                        Push(((x1 != 0 && x2 == 0) || (x1 == 0 && x2 != 0))? 1: 0);
                        break;

                    case TKN_SAMPLES:
                        Push (cdef.SampleCount);
                        break;

                    case TKN_STEP:
                        Push( step );
                        break;

                    case TKN_TREND:
                        double seconds = Pop();
                        double value = Pop();
                        double trend = Double.NaN;

                        // Is this the first value?
                        if (this.TrendWindowStart == 0)
                            this.TrendWindowStart = timestamp;

                        // Add new value
                        this.TrendValues.Add(value);

                        // To we have a full window?
                        if (timestamp >= this.TrendWindowStart + seconds)
                        {
                            //this.TrendWindowStart = timestamp;

                            double sum = 0;
                            // Sum up all values
                            for (int v = 0; v < this.TrendValues.Count; v++)
                            {
                                sum += this.TrendValues[v];
                            }

                            // Calc average, i.e. trend
                            trend = sum / this.TrendValues.Count;

                            // Remove oldest value
                            this.TrendValues.RemoveAt(0);
                        }

                        // Return the calculated point
                        Push(trend);
                        break;
                }
            }

            if (stack.Count != 1)
                throw new RrdException("RPN error, invalid stack length");

            return Pop();
        }