1 /*
2 **********************************************************************
3 * Copyright (c) 2002-2014, 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.
19 struct UOption;
20 typedef struct UOption UOption;
21 
22 #if !UCONFIG_NO_CONVERSION
23 
24 U_NAMESPACE_USE
25 // Use the TESTCASE macro in subclasses of UPerfTest. 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 //|             break;
37 //|     }
38 //|     return NULL;
39 //| }
40 #define TESTCASE(id,test)                       \
41     case id:                                    \
42         name = #test;                           \
43         if (exec) {                             \
44             return test();                      \
45         }                                       \
46         break
47 
48 // More convenient macros. These allow easy reordering of the test cases.
49 // Copied from intltest.h, and adjusted to not logln() but return a UPerfFunction.
50 //
51 //| void MyTest::runIndexedTest(int32_t index, UBool exec,
52 //|                             const char* &name, char* /*par*/) {
53 //|     TESTCASE_AUTO_BEGIN;
54 //|     TESTCASE_AUTO(TestSomething);
55 //|     TESTCASE_AUTO(TestSomethingElse);
56 //|     TESTCASE_AUTO(TestAnotherThing);
57 //|     TESTCASE_AUTO_END;
58 //|     return NULL;
59 //| }
60 #define TESTCASE_AUTO_BEGIN \
61     for(;;) { \
62         int32_t testCaseAutoNumber = 0
63 
64 #define TESTCASE_AUTO(test) \
65         if (index == testCaseAutoNumber++) { \
66             name = #test; \
67             if (exec) { \
68                 return test(); \
69             } \
70             break; \
71         }
72 
73 #define TESTCASE_AUTO_END \
74         name = ""; \
75         break; \
76     }
77 
78 /**
79  * Subclasses of PerfTest will need to create subclasses of
80  * Function that define a call() method which contains the code to
81  * be timed.  They then call setTestFunction() in their "Test..."
82  * method to establish this as the current test functor.
83  */
84 class T_CTEST_EXPORT_API UPerfFunction {
85 public:
86     /**
87      * destructor
88      */
89     virtual ~UPerfFunction();
90 
91     /**
92      * Subclasses must implement this method to do the action to be
93      * measured.
94      */
95     virtual void call(UErrorCode* status)=0;
96 
97     /**
98      * Subclasses must implement this method to return positive
99      * integer indicating the number of operations in a single
100      * call to this object's call() method.
101      */
102     virtual long getOperationsPerIteration()=0;
103     /**
104      * Subclasses should override this method to return either positive
105      * or negative integer indicating the number of events in a single
106      * call to this object's call() method, if applicable
107      * e.g: Number of breaks / iterations for break iterator
108      */
getEventsPerIteration()109     virtual long getEventsPerIteration(){
110         return -1;
111     }
112     /**
113      * Call call() n times in a tight loop and return the elapsed
114      * milliseconds.  If n is small and call() is fast the return
115      * result may be zero.  Small return values have limited
116      * meaningfulness, depending on the underlying CPU and OS.
117      */
time(int32_t n,UErrorCode * status)118      virtual double time(int32_t n, UErrorCode* status) {
119         UTimer start, stop;
120         utimer_getTime(&start);
121         while (n-- > 0) {
122             call(status);
123         }
124         utimer_getTime(&stop);
125         return utimer_getDeltaSeconds(&start,&stop); // ms
126     }
127 
128 };
129 
130 
131 class T_CTEST_EXPORT_API UPerfTest {
132 public:
133     UBool run();
134     UBool runTest( char* name = NULL, char* par = NULL ); // not to be overidden
135 
136     virtual void usage( void ) ;
137 
138     virtual ~UPerfTest();
139 
140     void setCaller( UPerfTest* callingTest ); // for internal use only
141 
142     void setPath( char* path ); // for internal use only
143 
144     ULine* getLines(UErrorCode& status);
145 
146     const UChar* getBuffer(int32_t& len,UErrorCode& status);
147 
148 protected:
149     UPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
150 
151     UPerfTest(int32_t argc, const char* argv[],
152               UOption addOptions[], int32_t addOptionsCount,
153               const char *addUsage,
154               UErrorCode& status);
155 
156     void init(UOption addOptions[], int32_t addOptionsCount,
157               UErrorCode& status);
158 
159     virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
160 
161     virtual UBool runTestLoop( char* testname, char* par );
162 
163     virtual UBool callTest( UPerfTest& testToBeCalled, char* par );
164 
165     int32_t      _argc;
166     const char** _argv;
167     const char * _addUsage;
168     char*        resolvedFileName;
169     UCHARBUF*    ucharBuf;
170     const char*  encoding;
171     UBool        uselen;
172     const char*  fileName;
173     const char*  sourceDir;
174     int32_t      _remainingArgc;
175     ULine*       lines;
176     int32_t      numLines;
177     UBool        line_mode;
178     UChar* buffer;
179     int32_t      bufferLen;
180     UBool        verbose;
181     UBool        bulk_mode;
182     int32_t      passes;
183     int32_t      iterations;
184     int32_t      time;
185     const char*  locale;
186 private:
187     UPerfTest*   caller;
188     char*        path;           // specifies subtests
189 
190 // static members
191 public:
192     static UPerfTest* gTest;
193     static const char gUsageString[];
194 };
195 
196 #endif
197 #endif
198 
199