KickJava   Java API By Example, From Geeks To Geeks.

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


1 package edu.rice.rubbos.client;
2
3 import java.io.BufferedReader JavaDoc;
4 import java.io.FileReader JavaDoc;
5 import java.io.FileNotFoundException JavaDoc;
6 import java.io.IOException JavaDoc;
7 import java.lang.NumberFormatException JavaDoc;
8 import java.util.StringTokenizer JavaDoc;
9 import java.util.NoSuchElementException JavaDoc;
10 import java.util.Random JavaDoc;
11 import java.util.Stack JavaDoc;
12
13 /**
14  * This class provides support for transitions between RUBBoS web site pages.
15  * A matrix contains probabilities of transition from one state to another.
16  * A ReadExcelTextFile() method generates a matrix from an Excel file saved
17  * as text with tab separator. The text file must have the following format :
18  * <pre>
19  * RUBiS Transition Table <tab> Name of transition set
20  *
21  * "To >>>
22  * From vvvv "[tab]Home[tab]Register[tab]...list of column headers...[tab]About Me
23  * Home [tab]probability_1_1[tab]probability_2_1[tab]...[tab]probability_25_1[tab]transition_waiting_time
24  * Register [tab]probability_1_2[tab]probability_2_2[tab]...[tab]probability_25_2[tab]transition_waiting_time
25  * RegisterUser [tab]probability_1_3[tab]probability_2_3[tab]...[tab]probability_25_3[tab]transition_waiting_time
26  * Browse [tab]probability_1_4[tab]probability_2_4[tab]...[tab]probability_25_4[tab]transition_waiting_time
27  * BrowseCategories [tab]probability_1_5[tab]probability_2_5[tab]...[tab]probability_25_5[tab]transition_waiting_time
28  * SearchItemsInCategory [tab]probability_1_6[tab]probability_2_6[tab]...[tab]probability_25_6[tab]transition_waiting_time
29  * BrowseRegions [tab]probability_1_7[tab]probability_2_7[tab]...[tab]probability_25_7[tab]transition_waiting_time
30  * BrowseCategoriesInRegion [tab]probability_1_8[tab]probability_2_8[tab]...[tab]probability_25_8[tab]transition_waiting_time
31  * SearchItemsInRegion [tab]probability_1_9[tab]probability_2_9[tab]...[tab]probability_25_9[tab]transition_waiting_time
32  * ViewItem [tab]probability_1_10[tab]probability_2_10[tab]...[tab]probability_25_10[tab]transition_waiting_time
33  * ViewUserInfo [tab]probability_1_11[tab]probability_2_11[tab]...[tab]probability_25_11[tab]transition_waiting_time
34  * ViewBidHistory [tab]probability_1_12[tab]probability_2_12[tab]...[tab]probability_25_12[tab]transition_waiting_time
35  * BuyNowAuth [tab]probability_1_13[tab]probability_2_13[tab]...[tab]probability_25_13[tab]transition_waiting_time
36  * BuyNow [tab]probability_1_14[tab]probability_2_14[tab]...[tab]probability_25_14[tab]transition_waiting_time
37  * StoreBuyBow [tab]probability_1_15[tab]probability_2_15[tab]...[tab]probability_25_15[tab]transition_waiting_time
38  * PutBidAuth [tab]probability_1_16[tab]probability_2_16[tab]...[tab]probability_25_16[tab]transition_waiting_time
39  * PutBid [tab]probability_1_17[tab]probability_2_17[tab]...[tab]probability_25_17[tab]transition_waiting_time
40  * StoreBid [tab]probability_1_18[tab]probability_2_18[tab]...[tab]probability_25_18[tab]transition_waiting_time
41  * PutCommentAuth [tab]probability_1_25[tab]probability_2_19[tab]...[tab]probability_25_19[tab]transition_waiting_time
42  * PutComment [tab]probability_1_20[tab]probability_2_20[tab]...[tab]probability_25_20[tab]transition_waiting_time
43  * StoreComment [tab]probability_1_21[tab]probability_2_21[tab]...[tab]probability_25_21[tab]transition_waiting_time
44  * Sell [tab]probability_1_22[tab]probability_2_22[tab]...[tab]probability_25_22[tab]transition_waiting_time
45  * SelectCategoryToSellItem [tab]probability_1_23[tab]probability_2_23[tab]...[tab]probability_25_23[tab]transition_waiting_time
46  * SellItemForm [tab]probability_1_24[tab]probability_2_24[tab]...[tab]probability_25_24[tab]transition_waiting_time
47  * RegisterItem [tab]probability_1_25[tab]probability_2_25[tab]...[tab]probability_25_25[tab]transition_waiting_time
48  * Back probability [tab]probability_1_26[tab]probability_2_26[tab]...[tab]probability_25_26[tab]transition_waiting_time
49  * End of Session [tab]probability_1_27[tab]probability_2_27[tab]...[tab]probability_25_27[tab]transition_waiting_time
50  * ...
51  *
52  * </pre>
53  * Everything after the <code>End of Session</code> line is ignored.
54  * <code>Initial state</code> is Home page (column 1).
55  * <code>probability_x_y</code> determines the probability to go from state x to state y.
56  *
57  * There are 2 extra lines compared to colums. These lines are:
58  * <code>Back probability:</code> probability to go back to last page (like the back button of the browser)
59  * <code>End of session:</code> probability that the user ends the session (leave the web site).
60  * </pre>
61  *
62  * @author <a HREF="mailto:cecchet@rice.edu">Emmanuel Cecchet</a> and <a HREF="mailto:julie.marguerite@inrialpes.fr">Julie Marguerite</a>
63  * @version 1.0
64  */

65
66 public class TransitionTable
67 {
68   private int nbColumns;
69   private int nbRows;
70   private float transitions[][];
71   private int transitionsTime[];
72   private String JavaDoc tableName = null;
73   private Random JavaDoc rand = new Random JavaDoc();
74   private Stack JavaDoc previousStates = new Stack JavaDoc();
75   private int currentState = 0;
76   private Stats stats;
77   private boolean useTPCWThinkTime;
78   private static String JavaDoc[] stateNames;
79   
80   /**
81    * Creates a new <code>TransitionTable</code> instance.
82    */

83   public TransitionTable(int columns, int rows, Stats statistics, boolean UseTPCWThinkTime)
84   {
85     nbColumns = columns;
86     nbRows = rows;
87     stats = statistics;
88     transitions = new float[nbColumns][nbRows];
89     transitionsTime = new int[nbRows];
90     useTPCWThinkTime = UseTPCWThinkTime;
91   }
92
93
94   /**
95    * Get the name of the transition table as defined in file.
96    *
97    * @return name of the transition table.
98    */

99   public String JavaDoc getTableName()
100   {
101     return tableName;
102   }
103
104
105   /**
106    * Resets the current state to initial state (home page).
107    */

108   public void resetToInitialState()
109   {
110     currentState = 0;
111     stats.incrementCount(currentState);
112   }
113
114
115   /**
116    * Return the current state value (row index).
117    *
118    * @return current state value (0 means initial state)
119    */

120   public int getCurrentState()
121   {
122     return currentState;
123   }
124
125
126   /**
127    * Return the previous state value (row index).
128    *
129    * @return previous state value (-1 means no previous state)
130    */

131   public int getPreviousState()
132   {
133     if (previousStates.empty())
134       return -1;
135     else
136     {
137       Integer JavaDoc state = (Integer JavaDoc)previousStates.peek();
138       return state.intValue();
139     }
140   }
141
142
143   /**
144    * Go back to the previous state and return the value of the new state
145    *
146    * @return new state value (-1 means no previous state)
147    */

148   public int backToPreviousState()
149   {
150     if (previousStates.empty())
151       return -1;
152     else
153     {
154       Integer JavaDoc state = (Integer JavaDoc)previousStates.pop();
155       currentState = state.intValue();
156       return currentState;
157     }
158   }
159
160
161   /**
162    * Returns true if the 'End of Session' state has been reached
163    *
164    * @return true if current state is 'End of Session'
165    */

166   public boolean isEndOfSession()
167   {
168     return currentState == (nbRows-1);
169   }
170   
171
172   /**
173    * Return the current state name
174    *
175    * @return current state name
176    */

177   public String JavaDoc getCurrentStateName()
178   {
179     return stateNames[currentState];
180   }
181   
182
183   /**
184    * Return a state name
185    *
186    * @return current state name
187    */

188   public static String JavaDoc getStateName(int state)
189   {
190     return stateNames[state];
191   }
192   
193
194   /**
195    * Compute a next state from current state according to transition matrix.
196    *
197    * @return value of the next state
198    */

199   public int nextState()
200   {
201     int beforeStep = currentState;
202     float step = rand.nextFloat();
203     float cumul = 0;
204     int i;
205
206     for (i = 0 ; i < nbRows ; i++)
207     {
208       cumul = cumul + transitions[currentState][i];
209       if (step < cumul)
210       {
211         currentState = i;
212         break;
213       }
214     }
215     // Deal with Back to previous state
216
if (currentState == nbRows-2)
217     {
218       if (previousStates.empty())
219         System.out.println("Error detected: Trying to go back but no previous state is available (currentState:"+currentState+", beforeStep:"+beforeStep);
220       else
221       { // Back adds both stats of back and new state but only sleep "back waiting time"
222
// and return the new state (after back).
223
stats.incrementCount(currentState); // Add back state stat
224
try
225         {
226           if (useTPCWThinkTime)
227             Thread.currentThread().sleep(TPCWthinkTime());
228           else
229             Thread.currentThread().sleep((long)((float)transitionsTime[currentState]*ClientEmulator.getSlowDownFactor()));
230         }
231         catch (java.lang.InterruptedException JavaDoc ie)
232         {
233           System.err.println("Thread "+Thread.currentThread().getName()+" has been interrupted.");
234         }
235         Integer JavaDoc previous = (Integer JavaDoc)previousStates.pop();
236         currentState = previous.intValue();
237         // System.out.println("Thread "+Thread.currentThread().getName()+": Going back from "+stateNames[beforeStep]+" to "+stateNames[currentState]+"<br>\n");
238
// stats.incrementCount(currentState); // Add new state stat
239
return currentState;
240       }
241     }
242     else
243     { // Add this state to history (previousStates) if needed
244
if (!isEndOfSession())
245       { // If there is no probability to go back from this state, just empty the stack
246
if (transitions[currentState][nbRows-2] == 0)
247           previousStates.removeAllElements();
248         else // else add the previous state to the history just in case we go back !
249
previousStates.push(new Integer JavaDoc(beforeStep));
250         // System.out.println("Thread "+Thread.currentThread().getName()+": "+stateNames[beforeStep]+" -> "+stateNames[currentState]+"<br>\n");
251
}
252     }
253     stats.incrementCount(currentState);
254     try
255     {
256       if (useTPCWThinkTime)
257         Thread.currentThread().sleep(TPCWthinkTime());
258       else
259         Thread.currentThread().sleep((long)((float)transitionsTime[currentState]*ClientEmulator.getSlowDownFactor()));
260     }
261     catch (java.lang.InterruptedException JavaDoc ie)
262     {
263       System.err.println("Thread "+Thread.currentThread().getName()+" has been interrupted.");
264     }
265     return currentState;
266   }
267
268   
269   /**
270    * Read the matrix transition from a file conforming to the
271    * format described in the class description.
272    *
273    * @param filename name of the file to read the matrix from
274    * @return true upon success else false
275    */

276   public boolean ReadExcelTextFile(String JavaDoc filename)
277   {
278     BufferedReader JavaDoc reader;
279     int i = 0;
280     int j = 0;
281
282     // Try to open the file
283
try
284     {
285       reader = new BufferedReader JavaDoc(new FileReader JavaDoc(filename));
286     }
287     catch (FileNotFoundException JavaDoc f)
288     {
289       System.err.println("File "+filename+" not found.");
290       return false;
291     }
292
293     // Now read the file using tab (\t) as field delimiter
294
try
295     {
296       // Header
297
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(reader.readLine(), "\t");
298       String JavaDoc s = st.nextToken(); // Should be 'RUBBoS Transition Table'
299
tableName = st.nextToken();
300 // System.out.println("Reading "+tableName+" from "+filename);
301
reader.readLine(); // Empty line
302
reader.readLine(); // To >>>
303
reader.readLine(); // Column headers
304

305       stateNames = new String JavaDoc[nbRows];
306       // Read the matrix
307
for (i = 0 ; i < nbRows ; i++)
308       {
309         st = new StringTokenizer JavaDoc(reader.readLine(), "\t");
310         stateNames[i] = st.nextToken();
311         for (j = 0 ; j < nbColumns ; j++)
312         {
313           Float JavaDoc f = new Float JavaDoc(st.nextToken());
314           transitions[j][i] = f.floatValue();
315         }
316         // Last column is transition_waiting_time
317
Integer JavaDoc t = new Integer JavaDoc(st.nextToken());
318         transitionsTime[i] = 1; // TBF: t.intValue();
319
}
320       reader.close();
321     }
322     catch (IOException JavaDoc ioe)
323     {
324       System.err.println("An error occured while reading "+filename+". ("+ioe.getMessage()+")");
325       return false;
326     }
327     catch (NoSuchElementException JavaDoc nsu)
328     {
329       System.err.println("File format error in file "+filename+" when reading line "+i+", column "+j+". ("+nsu.getMessage()+")");
330       return false;
331     }
332     catch (NumberFormatException JavaDoc ne)
333     {
334       System.err.println("Number format error in file "+filename+" when reading line "+i+", column "+j+". ("+ne.getMessage()+")");
335       return false;
336     }
337 // System.out.println("Transition matrix successfully build.");
338
return true;
339   }
340
341
342   /**
343    * Display the transition matrix on the standard output.
344    *
345    * @param title transition table name to be displayed in title
346    */

347   protected void displayMatrix(String JavaDoc title)
348   {
349     int i,j;
350
351     System.out.println("\n<h3><br>### "+title+" Transition table ###</h3>\n");
352     System.out.println("Transition set: '"+tableName+"'<br>\n");
353     System.out.println("<TABLE border=\"1\" summary=\"transition table\"><TBODY>\n");
354     System.out.println("<THEAD><TR><TH>State name");
355     for (j = 0 ; j < nbColumns ; j++)
356       System.out.print("<TH>"+stateNames[j]);
357     System.out.print("<TH>Transition time");
358     for (i = 0 ; i < nbRows ; i++)
359     {
360       System.out.print("\n<TR><TD><div align=left><B>"+stateNames[i]+"</B></div>");
361       for (j = 0 ; j < nbColumns ; j++)
362         System.out.print("<TD><div align=right>"+Float.toString(transitions[j][i])+"</div>");
363       System.out.print("<TD><div align=right>"+Float.toString(transitionsTime[i])+"</div>");
364     }
365     System.out.println("\n</TBODY></TABLE>\n");
366     System.out.println();
367   }
368
369   // Negative exponential distribution used by
370
// TPC-W spec for Think Time (Clause 5.3.2.1) and USMD (Clause 6.1.9.2)
371
private long TPCWthinkTime()
372   {
373     double r = rand.nextDouble();
374     if (r < (double)4.54e-5)
375       return ((long) (r+0.5));
376     return ((long) ((((double)-7000.0)*Math.log(r))+0.5));
377   }
378
379 }
380
Popular Tags