1/*
2**********************************************************************
3* Copyright (c) 2002-2007, International Business Machines
4* Corporation and others.  All Rights Reserved.
5**********************************************************************
6*/
7#ifndef _UPERF_H
8#define _UPERF_H
9
10#include "unicode/utypes.h"
11#include "unicode/unistr.h"
12#include "unicode/ustring.h"
13
14#include "unicode/testtype.h"
15#include "unicode/utimer.h"
16#include "ucbuf.h"
17
18// Forward declarations from uoptions.h.
19struct UOption;
20typedef struct UOption UOption;
21
22#if !UCONFIG_NO_CONVERSION
23
24U_NAMESPACE_USE
25// Use the TESTCASE macro in subclasses of IntlTest.  Define the
26// runIndexedTest method in this fashion:
27//
28//| void MyTest::runIndexedTest(int32_t index, UBool exec,
29//|                             const char* &name, char* /*par*/) {
30//|     switch (index) {
31//|         TESTCASE(0,TestSomething);
32//|         TESTCASE(1,TestSomethingElse);
33//|         TESTCASE(2,TestAnotherThing);
34//|         default:
35//|             name = "";
36//|             return NULL;
37//|     }
38//| }
39#if 0
40#define TESTCASE(id,test)                       \
41    case id:                                    \
42        name = #test;                           \
43        if (exec) {                             \
44            fprintf(stdout,#test "---");        \
45            fprintf(stdout,"\n");               \
46            return test();                      \
47        }                                       \
48        break
49
50#endif
51#define TESTCASE(id,test)                       \
52    case id:                                    \
53        name = #test;                           \
54        if (exec) {                             \
55            return test();                      \
56        }                                       \
57        break
58
59/**
60 * Subclasses of PerfTest will need to create subclasses of
61 * Function that define a call() method which contains the code to
62 * be timed.  They then call setTestFunction() in their "Test..."
63 * method to establish this as the current test functor.
64 */
65class T_CTEST_EXPORT_API UPerfFunction {
66public:
67    /**
68     * Subclasses must implement this method to do the action to be
69     * measured.
70     */
71    virtual void call(UErrorCode* status)=0;
72
73    /**
74     * Subclasses must implement this method to return positive
75     * integer indicating the number of operations in a single
76     * call to this object's call() method.
77     */
78    virtual long getOperationsPerIteration()=0;
79    /**
80     * Subclasses should override this method to return either positive
81     * or negative integer indicating the number of events in a single
82     * call to this object's call() method, if applicable
83     * e.g: Number of breaks / iterations for break iterator
84     */
85    virtual long getEventsPerIteration(){
86        return -1;
87    }
88    /**
89     * destructor
90     */
91    virtual ~UPerfFunction() {}
92
93    /**
94     * Call call() n times in a tight loop and return the elapsed
95     * milliseconds.  If n is small and call() is fast the return
96     * result may be zero.  Small return values have limited
97     * meaningfulness, depending on the underlying CPU and OS.
98     */
99     virtual double time(int32_t n, UErrorCode* status) {
100        UTimer start, stop;
101        utimer_getTime(&start);
102        while (n-- > 0) {
103            call(status);
104        }
105        utimer_getTime(&stop);
106        return utimer_getDeltaSeconds(&start,&stop); // ms
107    }
108
109};
110
111
112class T_CTEST_EXPORT_API UPerfTest {
113public:
114    UBool run();
115    UBool runTest( char* name = NULL, char* par = NULL ); // not to be overidden
116
117    virtual void usage( void ) ;
118
119    virtual ~UPerfTest();
120
121    void setCaller( UPerfTest* callingTest ); // for internal use only
122
123    void setPath( char* path ); // for internal use only
124
125    ULine* getLines(UErrorCode& status);
126
127    const UChar* getBuffer(int32_t& len,UErrorCode& status);
128
129protected:
130    UPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
131
132    UPerfTest(int32_t argc, const char* argv[],
133              UOption addOptions[], int32_t addOptionsCount,
134              const char *addUsage,
135              UErrorCode& status);
136
137    void init(UOption addOptions[], int32_t addOptionsCount,
138              UErrorCode& status);
139
140    virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
141
142    virtual UBool runTestLoop( char* testname, char* par );
143
144    virtual UBool callTest( UPerfTest& testToBeCalled, char* par );
145
146    int32_t      _argc;
147    const char** _argv;
148    const char * _addUsage;
149    char*        resolvedFileName;
150    UCHARBUF*    ucharBuf;
151    const char*  encoding;
152    UBool        uselen;
153    const char*  fileName;
154    const char*  sourceDir;
155    int32_t      _remainingArgc;
156    ULine*       lines;
157    int32_t      numLines;
158    UBool        line_mode;
159    UChar* buffer;
160    int32_t      bufferLen;
161    UBool        verbose;
162    UBool        bulk_mode;
163    int32_t      passes;
164    int32_t      iterations;
165    int32_t      time;
166    const char*  locale;
167private:
168    UPerfTest*   caller;
169    char*        path;           // specifies subtests
170
171// static members
172public:
173    static UPerfTest* gTest;
174    static const char gUsageString[];
175};
176
177#endif
178#endif
179
180