00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef TEST_DICTIONARY_H_
00024 #define TEST_DICTIONARY_H_
00025
00026 #include <cppunit/extensions/HelperMacros.h>
00027 #include <cppunit/TestAssert.h>
00028 #include "baseTest.h"
00029
00030 namespace test {
00031
00032 using namespace amino;
00033
00034 template<typename DictType, typename ParaType, char const* CLASS_NAME> class DictionaryTest: public CppUnit::TestFixture,
00035 public BaseTest<ParaType> {
00036 CPPUNIT_TEST_SUITE(DictionaryTest)
00037 ;
00038 CPPUNIT_TEST(testInsertST);
00039 CPPUNIT_TEST(testDeleteKeyST);
00040 CPPUNIT_TEST(testFindValueST);
00041 CPPUNIT_TEST(testDeleteValueST);
00042 CPPUNIT_TEST(testInsertMT);
00043 CPPUNIT_TEST(testFindValueMT);
00044 CPPUNIT_TEST(testFindKeyMT);
00045 CPPUNIT_TEST(testDeleteKeyMT);
00046 CPPUNIT_TEST(testDeleteValueMT);
00047
00048 CPPUNIT_TEST_SUITE_END ()
00049 ;
00050 private:
00051 DictType *dict;
00052
00053 public:
00054 DictionaryTest() {
00055 }
00056
00057 DictType * getDict() {
00058 return dict;
00059 }
00060
00061 void setUp() {
00062 dict = new DictType();
00063 }
00064
00065 void reset() {
00066 delete dict;
00067 dict = new DictType();
00068 }
00069
00070 void tearDown() {
00071 delete dict;
00072 }
00073
00074
00075 void testInsertST();
00076 void testDeleteKeyST();
00077 void testFindValueST();
00078 void testDeleteValueST();
00079 void testInsertMT();
00080 void testFindValueMT();
00081 void testFindKeyMT();
00082 void testDeleteKeyMT();
00083 void testDeleteValueMT();
00084 void testInsertRemoveMT();
00085 };
00086
00087 #define ThreadInsert_T ThreadInsert<DictType, ParaType, CLASS_NAME>
00088 #define ThreadDeleteKey_T ThreadDeleteKey<DictType, ParaType, CLASS_NAME>
00089 #define ThreadDeleteValue_T ThreadDeleteValue<DictType, ParaType, CLASS_NAME>
00090
00091 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadInsert :
00092 public TestThread<ParaType> {
00093 private:
00094 DictType *dict;
00095 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00096 int elementNum;
00097 int operationNum;
00098
00099 public:
00100
00101 ThreadInsert(DictType *l, DictionaryTest<DictType, ParaType, CLASS_NAME>* lt,
00102 int nElement,int nOperation, int threadId = 0) :
00103 TestThread<ParaType>(threadId), dict(l), testcase(lt), elementNum(nElement),operationNum(nOperation)
00104 {
00105 }
00106
00107 void* run() {
00108 cout << "#operation of insert: " << operationNum << endl;
00109 for (int i = 0; i< this->operationNum; ++i) {
00110 ParaType tmp = testcase->data[i + ((this->threadId) * elementNum)];
00111
00112 if (dict->insert(tmp, tmp)) {
00113 this->inVec.push_back(tmp);
00114 } else {
00115 cout << "....................insert error." << endl;
00116 }
00117 }
00118 return NULL;
00119 }
00120 };
00121
00122 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadDeleteKey :
00123 public TestThread<ParaType> {
00124 private:
00125 DictType *dict;
00126 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00127 int elementNum;
00128 int operationNum;
00129
00130 public:
00131 ThreadDeleteKey(DictType *l, DictionaryTest<DictType, ParaType, CLASS_NAME>* lt,
00132 int nElement, int nOperation, int nThread = 0) :
00133 TestThread<ParaType>(nThread),dict(l), testcase(lt), elementNum(nElement), operationNum(nOperation) {
00134 }
00135
00136 void *run() {
00137 cout << "#operation of delete: " << operationNum << endl;
00138 for (int i = 0; i < operationNum; ++i) {
00139 ParaType tmp = testcase->data[i + ((this->threadId) * elementNum)];
00140 ParaType tmpValue;
00141
00142 if (dict->deleteKey(tmp, tmpValue)) {
00143
00144
00145 this->outVec.push_back(tmpValue);
00146 }
00147 }
00148
00149 return NULL;
00150 }
00151 };
00152
00153 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadDeleteValue :
00154 public TestThread<ParaType> {
00155 private:
00156 DictType *dict;
00157 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00158 int elementNum;
00159 int operationNum;
00160
00161 public:
00162 ThreadDeleteValue(DictType *l, DictionaryTest<DictType, ParaType, CLASS_NAME>* lt,
00163 int nElement, int nOperation, int nThread = 0) :
00164 TestThread<ParaType>(nThread), dict(l), testcase(lt), elementNum(nElement), operationNum(nOperation){
00165 }
00166
00167 void *run() {
00168 for (int i = 0; i < operationNum; ++i) {
00169 ParaType tmp = testcase->data[i + ((this->threadId) * elementNum)];
00170 ParaType tmpKey;
00171
00172
00173 if (dict->deleteValue(tmp, tmpKey)) {
00174 this->outVec.push_back(tmpKey);
00175 }
00176 }
00177
00178 return NULL;
00179 }
00180 };
00181
00182 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadFindValue :
00183 public TestThread<ParaType> {
00184 private:
00185 DictType *dict;
00186 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00187 int elementNum;
00188 int operationNum;
00189
00190 public:
00191 ThreadFindValue(DictType *l, DictionaryTest<DictType, ParaType, CLASS_NAME>* lt,
00192 int nElement, int nOperation, int nThread = 0) :
00193 TestThread<ParaType>(nThread), dict(l), testcase(lt), elementNum(nElement), operationNum(nOperation) {
00194 }
00195
00196 void *run() {
00197 for (int i = 0; i < operationNum; ++i) {
00198 ParaType tmp = testcase->data[i + ((this->threadId) * elementNum)];
00199 ParaType tmpKey;
00200
00201
00202 if (dict->findValue(tmp, tmpKey)) {
00203 this->outVec.push_back(tmpKey);
00204 }
00205 }
00206
00207 return NULL;
00208 }
00209 };
00210
00211 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadFindKey :
00212 public TestThread<ParaType> {
00213 private:
00214 DictType *dict;
00215 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00216 int elementNum;
00217 int operationNum;
00218
00219 public:
00220 ThreadFindKey(DictType *l, DictionaryTest<DictType, ParaType, CLASS_NAME>* lt,
00221 int nElement, int nOperation, int nThread = 0) :
00222 TestThread<ParaType>(nThread), dict(l), testcase(lt), elementNum(nElement), operationNum(nOperation) {
00223 }
00224
00225 void *run() {
00226 for (int i = 0; i < operationNum; ++i) {
00227 ParaType tmp = testcase->data[i + ((this->threadId) * elementNum)];
00228 ParaType tmpKey;
00229
00230
00231 if (dict->findKey(tmp, tmpKey)) {
00232 this->outVec.push_back(tmpKey);
00233 }
00234 }
00235
00236 return NULL;
00237 }
00238 };
00239
00240 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadInsertFactory :
00241 public ThreadFactory<ParaType> {
00242 private:
00243 DictType *dict;
00244 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00245 public:
00246 ThreadInsertFactory(DictType * l,
00247 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00248 dict(l), testcase(lt) {
00249 }
00250
00251 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00252 testcase->reset();
00253 dict = testcase->getDict();
00254 this->inVec.clear();
00255 this->outVec.clear();
00256
00257 Runnable ** threads;
00258 threads = new Runnable*[threadNum];
00259 for (int i = 0; i < threadNum; ++i) {
00260 threads[i] = new ThreadInsert<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum, operationNum, i);
00261 }
00262
00263 return threads;
00264 }
00265
00266 virtual void verifyResult(int threadNum, int elementNum) {
00267
00268 ParaType tmp;
00269 for(int id = 0; id < threadNum; ++id) {
00270 for (int i = 0; i< testcase->BaseTest<ParaType>::NOPERATION; ++i) {
00271
00272 if (dict->findKey(testcase->data[i + (id * elementNum)], tmp)) {
00273 this->outVec.push_back(tmp);
00274 }
00275 }
00276 }
00277
00278 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00279 }
00280 };
00281
00282 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadDeleteKeyFactory :
00283 public ThreadFactory<ParaType> {
00284 private:
00285 DictType *dict;
00286 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00287 public:
00288 ThreadDeleteKeyFactory(DictType * l,
00289 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00290 dict(l), testcase(lt) {
00291 }
00292
00293 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00294 testcase->reset();
00295 dict = testcase->getDict();
00296 this->inVec.clear();
00297 this->outVec.clear();
00298
00299 for (int i = 0; i < threadNum; ++i) {
00300 ThreadInsert_T threadInsert(dict, testcase, elementNum, operationNum, i);
00301 threadInsert.run();
00302
00303 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00304 back_inserter(this->inVec));
00305 }
00306
00307
00308
00309 Runnable ** threads;
00310 threads = new Runnable*[threadNum];
00311 for (int i = 0; i < threadNum; ++i) {
00312 threads[i] = new ThreadDeleteKey<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i);
00313 }
00314 return threads;
00315 }
00316
00317 virtual void verifyResult(int threadNum, int elementNum) {
00318
00319 sort(this->inVec.begin(), this->inVec.end());
00320 this->inVec.erase(unique(this->inVec.begin(),this->inVec.end()),this->inVec.end());
00321
00322 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00323 }
00324 };
00325
00326 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadDeleteValueFactory :
00327 public ThreadFactory<ParaType> {
00328 private:
00329 DictType *dict;
00330 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00331 public:
00332 ThreadDeleteValueFactory(DictType * l,
00333 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00334 dict(l), testcase(lt) {
00335 }
00336
00337 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00338 testcase->reset();
00339 dict = testcase->getDict();
00340 this->inVec.clear();
00341 this->outVec.clear();
00342
00343 for (int i = 0; i < threadNum; ++i) {
00344 ThreadInsert_T threadInsert(dict, testcase, elementNum, operationNum, i);
00345 threadInsert.run();
00346
00347 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00348 back_inserter(this->inVec));
00349 }
00350
00351
00352
00353 Runnable ** threads;
00354 threads = new Runnable*[threadNum];
00355 for (int i = 0; i < threadNum; ++i) {
00356 threads[i] = new ThreadDeleteValue<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i);
00357 }
00358 return threads;
00359 }
00360
00361 virtual void verifyResult(int threadNum, int elementNum) {
00362
00363 sort(this->inVec.begin(), this->inVec.end());
00364 this->inVec.erase(unique(this->inVec.begin(),this->inVec.end()),this->inVec.end());
00365
00366 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00367 }
00368 };
00369
00370 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadFindValueFactory :
00371 public ThreadFactory<ParaType> {
00372 private:
00373 DictType *dict;
00374 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00375 public:
00376 ThreadFindValueFactory(DictType * l,
00377 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00378 dict(l), testcase(lt) {
00379 }
00380
00381 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00382 testcase->reset();
00383 dict = testcase->getDict();
00384 this->inVec.clear();
00385 this->outVec.clear();
00386
00387 for (int i = 0; i < threadNum; ++i) {
00388 ThreadInsert_T threadInsert(dict, testcase, elementNum, operationNum, i);
00389 threadInsert.run();
00390
00391 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00392 back_inserter(this->inVec));
00393 }
00394
00395
00396
00397 Runnable ** threads;
00398 threads = new Runnable*[threadNum];
00399 for (int i = 0; i < threadNum; ++i) {
00400 threads[i] = new ThreadFindValue<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i);
00401 }
00402 return threads;
00403 }
00404
00405 virtual void verifyResult(int threadNum, int elementNum) {
00406
00407
00408
00409
00410 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00411 }
00412 };
00413
00414 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadFindKeyFactory :
00415 public ThreadFactory<ParaType> {
00416 private:
00417 DictType *dict;
00418 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00419 public:
00420 ThreadFindKeyFactory(DictType * l,
00421 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00422 dict(l), testcase(lt) {
00423 }
00424
00425 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00426 testcase->reset();
00427 dict = testcase->getDict();
00428 this->inVec.clear();
00429 this->outVec.clear();
00430
00431 for (int i = 0; i < threadNum; ++i) {
00432 ThreadInsert_T threadInsert(dict, testcase, elementNum, operationNum, i);
00433 threadInsert.run();
00434
00435 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00436 back_inserter(this->inVec));
00437 }
00438
00439
00440
00441 Runnable ** threads;
00442 threads = new Runnable*[threadNum];
00443 for (int i = 0; i < threadNum; ++i) {
00444 threads[i] = new ThreadFindKey<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i);
00445 }
00446 return threads;
00447 }
00448
00449 virtual void verifyResult(int threadNum, int elementNum) {
00450
00451
00452
00453
00454 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00455 }
00456 };
00457
00458 template<typename DictType, typename ParaType, char const* CLASS_NAME> class ThreadInsertRemoveFactory :
00459 public ThreadFactory<ParaType> {
00460 private:
00461 DictType *dict;
00462 DictionaryTest<DictType, ParaType, CLASS_NAME> *testcase;
00463 public:
00464 ThreadInsertRemoveFactory(DictType * l,
00465 DictionaryTest<DictType, ParaType, CLASS_NAME> * lt) :
00466 dict(l), testcase(lt) {
00467 }
00468
00469 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00470 testcase->reset();
00471 dict = testcase->getDict();
00472 this->inVec.clear();
00473 this->outVec.clear();
00474
00475 Runnable ** threads;
00476 threads = new Runnable*[threadNum];
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 for (int i = 0; i < threadNum; i += 2) {
00502 cout << "create insert thread" << endl;
00503 threads[i] = new ThreadInsert<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i);
00504 if (i+1 < threadNum) {
00505 cout << "create insert thread" << endl;
00506 threads[i+1] = new ThreadDeleteKey<DictType, ParaType, CLASS_NAME>(dict, testcase, elementNum,operationNum, i+1);
00507 }
00508 }
00509 return threads;
00510 }
00511
00512 virtual void verifyResult(int threadNum, int elementNum) {
00513
00514
00515
00516
00517
00518
00519
00520 }
00521 };
00522
00523
00524
00525
00526
00527
00528 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00529 DictType, ParaType, CLASS_NAME>::testInsertST() {
00530 ThreadInsert_T threadInsert(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00531 threadInsert.run();
00532
00533
00534 vector<ParaType> outVec;
00535 ParaType tmp;
00536 for (int i = 0; i< BaseTest<ParaType>::NOPERATION; ++i) {
00537 if (dict->findKey(this->data[i], tmp)) {
00538
00539 outVec.push_back(tmp);
00540 }
00541 }
00542
00543 sort(threadInsert.inVec.begin(), threadInsert.inVec.end());
00544
00545
00546 sort(outVec.begin(), outVec.end());
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 CPPUNIT_ASSERT(threadInsert.inVec == outVec);
00563 }
00564
00565 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00566 DictType, ParaType, CLASS_NAME>::testDeleteKeyST() {
00567 ThreadInsert_T threadInsert(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00568 ThreadDeleteKey_T threadDeleteKey(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00569
00570 threadInsert.run();
00571 threadDeleteKey.run();
00572
00573
00574
00575
00576
00577
00578
00579
00580 sort(threadInsert.inVec.begin(), threadInsert.inVec.end());
00581 threadInsert.inVec.erase(unique(threadInsert.inVec.begin(),threadInsert.inVec.end()),threadInsert.inVec.end());
00582
00583 sort(threadDeleteKey.outVec.begin(), threadDeleteKey.outVec.end());
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 CPPUNIT_ASSERT(threadInsert.inVec == threadDeleteKey.outVec);
00600 }
00601
00602 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00603 DictType, ParaType, CLASS_NAME>::testFindValueST() {
00604 ThreadInsert_T threadInsert(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00605 threadInsert.run();
00606
00607 vector<ParaType> outVec;
00608 ParaType tmp;
00609 for (int i = 0; i< BaseTest<ParaType>::NOPERATION; ++i) {
00610 if (dict->findValue(this->data[i], tmp)) {
00611
00612 outVec.push_back(tmp);
00613 }
00614 }
00615
00616 sort(threadInsert.inVec.begin(), threadInsert.inVec.end());
00617
00618
00619 sort(outVec.begin(), outVec.end());
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 CPPUNIT_ASSERT(threadInsert.inVec == outVec);
00636 }
00637
00638 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00639 DictType, ParaType, CLASS_NAME>::testDeleteValueST() {
00640 ThreadInsert_T threadInsert(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00641 ThreadDeleteValue_T threadDeleteValue(dict, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00642
00643 threadInsert.run();
00644 threadDeleteValue.run();
00645
00646
00647
00648
00649
00650
00651
00652
00653 sort(threadInsert.inVec.begin(), threadInsert.inVec.end());
00654 threadInsert.inVec.erase(unique(threadInsert.inVec.begin(),threadInsert.inVec.end()),threadInsert.inVec.end());
00655
00656 sort(threadDeleteValue.outVec.begin(), threadDeleteValue.outVec.end());
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 CPPUNIT_ASSERT(threadInsert.inVec == threadDeleteValue.outVec);
00673 }
00674
00675 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00676 DictType, ParaType, CLASS_NAME>::testInsertMT() {
00677 ThreadInsertFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00678 ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertMT");
00679 }
00680
00681 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00682 DictType, ParaType, CLASS_NAME>::testDeleteKeyMT() {
00683 ThreadDeleteKeyFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00684 ThreadRunner::runThreads(&factory, CLASS_NAME, "testDeleteKeyMT");
00685 }
00686
00687 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00688 DictType, ParaType, CLASS_NAME>::testDeleteValueMT() {
00689 ThreadDeleteValueFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00690 ThreadRunner::runThreads(&factory, CLASS_NAME, "testDeleteValueMT");
00691 }
00692
00693 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00694 DictType, ParaType, CLASS_NAME>::testFindValueMT() {
00695 ThreadFindValueFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00696 ThreadRunner::runThreads(&factory, CLASS_NAME, "testFindValueMT");
00697 }
00698
00699 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00700 DictType, ParaType, CLASS_NAME>::testFindKeyMT() {
00701 ThreadFindKeyFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00702 ThreadRunner::runThreads(&factory, CLASS_NAME, "testFindKeyMT");
00703 }
00704
00705 template<typename DictType, typename ParaType, char const* CLASS_NAME> void DictionaryTest<
00706 DictType, ParaType, CLASS_NAME>::testInsertRemoveMT() {
00707 ThreadInsertRemoveFactory<DictType, ParaType, CLASS_NAME> factory(dict, this);
00708 ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertRemoveMT");
00709 }
00710 }
00711
00712 #endif