KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > rubis > client > TransitionTable


1 /*
2  * RUBiS
3  * Copyright (C) 2002, 2003, 2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: jmob@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet, Julie Marguerite
22  * Contributor(s):
23  */

24  package edu.rice.rubis.client;
25
26 import java.io.BufferedReader JavaDoc;
27 import java.io.FileReader JavaDoc;
28 import java.io.FileNotFoundException JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.lang.NumberFormatException JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import java.util.NoSuchElementException JavaDoc;
33 import java.util.Random JavaDoc;
34 import java.util.Stack JavaDoc;
35
36 /**
37  * This class provides support for transitions between RUBiS web site pages.
38  * A matrix contains probabilities of transition from one state to another.
39  * A ReadExcelTextFile() method generates a matrix from an Excel file saved
40  * as text with tab separator. The text file must have the following format :
41  * <pre>
42  * RUBiS Transition Table <tab> Name of transition set
43  *
44  * "To >>>
45  * From vvvv "[tab]Home[tab]Register[tab]...list of column headers...[tab]About Me
46  * Home [tab]probability_1_1[tab]probability_2_1[tab]...[tab]probability_27_1[tab]transition_waiting_time
47  * Register [tab]probability_1_2[tab]probability_2_2[tab]...[tab]probability_27_2[tab]transition_waiting_time
48  * RegisterUser [tab]probability_1_3[tab]probability_2_3[tab]...[tab]probability_27_3[tab]transition_waiting_time
49  * Browse [tab]probability_1_4[tab]probability_2_4[tab]...[tab]probability_27_4[tab]transition_waiting_time
50  * BrowseCategories [tab]probability_1_5[tab]probability_2_5[tab]...[tab]probability_27_5[tab]transition_waiting_time
51  * SearchItemsInCategory [tab]probability_1_6[tab]probability_2_6[tab]...[tab]probability_27_6[tab]transition_waiting_time
52  * BrowseRegions [tab]probability_1_7[tab]probability_2_7[tab]...[tab]probability_27_7[tab]transition_waiting_time
53  * BrowseCategoriesInRegion [tab]probability_1_8[tab]probability_2_8[tab]...[tab]probability_27_8[tab]transition_waiting_time
54  * SearchItemsInRegion [tab]probability_1_9[tab]probability_2_9[tab]...[tab]probability_27_9[tab]transition_waiting_time
55  * ViewItem [tab]probability_1_10[tab]probability_2_10[tab]...[tab]probability_27_10[tab]transition_waiting_time
56  * ViewUserInfo [tab]probability_1_11[tab]probability_2_11[tab]...[tab]probability_27_11[tab]transition_waiting_time
57  * ViewBidHistory [tab]probability_1_12[tab]probability_2_12[tab]...[tab]probability_27_12[tab]transition_waiting_time
58  * BuyNowAuth [tab]probability_1_13[tab]probability_2_13[tab]...[tab]probability_27_13[tab]transition_waiting_time
59  * BuyNow [tab]probability_1_14[tab]probability_2_14[tab]...[tab]probability_27_14[tab]transition_waiting_time
60  * StoreBuyBow [tab]probability_1_15[tab]probability_2_15[tab]...[tab]probability_27_15[tab]transition_waiting_time
61  * PutBidAuth [tab]probability_1_16[tab]probability_2_16[tab]...[tab]probability_27_16[tab]transition_waiting_time
62  * PutBid [tab]probability_1_17[tab]probability_2_17[tab]...[tab]probability_27_17[tab]transition_waiting_time
63  * StoreBid [tab]probability_1_18[tab]probability_2_18[tab]...[tab]probability_27_18[tab]transition_waiting_time
64  * PutCommentAuth [tab]probability_1_27[tab]probability_2_19[tab]...[tab]probability_27_19[tab]transition_waiting_time
65  * PutComment [tab]probability_1_20[tab]probability_2_20[tab]...[tab]probability_27_20[tab]transition_waiting_time
66  * StoreComment [tab]probability_1_21[tab]probability_2_21[tab]...[tab]probability_27_21[tab]transition_waiting_time
67  * Sell [tab]probability_1_22[tab]probability_2_22[tab]...[tab]probability_27_22[tab]transition_waiting_time
68  * SelectCategoryToSellItem [tab]probability_1_23[tab]probability_2_23[tab]...[tab]probability_27_23[tab]transition_waiting_time
69  * SellItemForm [tab]probability_1_24[tab]probability_2_24[tab]...[tab]probability_27_24[tab]transition_waiting_time
70  * RegisterItem [tab]probability_1_25[tab]probability_2_25[tab]...[tab]probability_27_25[tab]transition_waiting_time
71  * AboutMe (auth form) [tab]probability_1_26[tab]probability_2_26[tab]...[tab]probability_27_26[tab]transition_waiting_time
72  * AboutMe [tab]probability_1_27[tab]probability_2_27[tab]...[tab]probability_27_27[tab]transition_waiting_time
73  * Back probability [tab]probability_1_28[tab]probability_2_28[tab]...[tab]probability_27_28[tab]transition_waiting_time
74  * End of Session [tab]probability_1_29[tab]probability_2_29[tab]...[tab]probability_27_29[tab]transition_waiting_time
75  * ...
76  *
77  * </pre>
78  * Everything after the <code>End of Session</code> line is ignored.
79  * <code>Initial state</code> is Home page (column 1).
80  * <code>probability_x_y</code> determines the probability to go from state x to state y.
81  *
82  * There are 2 extra lines compared to colums. These lines are:
83  * <code>Back probability:</code> probability to go back to last page (like the back button of the browser)
84  * <code>End of session:</code> probability that the user ends the session (leave the web site).
85  * </pre>
86  *
87  * @author <a HREF="mailto:cecchet@rice.edu">Emmanuel Cecchet</a> and <a HREF="mailto:julie.marguerite@inrialpes.fr">Julie Marguerite</a>
88  * @version 1.0
89  */

90
91 public class TransitionTable
92 {
93   private int nbColumns;
94   private int nbRows;
95   private float transitions[][];
96   private int transitionsTime[];
97   private String JavaDoc tableName = null;
98   private Random JavaDoc rand = new Random JavaDoc();
99   private Stack JavaDoc previousStates = new Stack JavaDoc();
100   private int currentState = 0;
101   private Stats stats;
102   private boolean useTPCWThinkTime;
103   private static String JavaDoc[] stateNames;
104
105   /**
106    * Creates a new <code>TransitionTable</code> instance.
107    */

108   public TransitionTable(int columns, int rows, Stats statistics, boolean UseTPCWThinkTime)
109   {
110     nbColumns = columns;
111     nbRows = rows;
112     stats = statistics;
113     transitions = new float[nbColumns][nbRows];
114     transitionsTime = new int[nbRows];
115     useTPCWThinkTime = UseTPCWThinkTime;
116   }
117
118
119   /**
120    * Get the name of the transition table as defined in file.
121    *
122    * @return name of the transition table.
123    */

124   public String JavaDoc getTableName()
125   {
126     return tableName;
127   }
128
129
130   /**
131    * Resets the current state to initial state (home page).
132    */

133   public void resetToInitialState()
134   {
135     currentState = 0;
136     stats.incrementCount(currentState);
137   }
138
139
140   /**
141    * Return the current state value (row index).
142    *
143    * @return current state value (0 means initial state)
144    */

145   public int getCurrentState()
146   {
147     return currentState;
148   }
149
150
151   /**
152    * Return the previous state value (row index).
153    *
154    * @return previous state value (-1 means no previous state)
155    */

156   public int getPreviousState()
157   {
158     if (previousStates.empty())
159       return -1;
160     else
161     {
162       Integer JavaDoc state = (Integer JavaDoc)previousStates.peek();
163       return state.intValue();
164     }
165   }
166
167
168   /**
169    * Go back to the previous state and return the value of the new state
170    *
171    * @return new state value (-1 means no previous state)
172    */

173   public int backToPreviousState()
174   {
175     if (previousStates.empty())
176       return -1;
177     else
178     {
179       Integer JavaDoc state = (Integer JavaDoc)previousStates.pop();
180       currentState = state.intValue();
181       return currentState;
182     }
183   }
184
185
186   /**
187    * Returns true if the 'End of Session' state has been reached
188    *
189    * @return true if current state is 'End of Session'
190    */

191   public boolean isEndOfSession()
192   {
193     return currentState == (nbRows-1);
194   }
195   
196
197   /**
198    * Return the current state name
199    *
200    * @return current state name
201    */

202   public String JavaDoc getCurrentStateName()
203   {
204     return stateNames[currentState];
205   }
206   
207
208   /**
209    * Return a state name
210    *
211    * @return current state name
212    */

213   public static String JavaDoc getStateName(int state)
214   {
215     return stateNames[state];
216   }
217   
218
219   /**
220    * Compute a next state from current state according to transition matrix.
221    *
222    * @return value of the next state
223    */

224   public int nextState()
225   {
226     int beforeStep = currentState;
227     float step = rand.nextFloat();
228     float cumul = 0;
229     int i;
230
231     for (i = 0 ; i < nbRows ; i++)
232     {
233       cumul = cumul + transitions[currentState][i];
234       if (step < cumul)
235       {
236         currentState = i;
237         break;
238       }
239     }
240     // Deal with Back to previous state
241
if (currentState == nbRows-2)
242     {
243       if (previousStates.empty())
244         System.out.println("Error detected: Trying to go back but no previous state is available (currentState:"+currentState+", beforeStep:"+beforeStep);
245       else
246       { // Back adds both stats of back and new state but only sleep "back waiting time"
247
// and return the new state (after back).
248
stats.incrementCount(currentState); // Add back state stat
249
try
250         {
251           if (useTPCWThinkTime)
252             Thread.currentThread().sleep((long)((float)TPCWthinkTime()*ClientEmulator.getSlowDownFactor()));
253           else
254             Thread.currentThread().sleep((long)((float)transitionsTime[currentState]*ClientEmulator.getSlowDownFactor()));
255         }
256         catch (java.lang.InterruptedException JavaDoc ie)
257         {
258           System.err.println("Thread "+Thread.currentThread().getName()+" has been interrupted.");
259         }
260         Integer JavaDoc previous = (Integer JavaDoc)previousStates.pop();
261         currentState = previous.intValue();
262 // System.out.println("Thread "+Thread.currentThread().getName()+": Going back from "+stateNames[beforeStep]+" to "+stateNames[currentState]+"<br>\n");
263
stats.incrementCount(currentState); // Add new state stat
264
return currentState;
265       }
266     }
267     else
268     { // Add this state to history (previousStates) if needed
269
if (!isEndOfSession())
270       { // If there is no probability to go back from this state, just empty the stack
271
if (transitions[currentState][nbRows-2] == 0)
272           previousStates.removeAllElements();
273         else // else add the previous state to the history just in case we go back !
274
previousStates.push(new Integer JavaDoc(beforeStep));
275 // System.out.println("Thread "+Thread.currentThread().getName()+": "+stateNames[beforeStep]+" -> "+stateNames[currentState]+"<br>\n");
276
}
277     }
278     stats.incrementCount(currentState);
279     try
280     {
281       if (useTPCWThinkTime)
282         Thread.currentThread().sleep((long)((float)TPCWthinkTime()*ClientEmulator.getSlowDownFactor()));
283       else
284         Thread.currentThread().sleep((long)((float)transitionsTime[currentState]*ClientEmulator.getSlowDownFactor()));
285     }
286     catch (java.lang.InterruptedException JavaDoc ie)
287     {
288       System.err.println("Thread "+Thread.currentThread().getName()+" has been interrupted.");
289     }
290     return currentState;
291   }
292
293   
294   /**
295    * Read the matrix transition from a file conforming to the
296    * format described in the class description.
297    *
298    * @param filename name of the file to read the matrix from
299    * @return true upon success else false
300    */

301   public boolean ReadExcelTextFile(String JavaDoc filename)
302   {
303     BufferedReader JavaDoc reader;
304     int i = 0;
305     int j = 0;
306
307     // Try to open the file
308
try
309     {
310       reader = new BufferedReader JavaDoc(new FileReader JavaDoc(filename));
311     }
312     catch (FileNotFoundException JavaDoc f)
313     {
314       System.err.println("File "+filename+" not found.");
315       return false;
316     }
317
318     // Now read the file using tab (\t) as field delimiter
319
try
320     {
321       // Header
322
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(reader.readLine(), "\t");
323       String JavaDoc s = st.nextToken(); // Should be 'RUBiS Transition Table'
324
tableName = st.nextToken();
325 // System.out.println("Reading "+tableName+" from "+filename);
326
reader.readLine(); // Empty line
327
reader.readLine(); // To >>>
328
reader.readLine(); // Column headers
329

330       stateNames = new String JavaDoc[nbRows];
331       // Read the matrix
332
for (i = 0 ; i < nbRows ; i++)
333       {
334         st = new StringTokenizer JavaDoc(reader.readLine(), "\t");
335         stateNames[i] = st.nextToken();
336         for (j = 0 ; j < nbColumns ; j++)
337         {
338           Float JavaDoc f = new Float JavaDoc(st.nextToken());
339           transitions[j][i] = f.floatValue();
340         }
341         // Last column is transition_waiting_time
342
Integer JavaDoc t = new Integer JavaDoc(st.nextToken());
343         transitionsTime[i] = t.intValue();
344       }
345       reader.close();
346     }
347     catch (IOException JavaDoc ioe)
348     {
349       System.err.println("An error occured while reading "+filename+". ("+ioe.getMessage()+")");
350       return false;
351     }
352     catch (NoSuchElementException JavaDoc nsu)
353     {
354       System.err.println("File format error in file "+filename+" when reading line "+i+", column "+j+". ("+nsu.getMessage()+")");
355       return false;
356     }
357     catch (NumberFormatException JavaDoc ne)
358     {
359       System.err.println("Number format error in file "+filename+" when reading line "+i+", column "+j+". ("+ne.getMessage()+")");
360       return false;
361     }
362 // System.out.println("Transition matrix successfully build.");
363
return true;
364   }
365
366
367   /**
368    * Display the transition matrix on the standard output.
369    * This function is only provided for debugging purposes.
370    */

371   protected void displayMatrix()
372   {
373     int i,j;
374
375     System.out.println("\n<h3><br>### Transition table ###</h3>\n");
376     System.out.println("Transition set: '"+tableName+"'<br>\n");
377     System.out.println("<TABLE border=\"1\" summary=\"transition table\"><TBODY>\n");
378     System.out.println("<THEAD><TR><TH>State name");
379     for (j = 0 ; j < nbColumns ; j++)
380       System.out.print("<TH>"+stateNames[j]);
381     System.out.print("<TH>Transition time");
382     for (i = 0 ; i < nbRows ; i++)
383     {
384       System.out.print("\n<TR><TD><div align=left><B>"+stateNames[i]+"</B></div>");
385       for (j = 0 ; j < nbColumns ; j++)
386         System.out.print("<TD><div align=right>"+Float.toString(transitions[j][i])+"</div>");
387       System.out.print("<TD><div align=right>"+Float.toString(transitionsTime[i])+"</div>");
388     }
389     System.out.println("\n</TBODY></TABLE>\n");
390     System.out.println();
391   }
392
393
394   // Negative exponential distribution used by
395
// TPC-W spec for Think Time (Clause 5.3.2.1) and USMD (Clause 6.1.9.2)
396
private long TPCWthinkTime()
397   {
398     double r = rand.nextDouble();
399     if (r < (double)4.54e-5)
400       return ((long) (r+0.5));
401     return ((long) ((((double)-7000.0)*Math.log(r))+0.5));
402   }
403
404 }
405
Popular Tags