KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > graph > Cdef


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org)
7  *
8  * Developers: Sasa Markovic (saxon@jrobin.org)
9  * Arne Vandamme (cobralord@jrobin.org)
10  *
11  * (C) Copyright 2003, by Sasa Markovic.
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25 package org.jrobin.graph;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import org.jrobin.core.RrdException;
31 import org.jrobin.core.XmlWriter;
32
33 /**
34  * <p>Represents a 'calculated' datasource for a graph. A calculated datasource is always based on a RPN
35  * (Reverse Polar Notation) expression the algorithm to be used for calculating values.</p>
36  *
37  * @author Arne Vandamme (cobralord@jrobin.org)
38  */

39 class Cdef extends Source
40 {
41     // ================================================================
42
// -- Members
43
// ================================================================
44
private String JavaDoc[] strTokens;
45         
46     private double[] constants;
47     private int[] dsIndices;
48     private byte[] tokens;
49     
50     
51     // ================================================================
52
// -- Constructors
53
// ================================================================
54
/**
55      * Constructs a new simple Cdef object based on an empty RPN expression,.
56      *
57      * @param name Name of the datasource in the graph definition.
58      */

59     Cdef( String JavaDoc name )
60     {
61         super( name );
62
63         strTokens = new String JavaDoc[0];
64     }
65
66     /**
67      * Constructs a new Cdef object holding a number of datapoints for a graph.
68      * A Cdef is always based on a RPN expression holding the calculation algorithm.
69      * @param name Name of the datasource in the graph definition.
70      * @param rpn Algorithm to use for value calculation in reverse polar notation (RPN) form.
71      */

72     Cdef( String JavaDoc name, String JavaDoc rpn )
73     {
74         super(name);
75         
76         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(rpn, ",");
77         int count = st.countTokens();
78         strTokens = new String JavaDoc[count];
79         
80         for( int i = 0; st.hasMoreTokens(); i++ )
81             strTokens[i] = st.nextToken().trim();
82     }
83
84
85     // ================================================================
86
// -- Protected methods
87
// ================================================================
88
/**
89      * Prepares the Cdef for faster value calculation by parsing the given RPN expression to
90      * a better more efficient format.
91      * @param sourceIndex Lookup table holding the name - index pairs for all datasources.
92      * @param numPoints Number of points used as graph resolution (size of the value table).
93      * @throws RrdException Thrown in case of a JRobin specific error.
94      */

95     void prepare( HashMap JavaDoc sourceIndex, int numPoints, int aggregatePoints ) throws RrdException
96     {
97         // Create values table of correct size
98
values = new double[numPoints];
99         this.aggregatePoints = aggregatePoints;
100
101         // Parse rpn expression for better performance
102
String JavaDoc tkn;
103         
104         constants = new double[ strTokens.length ];
105         dsIndices = new int[ strTokens.length ];
106         tokens = new byte[ strTokens.length ];
107         
108         for (int i = 0; i < strTokens.length; i++)
109         {
110             tkn = strTokens[i];
111             
112             if ( isNumber(tkn) ) {
113                 tokens[i] = RpnCalculator.TKN_CONSTANT;
114                 constants[i] = Double.parseDouble(tkn);
115             }
116             else if ( sourceIndex.containsKey(tkn) ) {
117                 tokens[i] = RpnCalculator.TKN_DATASOURCE;
118                 dsIndices[i] = ( (Integer JavaDoc) sourceIndex.get(tkn) ).intValue();
119             }
120             else if ( tkn.equals("+") )
121                 tokens[i] = RpnCalculator.TKN_PLUS;
122             else if ( tkn.equals("-") )
123                 tokens[i] = RpnCalculator.TKN_MINUS;
124             else if ( tkn.equals("*") )
125                 tokens[i] = RpnCalculator.TKN_MULTIPLY;
126             else if ( tkn.equals("/") )
127                 tokens[i] = RpnCalculator.TKN_DIVIDE;
128             else if ( tkn.equals("%") )
129                 tokens[i] = RpnCalculator.TKN_MOD;
130             else if ( tkn.equals("SIN") )
131                 tokens[i] = RpnCalculator.TKN_SIN;
132             else if ( tkn.equals("COS") )
133                 tokens[i] = RpnCalculator.TKN_COS;
134             else if ( tkn.equals("LOG") )
135                 tokens[i] = RpnCalculator.TKN_LOG;
136             else if ( tkn.equals("EXP") )
137                 tokens[i] = RpnCalculator.TKN_EXP;
138             else if ( tkn.equals("FLOOR") )
139                 tokens[i] = RpnCalculator.TKN_FLOOR;
140             else if ( tkn.equals("CEIL") )
141                 tokens[i] = RpnCalculator.TKN_CEIL;
142             else if ( tkn.equals("ROUND") )
143                 tokens[i] = RpnCalculator.TKN_ROUND;
144             else if ( tkn.equals("POW") )
145                 tokens[i] = RpnCalculator.TKN_POW;
146             else if ( tkn.equals("ABS") )
147                 tokens[i] = RpnCalculator.TKN_ABS;
148             else if ( tkn.equals("SQRT") )
149                 tokens[i] = RpnCalculator.TKN_SQRT;
150             else if ( tkn.equals("RANDOM") )
151                 tokens[i] = RpnCalculator.TKN_RANDOM;
152             else if ( tkn.equals("LT") )
153                 tokens[i] = RpnCalculator.TKN_LT;
154             else if ( tkn.equals("LE") )
155                 tokens[i] = RpnCalculator.TKN_LE;
156             else if ( tkn.equals("GT") )
157                 tokens[i] = RpnCalculator.TKN_GT;
158             else if ( tkn.equals("GE") )
159                 tokens[i] = RpnCalculator.TKN_GE;
160             else if ( tkn.equals("EQ") )
161                 tokens[i] = RpnCalculator.TKN_EQ;
162             else if ( tkn.equals("IF") )
163                 tokens[i] = RpnCalculator.TKN_IF;
164             else if ( tkn.equals("MIN") )
165                 tokens[i] = RpnCalculator.TKN_MIN;
166             else if ( tkn.equals("MAX") )
167                 tokens[i] = RpnCalculator.TKN_MAX;
168             else if ( tkn.equals("LIMIT") )
169                 tokens[i] = RpnCalculator.TKN_LIMIT;
170             else if ( tkn.equals("DUP") )
171                 tokens[i] = RpnCalculator.TKN_DUP;
172             else if ( tkn.equals("EXC") )
173                 tokens[i] = RpnCalculator.TKN_EXC;
174             else if ( tkn.equals("POP") )
175                 tokens[i] = RpnCalculator.TKN_POP;
176             else if ( tkn.equals("UN") )
177                 tokens[i] = RpnCalculator.TKN_UN;
178             else if ( tkn.equals("UNKN") )
179                 tokens[i] = RpnCalculator.TKN_UNKN;
180             else if ( tkn.equals("NOW") )
181                 tokens[i] = RpnCalculator.TKN_NOW;
182             else if ( tkn.equals("TIME") )
183                 tokens[i] = RpnCalculator.TKN_TIME;
184             else if ( tkn.equals("PI") )
185                 tokens[i] = RpnCalculator.TKN_PI;
186             else if ( tkn.equals("E") )
187                 tokens[i] = RpnCalculator.TKN_E;
188             else if ( tkn.equals("AND") )
189                 tokens[i] = RpnCalculator.TKN_AND;
190             else if ( tkn.equals("OR") )
191                 tokens[i] = RpnCalculator.TKN_OR;
192             else if ( tkn.equals("XOR") )
193                 tokens[i] = RpnCalculator.TKN_XOR;
194             // Extra tokens for JRobin
195
else if ( tkn.equals("SAMPLES") )
196                 tokens[i] = RpnCalculator.TKN_SAMPLES;
197             else if ( tkn.equals("STEP") )
198                 tokens[i] = RpnCalculator.TKN_STEP;
199             else
200                 throw new RrdException("Unknown token encountered: " + tkn);
201             
202         }
203     }
204
205     /**
206      * Returns the level this Cdef would have in the calculation tree. The level defines when
207      * the Cdef can be calculated. The level depends on the number of Sdefs this Cdef is depending
208      * on, and their corresponding calculation levels.
209      *
210      * @param levels Array containing the previously calculated calculation levels.
211      * @return Level of this Sdef in the calculation tree.
212      */

213     int calculateLevel( int[] levels )
214     {
215         int level = 0;
216
217         for ( int i = 0; i < dsIndices.length; i++ )
218             if ( levels[ dsIndices[i] ] > level )
219                 level = levels[ dsIndices[i] ];
220
221         return level;
222     }
223
224     /**
225      * Sets the value of a specific datapoint for this Cdef.
226      * @param pos Position (index in the value table) of the new datapoint.
227      * @param timestamp Timestamp of the new datapoint in number of seconds.
228      * @param val Double value of the new datapoint.
229      */

230     void set( int pos, long timestamp, double val )
231     {
232         super.set( pos, timestamp, val );
233         values[pos] = val;
234     }
235     
236     byte[] getTokens() {
237         return tokens;
238     }
239     
240     double[] getConstants() {
241         return constants;
242     }
243     
244     int[] getDsIndices() {
245         return dsIndices;
246     }
247     
248     String JavaDoc getRpnString()
249     {
250         StringBuffer JavaDoc tmpStr = new StringBuffer JavaDoc("");
251         for (int i = 0; i < strTokens.length - 1; i++) {
252             tmpStr.append( strTokens[i] );
253             tmpStr.append( ',' );
254         }
255         if ( strTokens.length > 0 )
256             tmpStr.append( strTokens[strTokens.length - 1] );
257         
258         return tmpStr.toString();
259     }
260     
261     // ================================================================
262
// -- Private methods
263
// ================================================================
264
/**
265      * Checks if a given string is a number.
266      * @param token String to check.
267      * @return True if the token is a number, false if not.
268      */

269     private boolean isNumber( String JavaDoc token )
270     {
271         try
272         {
273             Double.parseDouble(token);
274             
275             return true;
276         }
277         catch (NumberFormatException JavaDoc nfe) {
278             return false;
279         }
280     }
281
282     void exportXml(XmlWriter xml) {
283         xml.startTag("def");
284         xml.writeTag("name", getName());
285         xml.writeTag("rpn", getRpnString());
286         xml.closeTag(); // def
287
}
288 }
289
Popular Tags