~elambert/ds2drizzle/trunk

« back to all changes in this revision

Viewing changes to drivers/ds2xdriver.cs

  • Committer: Eric Lambert
  • Date: 2009-09-16 03:20:51 UTC
  • mfrom: (14.1.1 merge)
  • Revision ID: eric.d.lambert@gmail.com-20090916032051-suf0odher6dj937l
merge ds2/ds2drizzle merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Generalized DVD Store 2 Driver Program - ds2xdriver.cs
 
4
 *
 
5
 * Copyright (C) 2005 Dell, Inc. <dave_jaffe@dell.com> and <todd_muirhead@dell.com>
 
6
 *
 
7
 * Generates orders against DVD Store Database V.2 through web interface or directly against database
 
8
 * Simulates users logging in to store or creating new customer data; browsing for DVDs by title, actor or 
 
9
 * category, and purchasing selected DVDs
 
10
 *
 
11
 * To see syntax: ds2xdriver   where x= web, mysql, sqlserver or oracle
 
12
 *
 
13
 * Compile with appropriate functions file to generate driver for web, SQL Server, MySQL or Oracle target:
 
14
 *  csc /out:ds2webdriver.exe       ds2xdriver.cs ds2webfns.cs       /d:USE_WIN32_TIMER /d:GEN_PERF_CTRS
 
15
 *  csc /out:ds2sqlserverdriver.exe ds2xdriver.cs ds2sqlserverfns.cs /d:USE_WIN32_TIMER /d:GEN_PERF_CTRS
 
16
 *  csc /out:ds2mysqldriver.exe     ds2xdriver.cs ds2mysqlfns.cs     /d:USE_WIN32_TIMER /d:GEN_PERF_CTRS  /r:<path>MySql.Data.dll
 
17
 *  csc /out:ds2oracledriver.exe    ds2xdriver.cs ds2oraclefns.cs    /d:USE_WIN32_TIMER /d:GEN_PERF_CTRS  /r:<path>Oracle.DataAccess.dll
 
18
 *
 
19
 *  USE_WIN32_TIMER: if defined, program will use high resolution WIN32 timers
 
20
 *  GEN_PERF_CTRS: if defined, program will generate Windows Perfmon performance counters
 
21
 *
 
22
 *  csc is installed with Microsoft.NET   Typical location: C:\WINNT\Microsoft.NET\Framework\v2.0.50727
 
23
 *
 
24
 * Last Updated 11/28/07
 
25
 *
 
26
 *  This program is free software; you can redistribute it and/or modify
 
27
 *  it under the terms of the GNU General Public License as published by
 
28
 *  the Free Software Foundation; either version 2 of the License, or
 
29
 *  (at your option) any later version.
 
30
 *
 
31
 *  This program is distributed in the hope that it will be useful,
 
32
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
33
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
34
 *  GNU General Public License for more details.
 
35
 *
 
36
 *  You should have received a copy of the GNU General Public License
 
37
 *  along with this program; if not, write to the Free Software
 
38
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */
 
39
 
 
40
 
 
41
 
 
42
using System;
 
43
using System.IO;
 
44
using System.Threading;
 
45
using System.Diagnostics;
 
46
using System.Runtime.InteropServices;
 
47
 
 
48
namespace ds2xdriver
 
49
  {
 
50
  /// <summary>
 
51
  /// ds2xdriver: drives DVD Store 2 Database through web interface or directly against database
 
52
  /// </summary>
 
53
   
 
54
  public class GlobalConstants 
 
55
    { 
 
56
    public const int MAX_USERS = 1000;
 
57
    public const int MAX_CATEGORY = 16;
 
58
    public const int MAX_ROWS = 100;
 
59
    public const int LAST_N = 100;
 
60
    }
 
61
 
 
62
//
 
63
//-------------------------------------------------------------------------------------------------
 
64
//
 
65
  class Controller
 
66
    { 
 
67
    // If compile option /d:USE_WIN32_TIMER is specified will use 64b QueryPerformance counter from Win32
 
68
    // Else will use .NET DateTime class      
 
69
#if (USE_WIN32_TIMER)
 
70
    [DllImport("kernel32.dll")]
 
71
    extern static short QueryPerformanceCounter(ref long x);
 
72
    [DllImport("kernel32.dll")]
 
73
    extern static short QueryPerformanceFrequency(ref long x);   
 
74
#endif 
 
75
 
 
76
  
 
77
    // Variables needed by User objects 
 
78
    public static string target, windows_perf_host = null;  
 
79
    public static object UpdateLock = 1;
 
80
    public static int n_threads, n_threads_running = 0, n_threads_connected = 0;
 
81
    public static int n_overall = 0, n_login_overall = 0, n_newcust_overall = 0, n_browse_overall = 0,
 
82
      n_purchase_overall=0, n_rollbacks_overall=0, n_rollbacks_from_start=0, n_purchase_from_start=0, n_cpu_pct_samples=0;
 
83
    public static int pct_newcustomers=0, n_searches, search_batch_size, n_line_items, ramp_rate;
 
84
    public static double think_time, rt_tot_overall = 0.0, rt_login_overall = 0.0, rt_newcust_overall = 0.0,
 
85
      rt_browse_overall = 0.0, rt_purchase_overall = 0.0, cpu_pct_tot = 0.0;
 
86
    public static double[] rt_tot_lastn = new double[GlobalConstants.LAST_N];
 
87
    public static bool Start = false, End = false;
 
88
    public static int[] MAX_CUSTOMER = new int[] {20000, 2000000, 200000000};
 
89
    public static int[] MAX_PRODUCT = new int[] {10000, 100000, 1000000};
 
90
    public static int max_customer, max_product, prod_array_size;
 
91
    public static int[] prod_array = new int[1100000];
 
92
    public static string virt_dir = "ds2", page_type = "php";
 
93
 
 
94
    // Variables needed within Controller class
 
95
    static string[] input_parm_names  = new string[] {"config_file", "target", "n_threads", "ramp_rate",
 
96
      "run_time", "db_size_str", "warmup_time", "think_time", "pct_newcustomers", "n_searches",
 
97
      "search_batch_size", "n_line_items", "virt_dir", "page_type", "windows_perf_host"};
 
98
    static string[] input_parm_desc   = new string[] {"config file path", 
 
99
      "database/web server hostname or IP address", "number of driver threads", "startup rate (users/sec)",
 
100
      "run time (min) - 0 is infinite", "database size (S,M or L)", "warmup_time (min)", "think time (sec)", 
 
101
      "percent of customers that are new customers", "average number of searches per order", 
 
102
      "average number of items returned in each search", "average number of items per order",
 
103
      "virtual directory (for web driver)", "web page type (for web driver)", "target hostname for Perfmon CPU% display (Windows only)"};
 
104
    static string[] input_parm_values = new string[] {"none", "localhost", "1", "10", "0", "S", "1", "0",
 
105
      "20", "3", "5", "5", "ds2", "php", ""};
 
106
//
 
107
//-------------------------------------------------------------------------------------------------
 
108
//    
 
109
    [STAThread]
 
110
    static void Main(string[] args)
 
111
      { 
 
112
      new Controller(args);
 
113
      }
 
114
//
 
115
//-------------------------------------------------------------------------------------------------
 
116
//   
 
117
    Controller(string[] argarray)
 
118
      { 
 
119
      //Console.Error.WriteLine("Controller constructor: " + argarray.Length + " args");
 
120
  
 
121
      int i;
 
122
      double rt_tot_lastn_max;
 
123
      int i_sec, run_time = 0, warmup_time = 1;
 
124
      int db_size=0;
 
125
      string db_size_str, errmsg=null;
 
126
      double et;
 
127
      int opm, rt_login_avg_msec, rt_newcust_avg_msec, rt_browse_avg_msec, rt_purchase_avg_msec,
 
128
        rt_tot_lastn_max_msec, rt_tot_avg_msec;
 
129
              
 
130
#if (USE_WIN32_TIMER)
 
131
      long ctr0 = 0, ctr = 0, freq = 0;
 
132
#else
 
133
      TimeSpan TS = new TimeSpan();
 
134
      DateTime DT0;
 
135
#endif
 
136
 
 
137
      User[] users = new User[GlobalConstants.MAX_USERS];
 
138
      Thread[] threads = new Thread[GlobalConstants.MAX_USERS]; 
 
139
 
 
140
      if (argarray.Length == 0)
 
141
        {
 
142
        // display input parameter info
 
143
        Console.Error.WriteLine("\nEnter parameters with format --parm_name=parm_value");
 
144
        Console.Error.WriteLine("And/or use a config file with argument --config_file=(config file path)");
 
145
        Console.Error.WriteLine("Parms will be evaluated left to right");
 
146
        Console.Error.WriteLine("\n{0,-20}{1,-52}{2}\n", "Parameter Name", "Description", "Default Value");
 
147
        for (i=0; i<input_parm_names.Length; i++)
 
148
          {
 
149
          Console.Error.WriteLine("{0,-20}{1,-52}{2}", input_parm_names[i], input_parm_desc[i], input_parm_values[i]);
 
150
          }
 
151
        return;
 
152
        }
 
153
 
 
154
      // send args to parse_args, return 0 or # of parms set, error_message if any
 
155
      // parsed values are in array input_parm_values
 
156
      i = parse_args(argarray, ref errmsg);
 
157
      if (i != 0) {}//Console.Error.WriteLine("{0} parameters parsed", i);
 
158
      else 
 
159
        {
 
160
        Console.Error.WriteLine(errmsg);
 
161
        return;
 
162
        }
 
163
          
 
164
      // Set parameters from input_parm_values 
 
165
        
 
166
      target = input_parm_values[Array.IndexOf(input_parm_names, "target")];
 
167
      try 
 
168
        {
 
169
        n_threads = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "n_threads")]);
 
170
        }
 
171
      catch (System.Exception e) 
 
172
        {
 
173
        Console.Error.WriteLine("Error in converting parameter n_threads: {0}", e.Message);
 
174
        return;
 
175
        }
 
176
      try 
 
177
        {
 
178
        ramp_rate = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "ramp_rate")]);
 
179
        }
 
180
      catch (System.Exception e) 
 
181
        {
 
182
        Console.Error.WriteLine("Error in converting parameter ramp_rate: {0}", e.Message);
 
183
        return;
 
184
        }
 
185
      try 
 
186
        {
 
187
        run_time = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "run_time")]);
 
188
        }
 
189
      catch (System.Exception e) 
 
190
        {
 
191
        Console.Error.WriteLine("Error in converting parameter run_time: {0}", e.Message);
 
192
        return;
 
193
        }
 
194
      db_size_str = input_parm_values[Array.IndexOf(input_parm_names, "db_size_str")];
 
195
      string sizes= "SML";
 
196
      if ((db_size = sizes.IndexOf(db_size_str.ToUpper())) < 0)
 
197
        {
 
198
        Console.Error.WriteLine("Error: db_size_str must be one of S, M or L");
 
199
        return;
 
200
        }
 
201
      try 
 
202
        {
 
203
        warmup_time = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "warmup_time")]);
 
204
        }
 
205
      catch (System.Exception e) 
 
206
        {
 
207
        Console.Error.WriteLine("Error in converting parameter warmup_time: {0}", e.Message);
 
208
        return;
 
209
        }
 
210
      try 
 
211
        {
 
212
        think_time = Convert.ToDouble(input_parm_values[Array.IndexOf(input_parm_names, "think_time")]);
 
213
        }
 
214
      catch (System.Exception e) 
 
215
        {
 
216
        Console.Error.WriteLine("Error in converting parameter think_time: {0}", e.Message);
 
217
        return;
 
218
        }
 
219
      try 
 
220
        {
 
221
        pct_newcustomers = 
 
222
          Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "pct_newcustomers")]);
 
223
        }
 
224
      catch (System.Exception e) 
 
225
        {
 
226
        Console.Error.WriteLine("Error in converting parameter pct_newcustomers: {0}", e.Message);
 
227
        return;
 
228
        }
 
229
      try 
 
230
        {
 
231
        n_searches = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "n_searches")]);
 
232
        if (n_searches <= 0)
 
233
          {
 
234
          Console.Error.WriteLine("n_searches must be greater than 0");
 
235
          return;
 
236
          }
 
237
        }
 
238
      catch (System.Exception e) 
 
239
        {
 
240
        Console.Error.WriteLine("Error in converting parameter n_searches: {0}", e.Message);
 
241
        return;
 
242
        }
 
243
      try 
 
244
        {
 
245
        search_batch_size = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, 
 
246
          "search_batch_size")]);
 
247
        if (search_batch_size <= 0)
 
248
          {
 
249
          Console.Error.WriteLine("search_batch_size must be greater than 0");
 
250
          return;
 
251
          }        
 
252
        }
 
253
      catch (System.Exception e) 
 
254
        {
 
255
        Console.Error.WriteLine("Error in converting parameter search_batch_size: {0}", e.Message);
 
256
        return;
 
257
        }
 
258
      try 
 
259
        {
 
260
        n_line_items = Convert.ToInt32(input_parm_values[Array.IndexOf(input_parm_names, "n_line_items")]);
 
261
        if (n_line_items <= 0)
 
262
          {
 
263
          Console.Error.WriteLine("n_line_items must be greater than 0");
 
264
          return;
 
265
          }        
 
266
        }
 
267
      catch (System.Exception e) 
 
268
        {
 
269
        Console.Error.WriteLine("Error in converting parameter n_line_items: {0}", e.Message);
 
270
        return;
 
271
        }        
 
272
      virt_dir = input_parm_values[Array.IndexOf(input_parm_names, "virt_dir")]; 
 
273
      page_type = input_parm_values[Array.IndexOf(input_parm_names, "page_type")];
 
274
      windows_perf_host = input_parm_values[Array.IndexOf(input_parm_names, "windows_perf_host")];
 
275
      if (windows_perf_host == "") windows_perf_host = null;
 
276
 
 
277
      Console.Error.WriteLine("target= {0}  n_threads= {1}  ramp_rate= {2}  run_time= {3}  db_size_str= {4}" +
 
278
        "  warmup_time= {5}  think_time= {6}\npct_newcustomers= {7}  n_searches= {8}  search_batch_size= {9}" +
 
279
        "  n_line_items= {10}  virt_dir= {11}  page_type= {12}  windows_perf_host= {13}", 
 
280
        target, n_threads, ramp_rate, run_time, db_size_str, warmup_time, think_time, pct_newcustomers,
 
281
        n_searches, search_batch_size, n_line_items, virt_dir, page_type, windows_perf_host);
 
282
 
 
283
#if (USE_WIN32_TIMER)
 
284
      Console.Error.WriteLine("\nUsing WIN32 QueryPerformanceCounters for measuring response time\n");
 
285
#else
 
286
     Console.Error.WriteLine("\nUsing .NET DateTime for measuring response time\n");
 
287
#endif
 
288
      max_customer = MAX_CUSTOMER[db_size];
 
289
      max_product = MAX_PRODUCT[db_size];
 
290
 
 
291
      // Set up array to choose product ids from, weighted with more entries for popular products
 
292
      // Popular products (in this case every 10,000th) will have 10 entries in list, others just 1
 
293
      i=0;
 
294
      for (int j=1; j<=max_product; j++)
 
295
        {
 
296
        if ((j % 10000) == 0) for (int k=0; k<10; k++) prod_array[i++]=j;
 
297
        else prod_array[i++] = j;
 
298
        }
 
299
      prod_array_size = i;
 
300
      //Console.Error.WriteLine("{0} products in array", prod_array_size);
 
301
             
 
302
      for (i=0; i<GlobalConstants.LAST_N; i++) {rt_tot_lastn[i] = 0.0;}
 
303
 
 
304
#if (GEN_PERF_CTRS)      
 
305
      if (!PerformanceCounterCategory.Exists("Test")) // Create Performance Counter object if necessary
 
306
        {
 
307
        CounterCreationDataCollection CCDC = new CounterCreationDataCollection();
 
308
        CounterCreationData MaxRT = new CounterCreationData();
 
309
        MaxRT.CounterType = PerformanceCounterType.NumberOfItems32;
 
310
        MaxRT.CounterName = "MaxRT";
 
311
        CCDC.Add(MaxRT);
 
312
        CounterCreationData OPM = new CounterCreationData();
 
313
        OPM.CounterType = PerformanceCounterType.NumberOfItems32;
 
314
        OPM.CounterName = "OPM";
 
315
        CCDC.Add(OPM);       
 
316
                // For Visual Studio 2003: PerformanceCounterCategory.Create("Test", "DB Stress Data", CCDC);
 
317
        PerformanceCounterCategory.Create("Test", "DB Stress Data", PerformanceCounterCategoryType.SingleInstance, CCDC);
 
318
        Console.Error.WriteLine("Performance Counter Category Test and Counters MaxRT and OPM created");
 
319
        }          
 
320
      else
 
321
        {
 
322
        if ( !( PerformanceCounterCategory.CounterExists("MaxRT", "Test") && 
 
323
          PerformanceCounterCategory.CounterExists("OPM", "Test")) )
 
324
          { 
 
325
          PerformanceCounterCategory.Delete("Test");
 
326
          CounterCreationDataCollection CCDC = new CounterCreationDataCollection();
 
327
          CounterCreationData MaxRT = new CounterCreationData();
 
328
          MaxRT.CounterType = PerformanceCounterType.NumberOfItems32;
 
329
          MaxRT.CounterName = "MaxRT";
 
330
          CCDC.Add(MaxRT);
 
331
          CounterCreationData OPM = new CounterCreationData();
 
332
          OPM.CounterType = PerformanceCounterType.NumberOfItems32;
 
333
          OPM.CounterName = "OPM";
 
334
          CCDC.Add(OPM);       
 
335
                  // For Visual Studio 2003: PerformanceCounterCategory.Create("Test", "DB Stress Data", CCDC);
 
336
          PerformanceCounterCategory.Create("Test", "DB Stress Data", PerformanceCounterCategoryType.SingleInstance, CCDC); 
 
337
          Console.Error.WriteLine
 
338
            ("Performance Counter Category Test deleted; Category Test and Counters MaxRT/OPM created");
 
339
          }
 
340
        else
 
341
          {
 
342
          Console.Error.WriteLine("Performance Counter Category Test and Counter MaxRT exist");
 
343
          }
 
344
        }
 
345
      PerformanceCounter MaxRTC = new PerformanceCounter("Test", "MaxRT", false); // Max response time
 
346
      PerformanceCounter OPMC = new PerformanceCounter("Test", "OPM", false); // Orders per minute
 
347
      
 
348
      // Read CPU Utilization % of target host (if Windows)
 
349
      PerformanceCounter CPU_PCT = null;
 
350
      if (windows_perf_host != null)
 
351
        CPU_PCT = new PerformanceCounter("Processor", "% Processor Time", "_Total", windows_perf_host);
 
352
      
 
353
#else
 
354
      Console.Error.WriteLine("Not generating Windows Performance Monitor Counters");
 
355
#endif     
 
356
    
 
357
      for (i=0; i<n_threads; i++) // Create User objects; associate each with new Thread running Emulate method
 
358
        {
 
359
        users[i] = new User(i);
 
360
        threads[i] = new Thread(new ThreadStart(users[i].Emulate));
 
361
        }
 
362
          
 
363
      for (i=0; i<n_threads; i++) // Start threads
 
364
        {
 
365
        threads[i].Start();
 
366
        }
 
367
            
 
368
      while (n_threads_running < n_threads) // Wait for all threads to start
 
369
        {
 
370
        //Console.Error.WriteLine("Controller: n_threads_running = {0}", n_threads_running);
 
371
        //Console.Error.WriteLine("Controller: Thread status:");
 
372
        //for (i=0; i<n_threads; i++) Console.Error.WriteLine("  Thread {0}: {1}", i, threads[i].ThreadState);
 
373
        Thread.Sleep(1000);
 
374
        }
 
375
      Console.Error.WriteLine("Controller ({0}): all threads running", DateTime.Now);
 
376
      //for (i=0; i<n_threads; i++) Console.Error.WriteLine("  Thread {0}: {1}", i, threads[i].ThreadState);   
 
377
                
 
378
      while (n_threads_connected < n_threads)
 
379
        {
 
380
        for (int j=0; j<n_threads; j++)  // If one of the threads has stopped quit
 
381
          if (threads[j].ThreadState == System.Threading.ThreadState.Stopped) return;
 
382
        Console.Error.WriteLine("Controller: n_threads_connected = {0}", n_threads_connected);
 
383
        Thread.Sleep(1000);
 
384
        }
 
385
      Console.Error.WriteLine("Controller ({0}): all threads connected - issuing Start", DateTime.Now);
 
386
      Start = true;
 
387
      
 
388
#if (USE_WIN32_TIMER)
 
389
      QueryPerformanceFrequency(ref freq); // obtain system freq (ticks/sec)
 
390
      QueryPerformanceCounter(ref ctr0); // Start response time clock   
 
391
#else
 
392
      DT0 = DateTime.Now;
 
393
#endif    
 
394
      
 
395
      if (run_time == 0) run_time = 1000000;  // test run time in minutes, 0 => forever
 
396
      run_time += warmup_time;  // Add warmup time for total run time
 
397
      
 
398
      for (i_sec=1; i_sec<=run_time*60; i_sec++) // run for run_time*60 seconds
 
399
        {
 
400
        Thread.Sleep(1000);     // Update perfmon stats about every second
 
401
        Monitor.Enter(UpdateLock);  // Block User threads from accessing code to update these values (below)       
 
402
#if (USE_WIN32_TIMER)
 
403
          QueryPerformanceCounter(ref ctr);
 
404
          et = (ctr-ctr0)/(double) freq;   
 
405
#else
 
406
          TS = DateTime.Now - DT0;
 
407
          et = TS.TotalSeconds;
 
408
#endif        
 
409
          opm = (int) Math.Floor(60.0*n_overall/et);
 
410
          rt_tot_lastn_max = 0.0;
 
411
          for (int j=0; j<GlobalConstants.LAST_N; j++)
 
412
            rt_tot_lastn_max = (rt_tot_lastn[j] > rt_tot_lastn_max) ? rt_tot_lastn[j] : rt_tot_lastn_max;
 
413
          rt_tot_lastn_max_msec = (int) Math.Floor(1000* rt_tot_lastn_max);
 
414
#if (GEN_PERF_CTRS)  
 
415
          MaxRTC.RawValue = rt_tot_lastn_max_msec;
 
416
          OPMC.RawValue = opm;
 
417
          if (windows_perf_host != null)
 
418
            {
 
419
            cpu_pct_tot += CPU_PCT.NextValue();
 
420
            ++n_cpu_pct_samples;
 
421
            }
 
422
#endif
 
423
          if (i_sec%10 == 0) // print out stats every 10 seconds
 
424
            {
 
425
            //rt_login_avg_msec = (int) Math.Floor(1000*rt_login_overall/n_login_overall);
 
426
            //rt_newcust_avg_msec = (int) Math.Floor(1000*rt_newcust_overall/n_newcust_overall);
 
427
            //rt_browse_avg_msec = (int) Math.Floor(1000*rt_browse_overall/n_browse_overall);
 
428
            //rt_purchase_avg_msec = (int) Math.Floor(1000*rt_purchase_overall/n_purchase_overall);
 
429
            rt_tot_avg_msec = (int) Math.Floor(1000*rt_tot_overall/n_overall);
 
430
            Console.Error.Write("et={0,7:F1} n_overall={1} opm={2} rt_tot_lastn_max_msec={3} rt_tot_avg_msec={4} " + 
 
431
              "rollbacks: n={5} %={6,5:F1}  ",
 
432
              et, n_overall, opm, rt_tot_lastn_max_msec, rt_tot_avg_msec, n_rollbacks_overall,
 
433
              (100.0*n_rollbacks_overall)/n_overall);
 
434
           if (windows_perf_host != null) 
 
435
             Console.Error.WriteLine("host {0} CPU%= {1,5:F1}", windows_perf_host, cpu_pct_tot/n_cpu_pct_samples);
 
436
           else Console.Error.Write("\n");
 
437
 
 
438
            for (int j=0; j<n_threads; j++)
 
439
              {
 
440
              if (threads[j].ThreadState == System.Threading.ThreadState.Stopped)
 
441
                {
 
442
                Console.Error.WriteLine("threads[{0}].ThreadState= {1}", j, threads[j].ThreadState);
 
443
                }
 
444
              }
 
445
            }
 
446
        Monitor.Exit(UpdateLock);
 
447
        
 
448
        if (i_sec == 60*warmup_time) // reset params after specified warmump
 
449
          {
 
450
          n_overall = 0; n_login_overall = 0; n_newcust_overall = 0; n_browse_overall = 0; n_purchase_overall = 0;
 
451
          n_rollbacks_overall = 0;
 
452
          rt_tot_overall = 0.0; rt_login_overall = 0.0; rt_newcust_overall = 0.0; rt_browse_overall = 0.0;
 
453
          rt_purchase_overall = 0.0;
 
454
          for (int j=0; j<GlobalConstants.LAST_N; j++) rt_tot_lastn[j] = 0.0;
 
455
          cpu_pct_tot = 0.0;
 
456
          n_cpu_pct_samples = 0;
 
457
#if (USE_WIN32_TIMER)
 
458
          QueryPerformanceCounter(ref ctr0);   
 
459
#else
 
460
          DT0 = DateTime.Now;
 
461
#endif
 
462
 
 
463
          Console.Error.WriteLine("Stats reset");
 
464
          }
 
465
        } // End for i_sec<run_time
 
466
        
 
467
      Console.Error.WriteLine("Run over");
 
468
      Monitor.Enter(UpdateLock);  // Block User threads from accessing code to update these values (below)
 
469
#if (USE_WIN32_TIMER)
 
470
        QueryPerformanceCounter(ref ctr);
 
471
        et = (ctr-ctr0)/(double) freq;   
 
472
#else
 
473
        TS = DateTime.Now - DT0;
 
474
        et = TS.TotalSeconds;
 
475
#endif
 
476
        opm = (int) Math.Floor(60.0*n_overall/et);
 
477
        rt_login_avg_msec = (int) Math.Floor(1000*rt_login_overall/n_login_overall);
 
478
        rt_newcust_avg_msec = (int) Math.Floor(1000*rt_newcust_overall/n_newcust_overall);
 
479
        rt_browse_avg_msec = (int) Math.Floor(1000*rt_browse_overall/n_browse_overall);
 
480
        rt_purchase_avg_msec = (int) Math.Floor(1000*rt_purchase_overall/n_purchase_overall);
 
481
        rt_tot_lastn_max = 0.0;
 
482
        for (int j=0; j<GlobalConstants.LAST_N; j++)
 
483
          rt_tot_lastn_max = (rt_tot_lastn[j] > rt_tot_lastn_max) ? rt_tot_lastn[j] : rt_tot_lastn_max;
 
484
        rt_tot_lastn_max_msec = (int) Math.Floor(1000* rt_tot_lastn_max);
 
485
        rt_tot_avg_msec = (int) Math.Floor(1000*rt_tot_overall/n_overall);
 
486
#if (GEN_PERF_CTRS)  
 
487
        MaxRTC.RawValue = rt_tot_lastn_max_msec;
 
488
        OPMC.RawValue = opm;
 
489
#endif
 
490
        Console.Write("Final: et={0,7:F1} n_overall={1} opm={2} rt_tot_lastn_max={3} rt_tot_avg={4} " +
 
491
          "n_login_overall={5} n_newcust_overall={6} n_browse_overall={7} n_purchase_overall={8} " +
 
492
          "rt_login_avg_msec={9} rt_newcust_avg_msec={10} rt_browse_avg_msec={11} rt_purchase_avg_msec={12} " +
 
493
          "n_rollbacks_overall={13} rollback_rate = {14,5:F1}%  ",
 
494
          et, n_overall, opm, rt_tot_lastn_max_msec, rt_tot_avg_msec,n_login_overall, n_newcust_overall,
 
495
          n_browse_overall, n_purchase_overall, rt_login_avg_msec, rt_newcust_avg_msec, rt_browse_avg_msec,
 
496
          rt_purchase_avg_msec, n_rollbacks_overall, (100.0*n_rollbacks_overall)/n_overall);
 
497
        if (windows_perf_host != null) 
 
498
          Console.WriteLine("host {0} CPU%= {1,5:F1}", windows_perf_host, cpu_pct_tot/n_cpu_pct_samples);
 
499
        else Console.Write("\n");
 
500
                      
 
501
      Monitor.Exit(UpdateLock);      
 
502
 
 
503
      // Signal threads to end, wait for 'em to stop
 
504
      End = true;    
 
505
      bool all_stopped;
 
506
      do
 
507
        {
 
508
        Thread.Sleep(500);
 
509
        all_stopped = true;
 
510
        for (i=0; i<n_threads; i++) all_stopped &= (threads[i].ThreadState ==System.Threading.ThreadState.Stopped);
 
511
        }
 
512
        while (!all_stopped);
 
513
      Console.Error.WriteLine("Controller: all threads stopped, exiting; n_purchase_from_start= {0} " +
 
514
          "n_rollbacks_from_start= {1}", n_purchase_from_start, n_rollbacks_from_start);
 
515
#if (GEN_PERF_CTRS)  
 
516
      MaxRTC.RawValue = 0;
 
517
      OPMC.RawValue = 0;
 
518
#endif   
 
519
      } // End of Controller() Constructor
 
520
//
 
521
//-------------------------------------------------------------------------------------------------
 
522
//      
 
523
    static int parse_args(string[] argstring, ref string errmsg)
 
524
      {
 
525
      int parm_idx = -1, parm_count = 0;
 
526
      string[] split = null;
 
527
      string config_fname = null, parmline = null;
 
528
      char[] delimeter = {'='};
 
529
      
 
530
      for (int i=0; i<argstring.Length; i++)
 
531
        {
 
532
        //Console.Error.WriteLine(argstring[i]);
 
533
        if ((argstring[i].StartsWith("--")) && (argstring[i].IndexOf('=') > 2))
 
534
          {
 
535
          split = argstring[i].Substring(2).Split(delimeter);
 
536
          if (split[0] == "config_file")
 
537
            {
 
538
            config_fname = split[1];
 
539
            if (File.Exists(config_fname))
 
540
              {
 
541
              StreamReader sr = new StreamReader(config_fname);
 
542
              while((parmline = sr.ReadLine()) != null)
 
543
                {
 
544
                //Console.Error.WriteLine(parmline);            
 
545
                if (parmline.IndexOf('=') > 0)
 
546
                  {
 
547
                  split = parmline.Split(delimeter);                  
 
548
                  parm_idx = Array.IndexOf(input_parm_names, split[0]);
 
549
                  if (parm_idx > -1)
 
550
                    {
 
551
                    //Console.Error.WriteLine("Parameter {0} parsed; was {1}, now {2}", 
 
552
                    //  split[0], input_parm_values[parm_idx], split[1]);
 
553
                    input_parm_values[parm_idx] = split[1];
 
554
                    ++parm_count;
 
555
                    }
 
556
                  else
 
557
                    {
 
558
                    errmsg = "Parameter " + split[0] + " doesn't exist";
 
559
                    return(0);
 
560
                    }
 
561
                  }       
 
562
                else
 
563
                  {
 
564
                  errmsg = "Incorrect format in parameter: " +  argstring[i];
 
565
                  return(0);
 
566
                  }               
 
567
                } // End while((parmline = sr.ReadLine()) != null)
 
568
              sr.Close();
 
569
              }
 
570
            else
 
571
              {
 
572
              errmsg = "File " + split[1] + " doesn't exist";
 
573
              return(0);
 
574
              }   
 
575
            }  // End if (split[0] == "config_file")
 
576
          else  // Param is not a config file name
 
577
            {
 
578
            parm_idx = Array.IndexOf(input_parm_names, split[0]);
 
579
            if (parm_idx > -1)
 
580
              {
 
581
              //Console.Error.WriteLine("Parameter {0} parsed; was {1}, now {2}", 
 
582
              //  split[0], input_parm_values[parm_idx], split[1]);
 
583
              input_parm_values[parm_idx] = split[1];
 
584
              ++parm_count;
 
585
              }
 
586
            else
 
587
              {
 
588
              errmsg = "Parameter " + split[0] + " doesn't exist";
 
589
              return(0);
 
590
              }
 
591
            } // End else Param is not a config file name       
 
592
          } // End if ((argstring[i].StartsWith("--") ...
 
593
        else
 
594
          {
 
595
          errmsg = "Incorrect format in parameter: " +  argstring[i];
 
596
          return(0);
 
597
          }
 
598
        } // End for (int i=0; i<argstring.Length; i++)
 
599
      return(parm_count);
 
600
      } // End of parse_args
 
601
      
 
602
    } // End of class Controller
 
603
//
 
604
//-------------------------------------------------------------------------------------------------
 
605
//    
 
606
  class User
 
607
    {
 
608
    // If compile option /d:USE_WIN32_TIMER is specified will use 64b QueryPerformance counter from Win32
 
609
    // Else will use .NET DateTime class      
 
610
#if (USE_WIN32_TIMER)
 
611
    [DllImport("kernel32.dll")]
 
612
    extern static short QueryPerformanceCounter(ref long x);
 
613
    [DllImport("kernel32.dll")]
 
614
    extern static short QueryPerformanceFrequency(ref long x);  
 
615
#endif
 
616
      
 
617
    int Userid;
 
618
    ds2Interface[] ds2interfaces = new ds2Interface[GlobalConstants.MAX_USERS];
 
619
    Random r;
 
620
    string username_in, password_in, firstname_in, lastname_in, address1_in, address2_in, city_in, state_in;
 
621
    string zip_in, country_in, email_in, phone_in, creditcard_in, gender_in;
 
622
    int creditcardtype_in, ccexpmon_in, ccexpyr_in, income_in, age_in;
 
623
    string actor_in, title_in;
 
624
     
 
625
    public User(int userid)
 
626
      {
 
627
      Userid = userid;
 
628
      //Console.Error.WriteLine("user {0} created", userid);
 
629
      }
 
630
//
 
631
//-------------------------------------------------------------------------------------------------
 
632
//
 
633
    public void Emulate()
 
634
      {
 
635
      int i, customerid_out = 0, neworderid_out = 0, rows_returned = 0;
 
636
      bool IsLogin, IsRollback;
 
637
      double rt = 0, rt_tot, rt_login, rt_newcust, rt_browse, rt_purchase; 
 
638
      
 
639
      string[] title_out = new string[GlobalConstants.MAX_ROWS];         // Login, Browse
 
640
      string[] actor_out = new string[GlobalConstants.MAX_ROWS];         // Login, Browse
 
641
      string[] related_title_out = new string[GlobalConstants.MAX_ROWS]; // Login
 
642
      int[] prod_id_out = new int[GlobalConstants.MAX_ROWS];             // Browse
 
643
      decimal[] price_out = new decimal[GlobalConstants.MAX_ROWS];       // Browse
 
644
      int[] special_out = new int[GlobalConstants.MAX_ROWS];             // Browse
 
645
      int[] common_prod_id_out = new int[GlobalConstants.MAX_ROWS];      // Browse
 
646
      int[] prod_id_in = new int[GlobalConstants.MAX_ROWS];              // Purchase
 
647
      int[] qty_in = new int[GlobalConstants.MAX_ROWS];                  // Purchase
 
648
    
 
649
      Thread.CurrentThread.Name = Userid.ToString();
 
650
      Console.Error.WriteLine("Thread {0}: created for User {1}",  Thread.CurrentThread.Name, Userid);
 
651
      
 
652
      lock (typeof(User))  // Only allow one instance of User to access this code at a time
 
653
        {
 
654
        ++Controller.n_threads_running; 
 
655
        }
 
656
           
 
657
      // Create random stream r with very randomized seed
 
658
      Random rtemp = new Random(Userid*1000); // Temporary seed
 
659
      // For multi-thread runs sleep between 0 - 10 second to spread out Ticks (100 nsecs)
 
660
      if (Controller.n_threads > 1) Thread.Sleep(rtemp.Next(10000));
 
661
      long DTNT = DateTime.Now.Ticks;
 
662
      uint lowDTNT = (uint) (0x00000000ffffffff & DTNT);
 
663
      uint rev_lowDTNT = 0;  // take low 32 bits of Tick counter and reverse them
 
664
      for (i=0; i<32; i++) rev_lowDTNT = rev_lowDTNT | ((0x1 & (lowDTNT >> i)) << (31-i));
 
665
      //Console.Error.WriteLine("DTNT= 0x{0:x16}  lowDTNT= 0x{1:x8}  rev_lowDTNT= 0x{2:x8}", DTNT, lowDTNT, rev_lowDTNT);
 
666
      r = new Random((int)rev_lowDTNT);
 
667
      
 
668
      ds2interfaces[Userid] = new ds2Interface(Userid);
 
669
 
 
670
      
 
671
      if (!ds2interfaces[Userid].ds2initialize())
 
672
        {
 
673
        Console.Error.WriteLine("Can't initialize " +  Controller.target + "; exiting");
 
674
        return;
 
675
        }
 
676
              
 
677
      // Users randomly start connecting over a (#users/ramp_rate) sec period
 
678
      Thread.Sleep(r.Next((int)Math.Floor(1000.0*Controller.n_threads/(double)Controller.ramp_rate))); 
 
679
          
 
680
      if (!ds2interfaces[Userid].ds2connect())
 
681
        {
 
682
        Console.Error.WriteLine("Thread {0}: can't connect to {1}; exiting", Thread.CurrentThread.Name,
 
683
          Controller.target);
 
684
        return;
 
685
        }
 
686
     
 
687
      Console.Error.WriteLine("Thread {0}: connected to {1}",  Thread.CurrentThread.Name, Controller.target);
 
688
             
 
689
      lock (typeof(User))  // Only allow one instance of User to access this code at a time
 
690
        {
 
691
        ++Controller.n_threads_connected; 
 
692
        }
 
693
        
 
694
      // Wait for all threads to connect
 
695
      while(!Controller.Start) Thread.Sleep(100);
 
696
                                
 
697
      // Thread emulation loop - execute until Controller signals END      
 
698
      do
 
699
        {    
 
700
        // Initialize response time accumulators and other variables
 
701
        rt_tot = 0.0;  //  total response time for all phases of this emulation loop order
 
702
        rt_login = 0.0;  //  response time for login in this emulation loop
 
703
        rt_newcust = 0.0;  //  response time for new cust registration in this emulation loop
 
704
        rt_browse = 0.0;  //  total response time for browses in this emulation loop
 
705
        rt_purchase = 0.0;  //  response time for purchase in this emulation loop       
 
706
                
 
707
        IsLogin = false;
 
708
        IsRollback = false; 
 
709
        
 
710
        // Login/New Customer Phase
 
711
 
 
712
        double user_type = r.NextDouble();
 
713
  
 
714
        if (user_type >= Controller.pct_newcustomers/100.0) // If this is true we have a returning customer 
 
715
          {
 
716
          IsLogin = true;
 
717
          //Returning user with randomized username
 
718
          int i_user = 1 + r.Next(Controller.max_customer);
 
719
          username_in = "user" + i_user;
 
720
          password_in = "password";
 
721
          rows_returned = 0;
 
722
 
 
723
          if (!ds2interfaces[Userid].ds2login(username_in, password_in, ref customerid_out, ref rows_returned, 
 
724
            ref title_out, ref actor_out, ref related_title_out, ref rt))
 
725
            {
 
726
            Console.Error.WriteLine("Thread {0}: Error in Login for User {1}, thread exiting", 
 
727
              Thread.CurrentThread.Name, username_in);
 
728
            return;
 
729
            }
 
730
          
 
731
          if (customerid_out == 0)
 
732
            {
 
733
            Console.Error.WriteLine("Thread {0}: User {1} not found, thread exiting", 
 
734
              Thread.CurrentThread.Name, username_in);
 
735
            return;
 
736
            }   
 
737
                   
 
738
//        Console.Error.WriteLine("Thread {0}: User {1} logged in, customerid= {2}, previous DVDs ordered= {3}, " +
 
739
//          "RT= {4,10:F3}", Thread.CurrentThread.Name, username_in, customerid_out, rows_returned, rt);  
 
740
//        for (i=0; i<rows_returned; i++)
 
741
//          Console.Error.WriteLine("Thread {0}: title= {1} actor= {2} related_title= {3}", 
 
742
//            Thread.CurrentThread.Name, title_out[i], actor_out[i], related_title_out[i]);
 
743
          
 
744
          rt_login = rt;
 
745
          rt_tot += rt;          
 
746
          }  // end returning customer
 
747
 
 
748
        // New Customer with randomized username
 
749
  
 
750
        else   // New user
 
751
          {          
 
752
          CreateUserData();
 
753
          do  // Try newcustomer until find a userid that doesn't exist
 
754
            {      
 
755
            int i_user = 1 + r.Next(Controller.max_customer);
 
756
            username_in = "newuser" + i_user;
 
757
            password_in = "password";
 
758
    
 
759
            if (!ds2interfaces[Userid].ds2newcustomer(username_in, password_in, firstname_in, lastname_in, 
 
760
              address1_in, address2_in, city_in, state_in, zip_in, country_in, email_in, phone_in, 
 
761
              creditcardtype_in, creditcard_in, ccexpmon_in, ccexpyr_in, age_in, income_in, gender_in,
 
762
              ref customerid_out, ref rt))
 
763
              {
 
764
              Console.Error.WriteLine("Thread {0}: Error in Newcustomer {1}, thread exiting", 
 
765
                Thread.CurrentThread.Name, username_in);
 
766
              return;
 
767
              }
 
768
              
 
769
            if (customerid_out == 0) Console.Error.WriteLine("User name {0} already exists", username_in);         
 
770
            } while (customerid_out == 0); // end of do/while try newcustomer
 
771
            
 
772
//        Console.Error.WriteLine("Thread {0}: New user {1} logged in, customerid = {2}, RT= {3,10:F3}", 
 
773
//           Thread.CurrentThread.Name, username_in, customerid_out, rt);  
 
774
            
 
775
          rt_newcust = rt;  // Just count last iteration if had to retry username
 
776
          rt_tot += rt;
 
777
        
 
778
          } //End of Else (new user)
 
779
 
 
780
        // End of Login/New Customer Phase
 
781
        
 
782
        // Browse Phase
 
783
        
 
784
        // Search Product table different ways:
 
785
        // Browse by Category: with category randomized between 1 and MAX_CATEGORY (and SPECIAL=1)
 
786
        // Browse by Actor:  with first and last names selected randomly from list of names
 
787
        // Browse by Title:  with first and last words in title selected randomly from list of title words
 
788
             
 
789
        string browse_type_in = "", browse_category_in = "", browse_actor_in = "", browse_title_in = "";
 
790
        string browse_criteria= "";
 
791
        int batch_size_in;
 
792
        
 
793
        int n_browse = 1 + r.Next(2*Controller.n_searches - 1);   // Perform average of n_searches searches
 
794
        for (int ib=0; ib<n_browse; ib++)
 
795
          {
 
796
          batch_size_in = 1 + r.Next(2*Controller.search_batch_size - 1); // request avg of search_batch_size lines
 
797
          int search_type = r.Next(3); // randomly select search type
 
798
          switch(search_type)
 
799
            {
 
800
            case 0:  // Search by Category
 
801
              browse_type_in = "category";
 
802
              browse_category_in = (1 + r.Next(GlobalConstants.MAX_CATEGORY)).ToString();
 
803
              browse_actor_in = "";
 
804
              browse_title_in = "";
 
805
              browse_criteria = browse_category_in;
 
806
              break;
 
807
            case 1:  // Search by Actor 
 
808
              browse_type_in = "actor";
 
809
              browse_category_in = "";
 
810
              CreateActor();
 
811
              browse_actor_in = actor_in;
 
812
              browse_title_in = "";
 
813
              browse_criteria = browse_actor_in;
 
814
              break;
 
815
            case 2:  // Search by Title
 
816
              browse_type_in = "title";
 
817
              browse_category_in = "";
 
818
              browse_actor_in = "";
 
819
              CreateTitle();
 
820
              browse_title_in = title_in;
 
821
              browse_criteria = browse_title_in;
 
822
              break;
 
823
            }
 
824
            
 
825
          if (!ds2interfaces[Userid].ds2browse(browse_type_in, browse_category_in, browse_actor_in,
 
826
            browse_title_in, batch_size_in, customerid_out, ref rows_returned, ref prod_id_out, ref title_out,
 
827
            ref actor_out, ref price_out, ref special_out, ref common_prod_id_out, ref rt))
 
828
            {
 
829
            Console.Error.WriteLine("Thread {0}: Error in Browse by {1}, thread exiting", Thread.CurrentThread.Name,
 
830
              browse_type_in);
 
831
            return;
 
832
            }
 
833
 
 
834
//      Console.Error.WriteLine("Thread {0}: Search by {1}={2} returned {3} DVDs ({4} requested), RT= {5,10:F3}", 
 
835
//        Thread.CurrentThread.Name, browse_type_in, browse_criteria, rows_returned, batch_size_in,rt);
 
836
//      for (i=0; i<rows_returned; i++)
 
837
//        Console.Error.WriteLine("  Thread {0}: prod_id= {1} title= {2} actor= {3} price= {4} special= {5}" + 
 
838
//          " common_prod_id= {6}", 
 
839
//          Thread.CurrentThread.Name, prod_id_out[i], title_out[i], actor_out[i],
 
840
//          price_out[i], special_out[i], common_prod_id_out[i]);
 
841
            
 
842
          rt_browse += rt;
 
843
          }  // End of for ib=0 to n_browse
 
844
 
 
845
        rt_tot += rt_browse;           
 
846
        
 
847
        // End of Browse Phase
 
848
 
 
849
        // Purchase Phase
 
850
      
 
851
        for (i=0; i<GlobalConstants.MAX_ROWS; i++)
 
852
          {
 
853
          prod_id_in[i] = 0;
 
854
          qty_in[i] = 0;
 
855
          }
 
856
               
 
857
        // Randomize number of cart items with average n_line_items
 
858
        int cart_items = 1 + r.Next(2*Controller.n_line_items - 1);
 
859
        
 
860
        //For each cart item take product_id from search results or randomly select
 
861
        //for (i=0; i<cart_items; i++)
 
862
        //  {
 
863
        //  prod_id_in[i] = (rows_returned > i) ? prod_id_out[i] : (1 + r.Next(Controller.max_product));
 
864
        //  qty_in[i] = 1 + r.Next(3);  // qty (1, 2 or 3)
 
865
        //  }
 
866
 
 
867
        // For each cart item randomly select product_id using weighted prod_array
 
868
        for (i=0; i<cart_items; i++)
 
869
          {
 
870
          prod_id_in[i] = Controller.prod_array[r.Next(Controller.prod_array_size)];
 
871
          qty_in[i] = 1 + r.Next(3);  // qty (1, 2 or 3)
 
872
//        Console.Error.WriteLine("Thread {0}: Purchase prod_id_in[{1}] = {2}  qty_in[{1}]= {3}", 
 
873
//          Thread.CurrentThread.Name, i, prod_id_in[i], qty_in[i]);
 
874
          }
 
875
 
 
876
        if (!ds2interfaces[Userid].ds2purchase(cart_items, prod_id_in, qty_in, customerid_out, ref neworderid_out, 
 
877
          ref IsRollback, ref rt))
 
878
          {
 
879
          Console.Error.WriteLine("Thread {0}: Error in Purchase, thread exiting", Thread.CurrentThread.Name);
 
880
          return;
 
881
          }
 
882
        
 
883
//      Console.Error.WriteLine("Thread {0}: Purchase completed successfully, neworderid = {1}, rollback= {2}, " +
 
884
//        "RT= {3,10:F3}", Thread.CurrentThread.Name, neworderid_out, IsRollback, rt);
 
885
 
 
886
        rt_purchase = rt;
 
887
        rt_tot += rt;
 
888
        
 
889
        // End of Purchase Phase
 
890
        // End of Order sequence
 
891
      
 
892
        // Block other User threads or Controller from accessing this code while we update these values
 
893
        Monitor.Enter(Controller.UpdateLock); 
 
894
          if (IsLogin)
 
895
            {
 
896
            ++Controller.n_login_overall;
 
897
            Controller.rt_login_overall += rt_login;
 
898
            }
 
899
          else 
 
900
            {
 
901
            ++Controller.n_newcust_overall;
 
902
            Controller.rt_newcust_overall += rt_newcust;
 
903
            }
 
904
          Controller.n_browse_overall += n_browse;
 
905
          Controller.rt_browse_overall += rt_browse;
 
906
          ++Controller.n_purchase_overall;
 
907
          ++Controller.n_purchase_from_start;
 
908
          Controller.rt_purchase_overall += rt_purchase;
 
909
          if (IsRollback) 
 
910
            {
 
911
            ++Controller.n_rollbacks_overall;        
 
912
            ++Controller.n_rollbacks_from_start;        
 
913
            }
 
914
          ++Controller.n_overall;
 
915
          Controller.rt_tot_overall += rt_tot;
 
916
          Controller.rt_tot_lastn[Controller.n_overall%GlobalConstants.LAST_N] = rt_tot;
 
917
        Monitor.Exit(Controller.UpdateLock);
 
918
                       
 
919
        Thread.Sleep(r.Next(2*(int)Math.Floor(1000*Controller.think_time))); // Delay think time seconds               
 
920
                       
 
921
        } while(!Controller.End); // End of Thread Emulation loop
 
922
      
 
923
      ds2interfaces[Userid].ds2close();
 
924
          
 
925
      Console.Error.WriteLine("Thread {0}: exiting",  Thread.CurrentThread.Name); Console.Out.Flush();    
 
926
      }  // End of Emulate()
 
927
//
 
928
//-------------------------------------------------------------------------------------------------
 
929
//          
 
930
    void CreateUserData()
 
931
      {
 
932
      string[] states = new string[] {"AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "HI", "IA", 
 
933
                        "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MS", "MT", "NC", 
 
934
                        "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", 
 
935
                        "TX", "UT", "VA", "VT", "WA", "WI", "WV", "WY"};
 
936
 
 
937
      string[] countries = new string[] {"Australia", "Canada", "Chile", "China", "France", "Germany", "Japan", 
 
938
                           "Russia", "South Africa", "UK"};
 
939
   
 
940
      int j;
 
941
      firstname_in = ""; for (j=0; j<6; j++){firstname_in = firstname_in + (char) (65 + r.Next(26));}
 
942
      lastname_in = ""; for (j=0; j<10; j++){lastname_in = lastname_in + (char) (65 +  r.Next(26));}
 
943
      city_in = ""; for (j=0; j<7; j++){city_in = city_in + (char) (65 + r.Next(26));}
 
944
          
 
945
      if (r.Next(2) == 1) // Select region (US or ROW)
 
946
        { //ROW    
 
947
        zip_in = "";
 
948
        state_in = "";
 
949
        country_in = countries[r.Next(10)];
 
950
        }
 
951
      else //US
 
952
        {
 
953
        zip_in = (r.Next(100000)).ToString();
 
954
        state_in = states[r.Next(50)];
 
955
        country_in = "US";
 
956
        } //End Else
 
957
   
 
958
      phone_in = "" + r.Next(100, 1000) + r.Next(10000000);
 
959
      creditcardtype_in = 1 + r.Next(5);
 
960
      creditcard_in = "" + r.Next(10000000, 100000000) + r.Next(10000000, 100000000);
 
961
      ccexpmon_in = 1 + r.Next(12);
 
962
      ccexpyr_in = 2008 + r.Next(5);
 
963
      address1_in = phone_in + " Dell Way";
 
964
      address2_in = "";
 
965
      email_in = lastname_in + "@dell.com";           
 
966
      age_in = r.Next(18, 100);
 
967
      income_in = 20000 * r.Next(1, 6); // >$20,000, >$40,000, >$60,000, >$80,000, >$100,000
 
968
      gender_in =  (r.Next(2)== 1) ? "M" : "F";
 
969
    
 
970
      }  // End of CreateUserData
 
971
      
 
972
//
 
973
//-------------------------------------------------------------------------------------------------
 
974
//      
 
975
    void CreateActor()
 
976
      {
 
977
      // Names compiled by Dara Jaffe
 
978
 
 
979
      // 200 actor/actress firstnames
 
980
      string[] actor_firstnames = new string[]
 
981
        {
 
982
        "ADAM", "ADRIEN", "AL", "ALAN", "ALBERT", "ALEC", "ALICIA", "ANDY", "ANGELA", "ANGELINA", "ANJELICA", 
 
983
        "ANNE", "ANNETTE", "ANTHONY", "AUDREY", "BELA", "BEN", "BETTE", "BOB", "BRAD", "BRUCE", "BURT", "CAMERON", 
 
984
        "CANDICE", "CARMEN", "CARRIE", "CARY", "CATE", "CHARLES", "CHARLIZE", "CHARLTON", "CHEVY", "CHRIS", 
 
985
        "CHRISTIAN", "CHRISTOPHER", "CLARK", "CLINT", "CUBA", "DAN", "DANIEL", "DARYL", "DEBBIE", "DENNIS", 
 
986
        "DENZEL", "DIANE", "DORIS", "DREW", "DUSTIN", "ED", "EDWARD", "ELIZABETH", "ELLEN", "ELVIS", "EMILY", 
 
987
        "ETHAN", "EWAN", "FARRAH", "FAY", "FRANCES", "FRANK", "FRED", "GARY", "GENE", "GEOFFREY", "GINA", "GLENN", 
 
988
        "GOLDIE", "GRACE", "GREG", "GREGORY", "GRETA", "GROUCHO", "GWYNETH", "HALLE", "HARRISON", "HARVEY", 
 
989
        "HELEN", "HENRY", "HILARY", "HUGH", "HUME", "HUMPHREY", "IAN", "INGRID", "JACK", "JADA", "JAMES", "JANE", 
 
990
        "JAYNE", "JEFF", "JENNIFER", "JEREMY", "JESSICA", "JIM", "JOAN", "JODIE", "JOE", "JOHN", "JOHNNY", "JON", 
 
991
        "JUDE", "JUDI", "JUDY", "JULIA", "JULIANNE", "JULIETTE", "KARL", "KATE", "KATHARINE", "KENNETH", "KEVIN", 
 
992
        "KIM", "KIRK", "KIRSTEN", "LANA", "LAURA", "LAUREN", "LAURENCE", "LEELEE", "LENA", "LEONARDO", "LIAM", 
 
993
        "LISA", "LIV", "LIZA", "LUCILLE", "MADELINE", "MAE", "MARILYN", "MARISA", "MARLENE", "MARLON", "MARY", 
 
994
        "MATT", "MATTHEW", "MEG", "MEL", "MENA", "MERYL", "MICHAEL", "MICHELLE", "MILLA", "MINNIE", "MIRA", 
 
995
        "MORGAN", "NATALIE", "NEVE", "NICK", "NICOLAS", "NICOLE", "OLYMPIA", "OPRAH", "ORLANDO", "PARKER", 
 
996
        "PAUL", "PEARL", "PENELOPE", "RALPH", "RAY", "REESE", "RENEE", "RICHARD", "RIP", "RITA", "RIVER", 
 
997
        "ROBERT", "ROBIN", "ROCK", "ROSIE", "RUBY", "RUSSELL", "SALLY", "SALMA", "SANDRA", "SCARLETT", "SEAN", 
 
998
        "SHIRLEY", "SIDNEY", "SIGOURNEY", "SISSY", "SOPHIA", "SPENCER", "STEVE", "SUSAN", "SYLVESTER", "THORA", 
 
999
        "TIM", "TOM", "UMA", "VAL", "VIVIEN", "WALTER", "WARREN", "WHOOPI", "WILL", "WILLEM", "WILLIAM", "WINONA", 
 
1000
        "WOODY", "ZERO"
 
1001
        };
 
1002
        
 
1003
      // 200 actor/actress lastnames  
 
1004
      string[] actor_lastnames = new string[]
 
1005
        {
 
1006
        "AFFLECK", "AKROYD", "ALLEN", "ANISTON", "ASTAIRE", "BACALL", "BAILEY", "BALE", "BALL", "BARRYMORE", 
 
1007
        "BASINGER", "BEATTY", "BENING", "BERGEN", "BERGMAN", "BERRY", "BIRCH", "BLANCHETT", "BLOOM", "BOGART", 
 
1008
        "BOLGER", "BRANAGH", "BRANDO", "BRIDGES", "BRODY", "BULLOCK", "CAGE", "CAINE", "CAMPBELL", "CARREY", 
 
1009
        "CHAPLIN", "CHASE", "CLOSE", "COOPER", "COSTNER", "CRAWFORD", "CRONYN", "CROWE", "CRUISE", "CRUZ", 
 
1010
        "DAFOE", "DAMON", "DAVIS", "DAY", "DAY-LEWIS", "DEAN", "DEE", "DEGENERES", "DENCH", "DENIRO", 
 
1011
        "DEPP", "DERN", "DIAZ", "DICAPRIO", "DIETRICH", "DOUGLAS", "DREYFUSS", "DRIVER", "DUKAKIS", "DUNST", 
 
1012
        "EASTWOOD", "FAWCETT", "FIELD", "FIENNES", "FINNEY", "FISHER", "FONDA", "FORD", "FOSTER", "FREEMAN", 
 
1013
        "GABLE", "GARBO", "GARCIA", "GARLAND", "GIBSON", "GOLDBERG", "GOODING", "GRANT", "GUINESS", "HACKMAN", 
 
1014
        "HANNAH", "HARRIS", "HAWKE", "HAWN", "HAYEK", "HECHE", "HEPBURN", "HESTON", "HOFFMAN", "HOPE", 
 
1015
        "HOPKINS", "HOPPER", "HORNE", "HUDSON", "HUNT", "HURT", "HUSTON", "IRONS", "JACKMAN", "JOHANSSON", 
 
1016
        "JOLIE", "JOVOVICH", "KAHN", "KEATON", "KEITEL", "KELLY", "KIDMAN", "KILMER", "KINNEAR", "KUDROW", 
 
1017
        "LANCASTER", "LANSBURY", "LAW", "LEIGH", "LEWIS", "LOLLOBRIGIDA", "LOREN", "LUGOSI", "MALDEN", "MANSFIELD", 
 
1018
        "MARTIN", "MARX", "MATTHAU", "MCCONAUGHEY", "MCDORMAND", "MCGREGOR", "MCKELLEN", "MCQUEEN", "MINELLI", "MIRANDA", 
 
1019
        "MONROE", "MOORE", "MOSTEL", "NEESON", "NEWMAN", "NICHOLSON", "NOLTE", "NORTON", "O’DONNELL", "OLIVIER", 
 
1020
        "PACINO", "PALTROW", "PECK", "PENN", "PESCI", "PFEIFFER", "PHOENIX", "PINKETT", "PITT", "POITIER", 
 
1021
        "POSEY", "PRESLEY", "REYNOLDS", "RICKMAN", "ROBBINS", "ROBERTS", "RUSH", "RUSSELL", "RYAN", "RYDER", 
 
1022
        "SANDLER", "SARANDON", "SILVERSTONE", "SINATRA", "SMITH", "SOBIESKI", "SORVINO", "SPACEK", "STALLONE", "STREEP", 
 
1023
        "SUVARI", "SWANK", "TANDY", "TAUTOU", "TAYLOR", "TEMPLE", "THERON", "THURMAN", "TOMEI", "TORN", 
 
1024
        "TRACY", "TURNER", "TYLER", "VOIGHT", "WAHLBERG", "WALKEN", "WASHINGTON", "WATSON", "WAYNE", "WEAVER", 
 
1025
        "WEST", "WILLIAMS", "WILLIS", "WILSON", "WINFREY", "WINSLET", "WITHERSPOON", "WOOD", "WRAY", "ZELLWEGER"
 
1026
        }; 
 
1027
      
 
1028
      actor_in = actor_firstnames[r.Next(200)] + " " + actor_lastnames[r.Next(200)];
 
1029
      
 
1030
      }  // End of CreateActor
 
1031
       
 
1032
//
 
1033
//-------------------------------------------------------------------------------------------------
 
1034
//    
 
1035
    void CreateTitle()
 
1036
      {
 
1037
      // Names compiled by Dara Jaffe
 
1038
      
 
1039
      // 1000 movie title words
 
1040
 
 
1041
      string[] movie_titles = new string[]
 
1042
        {
 
1043
        "ACADEMY", "ACE", "ADAPTATION", "AFFAIR", "AFRICAN", "AGENT", "AIRPLANE", "AIRPORT", "ALABAMA", "ALADDIN", 
 
1044
        "ALAMO", "ALASKA", "ALI", "ALICE", "ALIEN", "ALLEY", "ALONE", "ALTER", "AMADEUS", "AMELIE", 
 
1045
        "AMERICAN", "AMISTAD", "ANACONDA", "ANALYZE", "ANGELS", "ANNIE", "ANONYMOUS", "ANTHEM", "ANTITRUST", "ANYTHING", 
 
1046
        "APACHE", "APOCALYPSE", "APOLLO", "ARABIA", "ARACHNOPHOBIA", "ARGONAUTS", "ARIZONA", "ARK", "ARMAGEDDON", "ARMY", 
 
1047
        "ARSENIC", "ARTIST", "ATLANTIS", "ATTACKS", "ATTRACTION", "AUTUMN", "BABY", "BACKLASH", "BADMAN", "BAKED", 
 
1048
        "BALLOON", "BALLROOM", "BANG", "BANGER", "BARBARELLA", "BAREFOOT", "BASIC", "BEACH", "BEAR", "BEAST", 
 
1049
        "BEAUTY", "BED", "BEDAZZLED", "BEETHOVEN", "BEHAVIOR", "BENEATH", "BERETS", "BETRAYED", "BEVERLY", "BIKINI", 
 
1050
        "BILKO", "BILL", "BINGO", "BIRCH", "BIRD", "BIRDCAGE", "BIRDS", "BLACKOUT", "BLADE", "BLANKET", 
 
1051
        "BLINDNESS", "BLOOD", "BLUES", "BOILED", "BONNIE", "BOOGIE", "BOONDOCK", "BORN", "BORROWERS", "BOULEVARD", 
 
1052
        "BOUND", "BOWFINGER", "BRANNIGAN", "BRAVEHEART", "BREAKFAST", "BREAKING", "BRIDE", "BRIGHT", "BRINGING", "BROOKLYN", 
 
1053
        "BROTHERHOOD", "BUBBLE", "BUCKET", "BUGSY", "BULL", "BULWORTH", "BUNCH", "BUTCH", "BUTTERFLY", "CABIN", 
 
1054
        "CADDYSHACK", "CALENDAR", "CALIFORNIA", "CAMELOT", "CAMPUS", "CANDIDATE", "CANDLES", "CANYON", "CAPER", "CARIBBEAN", 
 
1055
        "CAROL", "CARRIE", "CASABLANCA", "CASPER", "CASSIDY", "CASUALTIES", "CAT", "CATCH", "CAUSE", "CELEBRITY", 
 
1056
        "CENTER", "CHAINSAW", "CHAMBER", "CHAMPION", "CHANCE", "CHAPLIN", "CHARADE", "CHARIOTS", "CHASING", "CHEAPER", 
 
1057
        "CHICAGO", "CHICKEN", "CHILL", "CHINATOWN", "CHISUM", "CHITTY", "CHOCOLAT", "CHOCOLATE", "CHRISTMAS", "CIDER", 
 
1058
        "CINCINATTI", "CIRCUS", "CITIZEN", "CLASH", "CLEOPATRA", "CLERKS", "CLOCKWORK", "CLONES", "CLOSER", "CLUB", 
 
1059
        "CLUE", "CLUELESS", "CLYDE", "COAST", "COLDBLOODED", "COLOR", "COMA", "COMANCHEROS", "COMFORTS", "COMMAND", 
 
1060
        "COMMANDMENTS", "CONEHEADS", "CONFESSIONS", "CONFIDENTIAL", "CONFUSED", "CONGENIALITY", "CONNECTICUT", "CONNECTION", 
 
1061
        "CONQUERER", "CONSPIRACY", "CONTACT", "CONTROL", "CONVERSATION", "CORE", "COWBOY", "CRAFT", "CRANES", "CRAZY", 
 
1062
        "CREATURES", "CREEPERS", "CROOKED", "CROSSING", "CROSSROADS", "CROW", "CROWDS", "CRUELTY", "CRUSADE", "CRYSTAL", 
 
1063
        "CUPBOARD", "CURTAIN", "CYCLONE", "DADDY", "DAISY", "DALMATIONS", "DANCES", "DANCING", "DANGEROUS", "DARES", 
 
1064
        "DARKNESS", "DARKO", "DARLING", "DARN", "DATE", "DAUGHTER", "DAWN", "DAY", "DAZED", "DECEIVER", "DEEP", "DEER", 
 
1065
        "DELIVERANCE", "DESERT", "DESIRE", "DESPERATE", "DESTINATION", "DESTINY", "DETAILS", "DETECTIVE", "DEVIL", "DIARY", 
 
1066
        "DINOSAUR", "DIRTY", "DISCIPLE", "DISTURBING", "DIVIDE", "DIVINE", "DIVORCE", "DOCTOR", "DOGMA", "DOLLS", 
 
1067
        "DONNIE", "DOOM", "DOORS", "DORADO", "DOUBLE", "DOUBTFIRE", "DOWNHILL", "DOZEN", "DRACULA", "DRAGON", 
 
1068
        "DRAGONFLY", "DREAM", "DRIFTER", "DRIVER", "DRIVING", "DROP", "DRUMLINE", "DRUMS", "DUCK", "DUDE", 
 
1069
        "DUFFEL", "DUMBO", "DURHAM", "DWARFS", "DYING", "DYNAMITE", "EAGLES", "EARLY", "EARRING", "EARTH", 
 
1070
        "EASY", "EDGE", "EFFECT", "EGG", "EGYPT", "ELEMENT", "ELEPHANT", "ELF", "ELIZABETH", "EMPIRE", 
 
1071
        "ENCINO", "ENCOUNTERS", "ENDING", "ENEMY", "ENGLISH", "ENOUGH", "ENTRAPMENT", "ESCAPE", "EVE", "EVERYONE", "EVOLUTION", 
 
1072
        "EXCITEMENT", "EXORCIST", "EXPECATIONS", "EXPENDABLE", "EXPRESS", "EXTRAORDINARY", "EYES", "FACTORY", "FALCON", 
 
1073
        "FAMILY", "FANTASIA", "FANTASY", "FARGO", "FATAL", "FEATHERS", "FELLOWSHIP", "FERRIS", "FEUD", "FEVER", 
 
1074
        "FICTION", "FIDDLER", "FIDELITY", "FIGHT", "FINDING", "FIRE", "FIREBALL", "FIREHOUSE", "FISH", "FLAMINGOS", 
 
1075
        "FLASH", "FLATLINERS", "FLIGHT", "FLINTSTONES", "FLOATS", "FLYING", "FOOL", "FOREVER", "FORREST", "FORRESTER", 
 
1076
        "FORWARD", "FRANKENSTEIN", "FREAKY", "FREDDY", "FREEDOM", "FRENCH", "FRIDA", "FRISCO", "FROGMEN", "FRONTIER", 
 
1077
        "FROST", "FUGITIVE", "FULL", "FURY", "GABLES", "GALAXY", "GAMES", "GANDHI", "GANGS", "GARDEN", 
 
1078
        "GASLIGHT", "GATHERING", "GENTLEMEN", "GHOST", "GHOSTBUSTERS", "GIANT", "GILBERT", "GILMORE", "GLADIATOR", "GLASS", 
 
1079
        "GLEAMING", "GLORY", "GO", "GODFATHER", "GOLD", "GOLDFINGER", "GOLDMINE", "GONE", "GOODFELLAS", "GORGEOUS", 
 
1080
        "GOSFORD", "GRACELAND", "GRADUATE", "GRAFFITI", "GRAIL", "GRAPES", "GREASE", "GREATEST", "GREEDY", "GREEK", 
 
1081
        "GRINCH", "GRIT", "GROOVE", "GROSSE", "GROUNDHOG", "GUMP", "GUN", "GUNFIGHT", "GUNFIGHTER", "GUYS", 
 
1082
        "HALF", "HALL", "HALLOWEEN", "HAMLET", "HANDICAP", "HANGING", "HANKY", "HANOVER", "HAPPINESS", "HARDLY", 
 
1083
        "HAROLD", "HARPER", "HARRY", "HATE", "HAUNTED", "HAUNTING", "HAWK", "HEAD", "HEARTBREAKERS", "HEAVEN", 
 
1084
        "HEAVENLY", "HEAVYWEIGHTS", "HEDWIG", "HELLFIGHTERS", "HIGH", "HIGHBALL", "HILLS", "HOBBIT", "HOCUS", "HOLES", 
 
1085
        "HOLIDAY", "HOLLOW", "HOLLYWOOD", "HOLOCAUST", "HOLY", "HOME", "HOMEWARD", "HOMICIDE", "HONEY", "HOOK", 
 
1086
        "HOOSIERS", "HOPE", "HORN", "HORROR", "HOTEL", "HOURS", "HOUSE", "HUMAN", "HUNCHBACK", "HUNGER", 
 
1087
        "HUNTER", "HUNTING", "HURRICANE", "HUSTLER", "HYDE", "HYSTERICAL", "ICE", "IDAHO", "IDENTITY", "IDOLS", 
 
1088
        "IGBY", "ILLUSION", "IMAGE", "IMPACT", "IMPOSSIBLE", "INCH", "INDEPENDENCE", "INDIAN", "INFORMER", "INNOCENT", 
 
1089
        "INSECTS", "INSIDER", "INSTINCT", "INTENTIONS", "INTERVIEW", "INTOLERABLE", "INTRIGUE", "INVASION", "IRON", "ISHTAR", 
 
1090
        "ISLAND", "ITALIAN", "JACKET", "JADE", "JAPANESE", "JASON", "JAWBREAKER", "JAWS", "JEDI", "JEEPERS", 
 
1091
        "JEKYLL", "JEOPARDY", "JERICHO", "JERK", "JERSEY", "JET", "JINGLE", "JOON", "JUGGLER", "JUMANJI", 
 
1092
        "JUMPING", "JUNGLE", "KANE", "KARATE", "KENTUCKIAN", "KICK", "KILL", "KILLER", "KING", "KISS", 
 
1093
        "KISSING", "KNOCK", "KRAMER", "KWAI", "LABYRINTH", "LADY", "LADYBUGS", "LAMBS", "LANGUAGE", "LAWLESS", 
 
1094
        "LAWRENCE", "LEAGUE", "LEATHERNECKS", "LEBOWSKI", "LEGALLY", "LEGEND", "LESSON", "LIAISONS", "LIBERTY", "LICENSE", 
 
1095
        "LIES", "LIFE", "LIGHTS", "LION", "LOATHING", "LOCK", "LOLA", "LOLITA", "LONELY", "LORD", 
 
1096
        "LOSE", "LOSER", "LOST", "LOUISIANA", "LOVE", "LOVELY", "LOVER", "LOVERBOY", "LUCK", "LUCKY", 
 
1097
        "LUKE", "LUST", "MADIGAN", "MADISON", "MADNESS", "MADRE", "MAGIC", "MAGNIFICENT", "MAGNOLIA", "MAGUIRE", 
 
1098
        "MAIDEN", "MAJESTIC", "MAKER", "MALKOVICH", "MALLRATS", "MALTESE", "MANCHURIAN", "MANNEQUIN", "MARRIED", "MARS", 
 
1099
        "MASK", "MASKED", "MASSACRE", "MASSAGE", "MATRIX", "MAUDE", "MEET", "MEMENTO", "MENAGERIE", "MERMAID", 
 
1100
        "METAL", "METROPOLIS", "MICROCOSMOS", "MIDNIGHT", "MIDSUMMER", "MIGHTY", "MILE", "MILLION", "MINDS", "MINE", 
 
1101
        "MINORITY", "MIRACLE", "MISSION", "MIXED", "MOB", "MOCKINGBIRD", "MOD", "MODEL", "MODERN", "MONEY", 
 
1102
        "MONSOON", "MONSTER", "MONTEREY", "MONTEZUMA", "MOON", "MOONSHINE", "MOONWALKER", "MOSQUITO", "MOTHER", "MOTIONS", 
 
1103
        "MOULIN", "MOURNING", "MOVIE", "MULAN", "MULHOLLAND", "MUMMY", "MUPPET", "MURDER", "MUSCLE", "MUSIC", 
 
1104
        "MUSKETEERS", "MUSSOLINI", "MYSTIC", "NAME", "NASH", "NATIONAL", "NATURAL", "NECKLACE", "NEIGHBORS", "NEMO", 
 
1105
        "NETWORK", "NEWSIES", "NEWTON", "NIGHTMARE", "NONE", "NOON", "NORTH", "NORTHWEST", "NOTORIOUS", "NOTTING", 
 
1106
        "NOVOCAINE", "NUTS", "OCTOBER", "ODDS", "OKLAHOMA", "OLEANDER", "OPEN", "OPERATION", "OPPOSITE", "OPUS", 
 
1107
        "ORANGE", "ORDER", "ORIENT", "OSCAR", "OTHERS", "OUTBREAK", "OUTFIELD", "OUTLAW", "OZ", "PACIFIC", 
 
1108
        "PACKER", "PAJAMA", "PANIC", "PANKY", "PANTHER", "PAPI", "PARADISE", "PARIS", "PARK", "PARTY", 
 
1109
        "PAST", "PATHS", "PATIENT", "PATRIOT", "PATTON", "PAYCHECK", "PEACH", "PEAK", "PEARL", "PELICAN", 
 
1110
        "PERDITION", "PERFECT", "PERSONAL", "PET", "PHANTOM", "PHILADELPHIA", "PIANIST", "PICKUP", "PILOT", "PINOCCHIO", 
 
1111
        "PIRATES", "PITTSBURGH", "PITY", "PIZZA", "PLATOON", "PLUTO", "POCUS", "POLISH", "POLLOCK", "POND", 
 
1112
        "POSEIDON", "POTLUCK", "POTTER", "PREJUDICE", "PRESIDENT", "PRIDE", "PRIMARY", "PRINCESS", "PRIVATE", "PRIX", 
 
1113
        "PSYCHO", "PULP", "PUNK", "PURE", "PURPLE", "QUEEN", "QUEST", "QUILLS", "RACER", "RAGE", 
 
1114
        "RAGING", "RAIDERS", "RAINBOW", "RANDOM", "RANGE", "REAP", "REAR", "REBEL", "RECORDS", "REDEMPTION", 
 
1115
        "REDS", "REEF", "REIGN", "REMEMBER", "REQUIEM", "RESERVOIR", "RESURRECTION", "REUNION", "RIDER", "RIDGEMONT", 
 
1116
        "RIGHT", "RINGS", "RIVER", "ROAD", "ROBBERS", "ROBBERY", "ROCK", "ROCKETEER", "ROCKY", "ROLLERCOASTER", 
 
1117
        "ROMAN", "ROOF", "ROOM", "ROOTS", "ROSES", "ROUGE", "ROXANNE", "RUGRATS", "RULES", "RUN", 
 
1118
        "RUNAWAY", "RUNNER", "RUSH", "RUSHMORE", "SABRINA", "SADDLE", "SAGEBRUSH", "SAINTS", "SALUTE", "SAMURAI", 
 
1119
        "SANTA", "SASSY", "SATISFACTION", "SATURDAY", "SATURN", "SAVANNAH", "SCALAWAG", "SCARFACE", "SCHOOL", "SCISSORHANDS", 
 
1120
        "SCORPION", "SEA", "SEABISCUIT", "SEARCHERS", "SEATTLE", "SECRET", "SECRETARY", "SECRETS", "SENSE", "SENSIBILITY", 
 
1121
        "SEVEN", "SHAKESPEARE", "SHANE", "SHANGHAI", "SHAWSHANK", "SHEPHERD", "SHINING", "SHIP", "SHOCK", "SHOOTIST", 
 
1122
        "SHOW", "SHREK", "SHRUNK", "SIDE", "SIEGE", "SIERRA", "SILENCE", "SILVERADO", "SIMON", "SINNERS", 
 
1123
        "SISTER", "SKY", "SLACKER", "SLEEPING", "SLEEPLESS", "SLEEPY", "SLEUTH", "SLING", "SLIPPER", "SLUMS", 
 
1124
        "SMILE", "SMOKING", "SMOOCHY", "SNATCH", "SNATCHERS", "SNOWMAN", "SOLDIERS", "SOMETHING", "SONG", "SONS", 
 
1125
        "SORORITY", "SOUP", "SOUTH", "SPARTACUS", "SPEAKEASY", "SPEED", "SPICE", "SPIKING", "SPINAL", "SPIRIT", 
 
1126
        "SPIRITED", "SPLASH", "SPLENDOR", "SPOILERS", "SPY", "SQUAD", "STAGE", "STAGECOACH", "STALLION", "STAMPEDE", 
 
1127
        "STAR", "STATE", "STEEL", "STEERS", "STEPMOM", "STING", "STOCK", "STONE", "STORM", "STORY", 
 
1128
        "STRAIGHT", "STRANGELOVE", "STRANGER", "STRANGERS", "STREAK", "STREETCAR", "STRICTLY", "SUBMARINE", "SUGAR", "SUICIDES", 
 
1129
        "SUIT", "SUMMER", "SUN", "SUNDANCE", "SUNRISE", "SUNSET", "SUPER", "SUPERFLY", "SUSPECTS", "SWARM", 
 
1130
        "SWEDEN", "SWEET", "SWEETHEARTS", "TADPOLE", "TALENTED", "TARZAN", "TAXI", "TEEN", "TELEGRAPH", "TELEMARK", 
 
1131
        "TEMPLE", "TENENBAUMS", "TEQUILA", "TERMINATOR", "TEXAS", "THEORY", "THIEF", "THIN", "TIES", "TIGHTS", 
 
1132
        "TIMBERLAND", "TITANIC", "TITANS", "TOMATOES", "TOMORROW", "TOOTSIE", "TORQUE", "TOURIST", "TOWERS", "TOWN", 
 
1133
        "TRACY", "TRADING", "TRAFFIC", "TRAIN", "TRAINSPOTTING", "TRAMP", "TRANSLATION", "TRAP", "TREASURE", "TREATMENT", 
 
1134
        "TRIP", "TROJAN", "TROOPERS", "TROUBLE", "TRUMAN", "TURN", "TUXEDO", "TWISTED", "TYCOON", "UNBREAKABLE", 
 
1135
        "UNCUT", "UNDEFEATED", "UNFAITHFUL", "UNFORGIVEN", "UNITED", "UNTOUCHABLES", "UPRISING", "UPTOWN", "USUAL", "VACATION", 
 
1136
        "VALENTINE", "VALLEY", "VAMPIRE", "VANILLA", "VANISHED", "VANISHING", "VARSITY", "VELVET", "VERTIGO", "VICTORY", 
 
1137
        "VIDEOTAPE", "VIETNAM", "VILLAIN", "VIRGIN", "VIRGINIAN", "VIRTUAL", "VISION", "VOICE", "VOLCANO", "VOLUME", 
 
1138
        "VOYAGE", "WAGON", "WAIT", "WAKE", "WALLS", "WANDA", "WAR", "WARDROBE", "WARLOCK", "WARS", 
 
1139
        "WASH", "WASTELAND", "WATCH", "WATERFRONT", "WATERSHIP", "WEDDING", "WEEKEND", "WEREWOLF", "WEST", "WESTWARD", 
 
1140
        "WHALE", "WHISPERER", "WIFE", "WILD", "WILLOW", "WIND", "WINDOW", "WISDOM", "WITCHES", "WIZARD", 
 
1141
        "WOLVES", "WOMEN", "WON", "WONDERFUL", "WONDERLAND", "WONKA", "WORDS", "WORKER", "WORKING", "WORLD", 
 
1142
        "WORST", "WRATH", "WRONG", "WYOMING", "YENTL", "YOUNG", "YOUTH", "ZHIVAGO", "ZOOLANDER", "ZORRO", 
 
1143
        };
 
1144
        title_in = movie_titles[r.Next(1000)] + " " + movie_titles[r.Next(1000)];
 
1145
      }  // End of CreateTitle   
 
1146
   
 
1147
    } // End of Class User
 
1148
    
 
1149
  } // End of Namespace ds2xdriver
 
1150
 
 
1151
 
 
1152
 
 
1153
 
 
1154
 
 
1155