1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 // $Id: tdriver-datalist.cpp 9210 2013-01-21 14:10:42Z rdempsey $
19 #include <iostream>
20 #include <sstream>
21 #include <list>
22 
23 #include <pthread.h>
24 #include <time.h>
25 #include <sys/time.h>
26 
27 #include <cppunit/extensions/HelperMacros.h>
28 #include <cppunit/extensions/TestFactoryRegistry.h>
29 #include <cppunit/ui/text/TestRunner.h>
30 
31 #include "fifo.h"
32 #include "wsdl.h"
33 #include "constantdatalist.h"
34 #include "bucketdl.h"
35 #include "bandeddl.h"
36 #include "elementtype.h"
37 #include "stopwatch.cpp"
38 
39 // #undef CPPUNIT_ASSERT
40 // #define CPPUNIT_ASSERT(x)
41 
42 using namespace std;
43 using namespace joblist;
44 Stopwatch timer;
45 
46 struct DLElement
47 {
48 public:
49     int i;
operator <DLElement50     bool operator<(const DLElement& c) const
51     {
52         return (i < c.i);
53     }
getHashStringDLElement54     const char* getHashString(int mode, int* len) const
55     {
56         *len = 4;
57         return (char*) &i;
58     }
59 };
60 
operator >>(istream & is,DLElement & dl)61 istream& operator>>(istream& is, DLElement& dl)
62 {
63     is.read((char*)&dl.i, sizeof(int));
64     return is;
65 }
operator <<(ostream & os,const DLElement & dl)66 ostream& operator<<(ostream& os, const DLElement& dl)
67 {
68     os.write((char*)&dl.i, sizeof(int));
69     return os;
70 }
71 
72 int64_t count = 150000000/*1000000*/;
73 int maxElements = 32000000/*50000*/;   //max elements in memory at once for the benchmarks
74 int buckets = 16;  // # of buckets to use in bucketDL tests.
75 #define MAXINT64 (uint64_t) 0xffffffffffffffffLL
76 
77 /* Note, this is like what we'll use for banding operations */
78 class BandGrouper
79 {
80 public:
operator ()(const char * data,uint32_t len) const81     uint32_t operator()(const char* data, uint32_t len) const
82     {
83         stringstream ss(string(data, len));
84         ElementType dle;
85 
86         ss >> dle;
87 //  			cout << "bandGrouper sees " << dle.i << " returning " << dle.i/(::count/buckets) << endl;
88         return dle.first / (::count / buckets);
89     }
90 };
91 
timespec_sub(const struct timespec & tv1,const struct timespec & tv2,struct timespec & diff)92 void timespec_sub(const struct timespec& tv1, const struct timespec& tv2,
93                   struct timespec& diff)
94 {
95     if (tv2.tv_nsec < tv1.tv_nsec)
96     {
97         diff.tv_sec = tv2.tv_sec - tv1.tv_sec - 1;
98         diff.tv_nsec = tv1.tv_nsec - tv2.tv_nsec;
99     }
100     else
101     {
102         diff.tv_sec = tv2.tv_sec - tv1.tv_sec;
103         diff.tv_nsec = tv2.tv_nsec - tv1.tv_nsec;
104     }
105 }
106 
107 int cCount = 0, pCount = 0;
108 
MP_FIFO_stress_producer(void * arg)109 void* MP_FIFO_stress_producer(void* arg)
110 {
111     FIFO<ElementType>* f = reinterpret_cast<FIFO<ElementType> *>(arg);
112     uint64_t i;
113     ElementType val;
114     uint64_t id = ::pCount++;
115 
116 // 	cout << "producer " << id << " started" << endl;
117     for (i = 0; i < (uint32_t) ::count / 10; i++)
118     {
119         val.first = (id << 60) | i;
120         val.second = val.first;
121         f->insert(val);
122     }
123 
124     return NULL;
125 }
126 
MP_FIFO_stress_consumer(void * arg)127 void* MP_FIFO_stress_consumer(void* arg)
128 {
129     FIFO<ElementType>* f = reinterpret_cast<FIFO<ElementType> *>(arg);
130     int it;
131     ElementType val;
132     bool ret;
133 // 	int id = ::cCount++;
134     uint64_t pCounter[10];			// 10 producers right now; make this a global var...
135     uint64_t pnum, pnext;
136 
137     memset(pCounter, 0, 8 * 10);
138 
139 //  	cout << "consumer " << id << " started" << endl;
140     it = f->getIterator();
141     ret = f->next(it, &val);
142 
143     while (ret)
144     {
145         pnum = val.first >> 60;
146         pnext = pCounter[pnum]++;
147 //  		cerr << id << ":  .first=0x" << hex << val.first << dec << " pnum:" << pnum << " val:" << pnext << endl;
148         CPPUNIT_ASSERT((val.first & 0xfffffffffffffffLL) == pnext);
149         CPPUNIT_ASSERT(val.second == val.first);
150         ret = f->next(it, &val);
151     }
152 
153     return NULL;
154 }
155 
FIFO_stress_consumer(void * arg)156 void* FIFO_stress_consumer(void* arg)
157 {
158     FIFO<ElementType>* f = reinterpret_cast<FIFO<ElementType> *>(arg);
159     uint64_t i;
160     int it;
161     ElementType val;
162     bool ret;
163     int id = ++::cCount;
164 
165     cout << "consumer " << id << " started" << endl;
166     it = f->getIterator();
167 
168     for (i = 0; i < MAXINT64; i++)
169     {
170 //  		cout << id << ": " << i << " ";
171         ret = f->next(it, &val);
172 
173         if (!ret)
174         {
175             cout << "consumer " << id << " exiting" << endl;
176             return NULL;
177         }
178 
179         else
180         {
181 //  			cout << "first: " << val.first << " second: " << val.second << endl;
182             CPPUNIT_ASSERT(ret == true);
183             CPPUNIT_ASSERT(val.first == i && val.second == i);
184         }
185 
186     }
187 
188     return NULL;
189 }
190 
FIFO_bench_consumer(void * arg)191 void* FIFO_bench_consumer(void* arg)
192 {
193     FIFO<int>* f = reinterpret_cast<FIFO<int> *>(arg);
194     int i, it, val;
195     bool ret;
196 
197     it = f->getIterator();
198 
199     for (i = 0; i < ::count; i++)
200     {
201 // 		cout << "t " << i << endl;
202         ret = f->next(it, &val);
203 //    		CPPUNIT_ASSERT(ret == true);
204     }
205 
206     return NULL;
207 }
208 
FIFO_2_helper(void * arg)209 void* FIFO_2_helper(void* arg)
210 {
211     FIFO<DLElement>* f = reinterpret_cast<FIFO<DLElement> *>(arg);
212     int i;
213     DLElement fe;
214 
215     for (i = 0; i < ::count; i++)
216     {
217         fe.i = i;
218 #ifdef DEBUG
219         cout << "inserting " << i << endl;
220 #endif
221         f->insert(fe);
222     }
223 
224     sleep(5);		// causes the test to block on moreData until endOfInput is called
225     f->endOfInput();
226     return NULL;
227 }
228 
WSDL_2_helper(void * arg)229 void* WSDL_2_helper(void* arg)
230 {
231     WSDL<ElementType>* w = reinterpret_cast<WSDL<ElementType> *>(arg);
232     uint32_t i, id;
233     bool nextRet;
234     ElementType dle;
235 
236     id = w->getIterator();
237 
238 //  	cout << "id = " << id << endl;
239     for (i = 0; i < ::count; i++)
240     {
241         nextRet = w->next(id, &dle);
242 //   		cout << "tgot " << dle.i << endl;
243         CPPUNIT_ASSERT(nextRet == true);
244         CPPUNIT_ASSERT(dle.first == i && dle.second == i);
245     }
246 
247     return NULL;
248 }
249 
BandedDL_1_helper(void * arg)250 void* BandedDL_1_helper(void* arg)
251 {
252     BandedDL<ElementType>* w = reinterpret_cast<BandedDL<ElementType> *>(arg);
253     uint32_t i, id;
254     bool nextRet;
255     ElementType dle;
256 
257     id = w->getIterator();
258 
259 //   	cout << "id = " << id << endl;
260     for (i = 0; i < ::count; i++)
261     {
262         nextRet = w->next(id, &dle);
263 //    		cout << "tgot " << dle.i << endl;
264 //		CPPUNIT_ASSERT(nextRet == true);
265 //  		CPPUNIT_ASSERT(dle.first == i && dle.second == i);
266     }
267 
268     return NULL;
269 }
270 
BandedDL_2_helper(void * arg)271 void* BandedDL_2_helper(void* arg)
272 {
273     BandedDL<StringElementType>* w = reinterpret_cast<BandedDL<StringElementType> *>(arg);
274     uint32_t i, id;
275     bool nextRet;
276     StringElementType dle;
277 
278     id = w->getIterator();
279 
280 //   	cout << "id = " << id << endl;
281     for (i = 0; i < ::count; i++)
282     {
283         ostringstream os;
284 
285         os << "blah blah" << i;
286         nextRet = w->next(id, &dle);
287 //    		cout << "tgot " << dle.i << endl;
288         CPPUNIT_ASSERT(nextRet == true);
289         CPPUNIT_ASSERT(dle.first == i && dle.second == os.str());
290     }
291 
292     return NULL;
293 }
294 
WSDL_bench_helper(void * arg)295 void* WSDL_bench_helper(void* arg)
296 {
297     WSDL<ElementType>* w = reinterpret_cast<WSDL<ElementType> *>(arg);
298     int i, id;
299     bool nextRet;
300     ElementType e;
301 
302     id = w->getIterator();
303 
304     for (i = 0; i < ::count; i++)
305         nextRet = w->next(id, &e);
306 
307     return NULL;
308 }
309 
SWSDL_bench_helper(void * arg)310 void* SWSDL_bench_helper(void* arg)
311 {
312     SWSDL<ElementType>* sw = reinterpret_cast<SWSDL<ElementType> *>(arg);
313     int i, id;
314     bool nextRet;
315     ElementType e;
316 
317     id = sw->getIterator();
318 
319     for (i = 0; i < ::count * 8; i++)
320         nextRet = sw->next(id, &e);
321 
322     return NULL;
323 }
324 
BDL_bench_helper(void * arg)325 void* BDL_bench_helper(void* arg)
326 {
327     BandedDL<ElementType>* sw = reinterpret_cast<BandedDL<ElementType> *>(arg);
328     int i, id;
329     bool nextRet;
330     ElementType e;
331 
332     id = sw->getIterator();
333 
334     for (i = 0; i < ::count * 8; i++)
335         nextRet = sw->next(id, &e);
336 
337     return NULL;
338 }
339 
SWSDL_producer(void * arg)340 void* SWSDL_producer(void* arg)
341 {
342     SWSDL<ElementType>* sw = reinterpret_cast<SWSDL<ElementType> *>(arg);
343 
344     for (int i = 0; i < ::count; i++)
345         sw->insert(ElementType(i, i));
346 
347     return NULL;
348 }
349 
BDL_producer(void * arg)350 void* BDL_producer(void* arg)
351 {
352     BandedDL<ElementType>* sw = reinterpret_cast<BandedDL<ElementType> *>(arg);
353     ElementType dle;
354 
355     for (int i = 0; i < ::count; i++)
356     {
357         //dle.first = dle.second = i;
358         sw->insert(ElementType(i, i));
359     }
360 
361     //sw->endOfInput();
362     //cout << "end of input size is " << sw->totalSize() << endl;
363     return NULL;
364 }
365 
ZDL_producer(void * arg)366 void* ZDL_producer(void* arg)
367 {
368     ZDL<ElementType>* zdl = reinterpret_cast<ZDL<ElementType> *>(arg);
369 
370     for (int i = 0; i < ::count; i++)
371     {
372         zdl.insert(ElementType((int) N * rand() / (RAND_MAX + 1.0), i));
373     }
374 
375     return NULL;
376 }
377 
ZDL_consumer(void * arg)378 void* ZDL_consumer(void* arg)
379 {
380     ZDL<ElementType>* zdl = reinterpret_cast<ZDL<ElementType> *>(arg);
381     int i, id;
382     bool nextRet;
383     ElementType e;
384 
385     id = zdl->getIterator();
386     nextRet = zdl->next(id, &e);
387 
388     while (nextRet)
389         nextRet = zdl->next(id, &e);
390 
391     return NULL;
392 }
393 
SWSDL_consumer(void * arg)394 void* SWSDL_consumer(void* arg)
395 {
396     SWSDL<ElementType>* sw = reinterpret_cast<SWSDL<ElementType> *>(arg);
397     int i, id;
398     bool nextRet;
399     ElementType e;
400 
401     id = sw->getIterator();
402     nextRet = sw->next(id, &e);
403 
404     while (nextRet)
405         nextRet = zdl->next(id, &e);
406 
407     return NULL;
408 }
409 
410 class DataListDriver : public CppUnit::TestFixture
411 {
412 
413     CPPUNIT_TEST_SUITE(DataListDriver);
414 
415 //CPPUNIT_TEST(FIFO_1);
416 //CPPUNIT_TEST(FIFO_2);
417 //CPPUNIT_TEST(MP_FIFO_stress);		//10 consumers 10 producers
418 // CPPUNIT_TEST(FIFO_stress);  // 10 consumers 1 producer; doesn't stop
419 // CPPUNIT_TEST(FIFO_bench);
420 // CPPUNIT_TEST(FIFO_singlethread_bench);
421 //CPPUNIT_TEST(WSDL_1);
422 //CPPUNIT_TEST(WSDL_2);
423 //CPPUNIT_TEST(WSDL_3);		// WSDL_1 with StringElementTypes
424 // CPPUNIT_TEST(WSDL_bench);
425 // CPPUNIT_TEST(WSDL_singlethread_bench);
426 //CPPUNIT_TEST(CON_DL_1);   // ConstantDataList
427 //CPPUNIT_TEST(BucketDL_1);
428 
429 //CPPUNIT_TEST(BandedDL_1);		// WSDL_2 ported to BandedDLs
430 //CPPUNIT_TEST(BandedDL_2);		// BandedDL_1 that uses StringElementTypes
431 
432 // make sure the DataList consumer-side interface works.
433 //CPPUNIT_TEST(BandedDL_as_WSDL_1);
434 
435 // random inserts to bucketDL, create bandedDL, make sure it's in order
436 //CPPUNIT_TEST(BandedDL_as_WSDL_2);
437 
438     /* tests prompted by feedback */
439 //CPPUNIT_TEST(polymorphism_1);
440 
441 // make sure we can store basic types (int in this case)
442 //CPPUNIT_TEST(polymorphism_2);
443 
444 // make sure we can create a FIFO, fill it, cast it to a DataList, and read the elements.
445 //CPPUNIT_TEST(polymorphism_3);
446 //CPPUNIT_TEST(SWSDL_bench);
447 //CPPUNIT_TEST(BDL_multiproducer_bench);
448 //CPPUNIT_TEST(BDL_consumer_bench);
449 //CPPUNIT_TEST(SWSDL_multiproducer_bench);
450     CPPUNIT_TEST(SWSDL_consumer_bench);
451 //CPPUNIT_TEST(BDL_singlethread_bench);
452     CPPUNIT_TEST(ZDL_bench);
453     CPPUNIT_TEST_SUITE_END();
454 
455 private:
456 public:
457 
FIFO_1()458     void FIFO_1()
459     {
460         int i, it;
461         DLElement dummy;
462         FIFO<DLElement> f(1, 20);
463         bool nextRet;
464 
465         for (i = 0; i < 10; i++)
466         {
467             dummy.i = i;
468             f.insert(dummy);
469         }
470 
471         f.endOfInput();
472         it = f.getIterator();
473         CPPUNIT_ASSERT(it == 0);
474 
475         for (i = 0; i < 10; i++)
476         {
477             nextRet = f.next(it, &dummy);
478             CPPUNIT_ASSERT(nextRet == true);
479             CPPUNIT_ASSERT(dummy.i == i);
480         }
481     }
482 
FIFO_2()483     void FIFO_2()
484     {
485         int i, it;
486         DLElement fe;
487         FIFO<DLElement> fifo(1, 2000);
488         pthread_t thread;
489         bool ret;
490 
491         fe.i = 0;
492         pthread_create(&thread, NULL, FIFO_2_helper, &fifo);
493         sleep(1);   // make sure the thread sleeps after 2000 inserts
494         it = fifo.getIterator();
495 
496         for (i = 0; i < ::count; i++)
497         {
498             if (i % 100000 == 0)
499                 cout << i << "/" << ::count << endl;
500 
501             ret = fifo.next(it, &fe);
502 // 			cout << "fe = " << fe.i << endl;
503             CPPUNIT_ASSERT(ret == true);
504             CPPUNIT_ASSERT(fe.i == i);
505         }
506 
507         ret = fifo.next(it, &fe);		// should sleep until the thread calls endOfInput()
508         CPPUNIT_ASSERT(ret == false);
509         pthread_join(thread, NULL);
510     }
511 
MP_FIFO_stress()512     void MP_FIFO_stress()
513     {
514         int64_t i;
515         FIFO<ElementType> f(10, 25000);
516         pthread_t consumer[10];
517         pthread_t producer[10];
518 
519         f.setMultipleProducers(true);
520 
521         for (i = 0; i < 10; i++)
522             pthread_create(&consumer[i], NULL, MP_FIFO_stress_consumer, &f);
523 
524         for (i = 0; i < 10; i++)
525             pthread_create(&producer[i], NULL, MP_FIFO_stress_producer, &f);
526 
527         for (i = 0; i < 10; i++)
528             pthread_join(producer[i], NULL);
529 
530         f.endOfInput();
531 
532         /*
533         //  		for (i = 0; i < MAXINT64; i++) {
534          		for (i = 0; i < ::count; i++) {
535          			if ((i % 10000000) == 0)
536         				cout << i << endl;
537         			f.insert(ElementType(i, i));
538         		}
539         		f.endOfInput();
540         */
541         for (i = 0; i < 10; i++)
542             pthread_join(consumer[i], NULL);
543     }
544 
FIFO_stress()545     void FIFO_stress()
546     {
547         int64_t i;
548         FIFO<ElementType> f(10, 25000);
549         pthread_t consumer[10];
550 
551         for (i = 0; i < 10; i++)
552             pthread_create(&consumer[i], NULL, FIFO_stress_consumer, &f);
553 
554 //  		for (i = 0; i < MAXINT64; i++) {
555         for (i = 0; i < ::count; i++)
556         {
557             if ((i % 10000000) == 0)
558                 cout << i << endl;
559 
560             f.insert(ElementType(i, i));
561         }
562 
563         f.endOfInput();
564 
565         for (i = 0; i < 10; i++)
566             pthread_join(consumer[i], NULL);
567     }
568 
FIFO_bench()569     void FIFO_bench()
570     {
571         int i;
572         FIFO<int> f(1, ::maxElements);
573         pthread_t consumer;
574         struct timespec tv1, tv2, diff;
575 
576 
577         pthread_create(&consumer, NULL, FIFO_bench_consumer, &f);
578         clock_gettime(CLOCK_REALTIME, &tv1);
579 
580         for (i = 0; i < ::count; i++)
581         {
582             f.insert(i);
583         }
584 
585         f.endOfInput();
586         pthread_join(consumer, NULL);
587         clock_gettime(CLOCK_REALTIME, &tv2);
588         timespec_sub(tv1, tv2, diff);
589         cout << "producer & consumer passed " << ::count << " elements in " <<
590              diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
591 
592     }
593 
FIFO_singlethread_bench()594     void FIFO_singlethread_bench()
595     {
596         int i, it, e;
597         FIFO<int> f(1, ::count);
598         bool more;
599         struct timespec tv1, tv2, diff;
600 
601         clock_gettime(CLOCK_REALTIME, &tv1);
602 
603         for (i = 0; i < ::count; i++)
604         {
605             f.insert(i);
606         }
607 
608         f.endOfInput();
609         clock_gettime(CLOCK_REALTIME, &tv2);
610         timespec_sub(tv1, tv2, diff);
611 
612         cout << "FIFO_singlethreaded_bench: inserted " << ::count <<
613              " ints in " << diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
614 
615         it = f.getIterator();
616 
617         for (i = 0; i < ::count; i++)
618         {
619             more = f.next(it, &e);
620         }
621 
622         clock_gettime(CLOCK_REALTIME, &tv1);
623         timespec_sub(tv2, tv1, diff);
624         cout << "FIFO_singlethread_bench: consumed, took " << diff.tv_sec << "s " <<
625              diff.tv_nsec << "ns" << endl;
626     }
627 
628 
WSDL_1()629     void WSDL_1()
630     {
631         WSDL<ElementType> w(1, ::count / 100);
632         ElementType dle;
633         uint32_t i, id;
634         bool nextRet;
635 
636         for (i = 0; i < ::count; i++)
637         {
638 // 			cout << "inserting " << i << endl;
639             dle.first = dle.second = i;
640             w.insert(dle);
641         }
642 
643         w.endOfInput();
644         id = w.getIterator();
645 
646         for (i = 0; i < ::count; i++)
647         {
648             nextRet = w.next(id, &dle);
649 //  			cout << i << ":got " << dle.first << " " << dle.second << endl;
650             CPPUNIT_ASSERT(nextRet == true);
651             CPPUNIT_ASSERT(dle.first == i && dle.second == i);
652         }
653     }
654 
WSDL_2()655     void WSDL_2()
656     {
657         WSDL<ElementType> w(2, ::count / 10);
658         ElementType dle;
659         uint32_t i, id, size;
660         bool nextRet;
661         pthread_t consumer1;
662 
663         pthread_create(&consumer1, NULL, WSDL_2_helper, &w);
664 
665         // thread should wait here waiting on endOfInput()
666 
667         for (i = 0; i < ::count; i++)
668         {
669             dle.first = dle.second = i;
670             w.insert(dle);
671         }
672 
673         sleep(1);
674         w.endOfInput();
675 
676         /* let the thread consume the loaded set; make sure that the load
677         doesn't happen until the main thread finishes with the loaded set */
678 
679         sleep(1);
680         size = w.totalSize();
681         id = w.getIterator();
682 
683         for (i = 0; i < ::count; i++)
684         {
685             nextRet = w.next(id, &dle);
686 //   			cout << "got " << dle.i << endl;
687             CPPUNIT_ASSERT(nextRet == true);
688             CPPUNIT_ASSERT(dle.first == i && dle.second == i);
689         }
690 
691         pthread_join(consumer1, NULL);
692     }
693 
WSDL_3()694     void WSDL_3()
695     {
696         WSDL<StringElementType> w(1, ::count / 10);
697         StringElementType dle;
698         uint32_t i, id;
699         bool nextRet;
700 
701         for (i = 0; i < ::count; i++)
702         {
703             ostringstream os;
704 
705             os << "blah blah blah" << i;
706 // 			cout << "inserting " << i << endl;
707             dle.first = i;
708             dle.second = os.str();
709             w.insert(dle);
710         }
711 
712         w.endOfInput();
713         id = w.getIterator();
714 
715         for (i = 0; i < ::count; i++)
716         {
717             ostringstream os;
718 
719             os << "blah blah blah" << i;
720             nextRet = w.next(id, &dle);
721 //   			cout << i << ":got " << dle.first << " " << dle.second << endl;
722             CPPUNIT_ASSERT(nextRet == true);
723             CPPUNIT_ASSERT(dle.first == i && dle.second == os.str());
724         }
725     }
726 
WSDL_bench()727     void WSDL_bench()
728     {
729         WSDL<ElementType> w(1, ::maxElements);
730         int i;
731         pthread_t consumer;
732         struct timespec ts1, ts2, diff;
733 
734         clock_gettime(CLOCK_REALTIME, &ts1);
735         pthread_create(&consumer, NULL, WSDL_bench_helper, &w);
736 
737         for (i = 0; i < ::count; i++)
738             w.insert(ElementType(i, i));
739 
740         w.endOfInput();
741         cout << "end of input size is " << w.totalSize() << endl;
742         pthread_join(consumer, NULL);
743         clock_gettime(CLOCK_REALTIME, &ts2);
744         timespec_sub(ts1, ts2, diff);
745         cout << "WSDL_bench: producer & consumer passed " << ::count << " elements in " <<
746              diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
747     }
748 
WSDL_singlethread_bench()749     void WSDL_singlethread_bench()
750     {
751         WSDL<int> w(1, ::maxElements);
752         int i, id, e;
753         bool nextRet;
754         struct timespec ts1, ts2, diff;
755 
756         clock_gettime(CLOCK_REALTIME, &ts1);
757 
758         for (i = 0; i < ::count; i++)
759             w.insert(i);
760 
761         w.endOfInput();
762         id = w.getIterator();
763 
764         for (i = 0; i < ::count; i++)
765             nextRet = w.next(id, &e);
766 
767         clock_gettime(CLOCK_REALTIME, &ts2);
768         timespec_sub(ts1, ts2, diff);
769         cout << "WSDL_singlethread_bench: producer & consumer passed " <<
770              ::count << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
771              "ns" << endl;
772     }
773 
SWSDL_bench()774     void SWSDL_bench()
775     {
776         /*
777         SWSDL<ElementType> sw(1, ::maxElements);
778         int i;
779         pthread_t consumer;
780         pthread_t producer;
781         struct timespec ts1, ts2, diff;
782 
783         clock_gettime(CLOCK_REALTIME, &ts1);
784         pthread_create(&producer, NULL, SWSDL_producer, &sw);
785         pthread_create(&consumer, NULL, SWSDL_bench_helper, &sw);
786 
787         pthread_join(producer, NULL);
788         pthread_join(consumer, NULL);
789         clock_gettime(CLOCK_REALTIME, &ts2);
790         timespec_sub(ts1, ts2, diff);
791         cout << "SWSDL_bench: producer & consumer passed " << ::count << " elements in " <<
792         	diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
793         */
794         SWSDL<ElementType> sw(1, ::maxElements);
795         int i;
796         pthread_t consumer;
797         struct timespec ts1, ts2, diff;
798 
799         clock_gettime(CLOCK_REALTIME, &ts1);
800         pthread_create(&consumer, NULL, SWSDL_bench_helper, &sw);
801 
802         for (i = 0; i < ::count; i++)
803             sw.insert(ElementType(i, i));
804 
805         sw.endOfInput();
806         cout << "end of input size is " << sw.totalSize() << endl;
807         pthread_join(consumer, NULL);
808         clock_gettime(CLOCK_REALTIME, &ts2);
809         timespec_sub(ts1, ts2, diff);
810         cout << "SWSDL_bench: producer & consumer passed " << ::count << " elements in " <<
811              diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
812     }
813 
SWSDL_multiproducer_bench()814     void SWSDL_multiproducer_bench()
815     {
816         SWSDL<ElementType> sw(1, ::maxElements);
817         sw.setMultipleProducers(true);
818         int i, id;
819         ElementType e;
820         bool nextRet;
821         uint32_t numOfThreads = 8;
822         pthread_t producer[numOfThreads];
823         struct timespec ts1, ts2, diff;
824 
825         clock_gettime(CLOCK_REALTIME, &ts1);
826 
827         for (i = 0; i < numOfThreads; i++)
828             pthread_create(&producer[i], NULL, SWSDL_producer, &sw);
829 
830         for (i = 0; i < numOfThreads; i++)
831             pthread_join(producer[i], NULL);
832 
833         sw.endOfInput();
834         cout << "end of input size is " << sw.totalSize() << endl;
835         clock_gettime(CLOCK_REALTIME, &ts2);
836         timespec_sub(ts1, ts2, diff);
837         cout << "# of Producer: " << numOfThreads << endl;
838         cout << "SWSDL_producer_phase_bench: producer & consumer passed " <<
839              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
840              "ns" << endl;
841         clock_gettime(CLOCK_REALTIME, &ts1);
842         id = sw.getIterator();
843 
844         for (i = 0; i < ::count; i++)
845             nextRet = sw.next(id, &e);
846 
847         clock_gettime(CLOCK_REALTIME, &ts2);
848         timespec_sub(ts1, ts2, diff);
849 
850         cout << "SWSDL_consumer_phase_bench: producer & consumer passed " <<
851              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
852              "ns" << endl;
853     }
854 
SWSDL_consumer_bench()855     void SWSDL_consumer_bench()
856     {
857         SWSDL<ElementType> sw(4);
858         sw.setMultipleProducers(true);
859         ElementType dle;
860         uint32_t i, id;
861         bool nextRet;
862         uint32_t numOfProducers = 8;
863         uint32_t numOfConsumers = 4;
864         pthread_t producer[numOfProducers];
865         pthread_t consumer[numOfConsumers];
866         struct timespec ts1, ts2, diff;
867 
868         clock_gettime(CLOCK_REALTIME, &ts1);
869 
870         for (i = 0; i < numOfProducers; i++)
871             pthread_create(&producer[i], NULL, SWSDL_producer, &sw);
872 
873         for (i = 0; i < numOfConsumers; i++)
874             pthread_create(&consumer[i], NULL, SWSDL_consumer, &sw);
875 
876         for (i = 0; i < numOfThreads; i++)
877             pthread_join(producer[i], NULL);
878 
879         sw.endOfInput();
880 
881         clock_gettime(CLOCK_REALTIME, &ts2);
882         timespec_sub(ts1, ts2, diff);
883 
884         cout << "# of Producer: " << numOfThreads << endl;
885         cout << "SWSDL_consumer_bench: producer & consumer passed " <<
886              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
887              "ns" << endl;
888     }
889 
890 
BDL_multiproducer_bench()891     void BDL_multiproducer_bench()
892     {
893         BandedDL<ElementType> w(2);
894         w.setMultipleProducers(true);
895         ElementType dle;
896         uint32_t i, id;
897         bool nextRet;
898         uint32_t numOfThreads = 8;
899         pthread_t producer[numOfThreads];
900         struct timespec ts1, ts2, diff;
901 
902         clock_gettime(CLOCK_REALTIME, &ts1);
903 
904         for (i = 0; i < numOfThreads; i++)
905             pthread_create(&producer[i], NULL, BDL_producer, &w);
906 
907         for (i = 0; i < numOfThreads; i++)
908             pthread_join(producer[i], NULL);
909 
910         w.endOfInput();
911         cout << "end of input size is " << w.totalSize() << endl;
912         clock_gettime(CLOCK_REALTIME, &ts2);
913         timespec_sub(ts1, ts2, diff);
914         cout << "# of Producer: " << numOfThreads << endl;
915         cout << "BDL_producer_phase_bench: producer & consumer passed " <<
916              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
917              "ns" << endl;
918 
919         clock_gettime(CLOCK_REALTIME, &ts1);
920         id = w.getIterator();
921 
922         for (i = 0; i < ::count; i++)
923         {
924             nextRet = w.next(id, &dle);
925         }
926 
927         clock_gettime(CLOCK_REALTIME, &ts2);
928         timespec_sub(ts1, ts2, diff);
929 
930         cout << "BDL_consumer_phase_bench: producer & consumer passed " <<
931              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
932              "ns" << endl;
933         /*
934         		SWSDL<ElementType> sw(1, ::maxElements);
935         		int i;
936         		pthread_t consumer;
937         		struct timespec ts1, ts2, diff;
938 
939         		clock_gettime(CLOCK_REALTIME, &ts1);
940         		pthread_create(&consumer, NULL, SWSDL_bench_helper, &sw);
941          		for (i = 0; i < ::count; i++)
942         			sw.insert(ElementType(i, i));
943 
944         		sw.endOfInput();
945         		cout << "end of input size is " << sw.totalSize() << endl;
946         		pthread_join(consumer, NULL);
947         		clock_gettime(CLOCK_REALTIME, &ts2);
948         		timespec_sub(ts1, ts2, diff);
949         		cout << "SWSDL_bench: producer & consumer passed " << ::count << " elements in " <<
950         			diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
951         */
952     }
953 
BDL_consumer_bench()954     void BDL_consumer_bench()
955     {
956         BandedDL<ElementType> w(2);
957         w.setMultipleProducers(true);
958         ElementType dle;
959         uint32_t i, id;
960         bool nextRet;
961         uint32_t numOfThreads = 8;
962         pthread_t producer[numOfThreads];
963         pthread_t consumer;
964         struct timespec ts1, ts2, diff;
965 
966         clock_gettime(CLOCK_REALTIME, &ts1);
967 
968         for (i = 0; i < numOfThreads; i++)
969             pthread_create(&producer[i], NULL, BDL_producer, &w);
970 
971         for (i = 0; i < numOfThreads; i++)
972             pthread_join(producer[i], NULL);
973 
974         w.endOfInput();
975         //pthread_create(&consumer, NULL, BDL_bench_helper, &w);
976         //cout << "end of input size is " << w.totalSize() << endl;
977         //clock_gettime(CLOCK_REALTIME, &ts2);
978         //timespec_sub(ts1, ts2, diff);
979         //cout << "# of Producer: " << numOfThreads << endl;
980         //cout << "BDL_producer_phase_bench: producer & consumer passed " <<
981         //	::count * numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
982         //	"ns" << endl;
983 
984         //clock_gettime(CLOCK_REALTIME, &ts1);
985         id = w.getIterator();
986 
987         for (i = 0; i < ::count * 8; i++)
988         {
989             nextRet = w.next(id, &dle);
990         }
991 
992         clock_gettime(CLOCK_REALTIME, &ts2);
993         timespec_sub(ts1, ts2, diff);
994         cout << "end of input size is " << w.totalSize() << endl;
995         cout << "BDL_consumer_phase_bench: producer & consumer passed " <<
996              ::count* numOfThreads << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
997              "ns" << endl;
998         /*
999         		SWSDL<ElementType> sw(1, ::maxElements);
1000         		int i;
1001         		pthread_t consumer;
1002         		struct timespec ts1, ts2, diff;
1003 
1004         		clock_gettime(CLOCK_REALTIME, &ts1);
1005         		pthread_create(&consumer, NULL, SWSDL_bench_helper, &sw);
1006          		for (i = 0; i < ::count; i++)
1007         			sw.insert(ElementType(i, i));
1008 
1009         		sw.endOfInput();
1010         		cout << "end of input size is " << sw.totalSize() << endl;
1011         		pthread_join(consumer, NULL);
1012         		clock_gettime(CLOCK_REALTIME, &ts2);
1013         		timespec_sub(ts1, ts2, diff);
1014         		cout << "SWSDL_bench: producer & consumer passed " << ::count << " elements in " <<
1015         			diff.tv_sec << "s " << diff.tv_nsec << "ns" << endl;
1016         */
1017     }
1018 
BDL_singlethread_bench()1019     void BDL_singlethread_bench()
1020     {
1021         /*SWSDL<ElementType> sw(1, ::maxElements);
1022         int i;
1023         pthread_t consumer;
1024         pthread_t producer;
1025         struct timespec ts1, ts2, diff;
1026 
1027         clock_gettime(CLOCK_REALTIME, &ts1);
1028         pthread_create(&producer, NULL, SWSDL_producer, &sw);
1029         pthread_join(producer, NULL);
1030         pthread_create(&consumer, NULL, SWSDL_bench_helper, &sw);
1031 
1032         pthread_join(consumer, NULL);
1033         clock_gettime(CLOCK_REALTIME, &ts2);
1034         timespec_sub(ts1, ts2, diff);*/
1035         SWSDL<ElementType> sw(1, ::maxElements);
1036         int i, id;
1037         ElementType e;
1038         bool nextRet;
1039         struct timespec ts1, ts2, diff;
1040 
1041         clock_gettime(CLOCK_REALTIME, &ts1);
1042         cout << "start of input size is " << ::count << endl;
1043 
1044         for (i = 0; i < ::count; i++)
1045             sw.insert(ElementType(i, i));
1046 
1047         //cout << "end of input size is " << sw.totalSize() << endl;
1048         //sw.endOfInput();
1049         //id = sw.getIterator();
1050         for (i = 0; i < ::count; i++)
1051             nextRet = sw.next(id, &e);
1052 
1053         clock_gettime(CLOCK_REALTIME, &ts2);
1054         timespec_sub(ts1, ts2, diff);
1055 
1056         //cout << "SWSDL_consumer_phase_bench: producer & consumer passed " <<
1057         //	::count << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
1058         //	"ns" << endl;
1059     }
1060 
CON_DL_1()1061     void CON_DL_1()
1062     {
1063         DLElement d, d2;
1064         int i = 0;
1065         bool nextRet;
1066 
1067         d.i = 1;
1068 
1069         ConstantDataList<DLElement> c(d);
1070 
1071         nextRet = c.next(i, &d2);
1072         CPPUNIT_ASSERT(nextRet == true);
1073         CPPUNIT_ASSERT(d.i == 1 && d2.i == 1);
1074 
1075         d.i = 2;
1076         c.insert(d);
1077         nextRet = c.next(i, &d2);
1078         CPPUNIT_ASSERT(nextRet == true);
1079         CPPUNIT_ASSERT(d.i == 2 && d2.i == 2);
1080     }
1081 
BucketDL_1()1082     void BucketDL_1()
1083     {
1084         BucketDL<ElementType> bdl(16, 1, ::count / 100);
1085         ElementType dle;
1086         uint32_t i, it, eCount = 0, buckets;
1087         bool nextRet;
1088 
1089         for (i = 0; i < ::count; i++)
1090         {
1091 //  			if (i % 1000000 == 0) cout << i << endl;
1092             dle.first = dle.second = i;
1093             bdl.insert(dle);
1094         }
1095 
1096         bdl.endOfInput();
1097 //  		cout << "inserted " << ::count << " elements" << endl;
1098 
1099         buckets = bdl.bucketCount();
1100 
1101         for (i = 0; i < buckets; i++)
1102         {
1103             it = bdl.getIterator(i);
1104 
1105             do
1106             {
1107                 nextRet = bdl.next(i, it, &dle);
1108 
1109                 if (nextRet)
1110                 {
1111                     CPPUNIT_ASSERT(dle.first >= 0 && dle.first <= (uint64_t) ::count);
1112                     CPPUNIT_ASSERT(++eCount <= ::count);
1113                 }
1114             }
1115             while (nextRet == true);
1116         }
1117 
1118         CPPUNIT_ASSERT(eCount == ::count);
1119     }
1120 
BandedDL_1()1121     void BandedDL_1()
1122     {
1123         BandedDL<ElementType> w(2);
1124         ElementType dle;
1125         uint32_t i, id, size;
1126         bool nextRet;
1127         pthread_t consumer1;
1128 
1129         pthread_create(&consumer1, NULL, BandedDL_1_helper, &w);
1130 
1131         // thread should wait here waiting on endOfInput()
1132 
1133         for (i = 0; i < ::count; i++)
1134         {
1135             dle.first = dle.second = i;
1136             w.insert(dle);
1137 
1138             if (((i + 1) % (::count / 10)) == 0)
1139             {
1140                 cout << "inserted " << i + 1 << "/" << ::count << endl;
1141                 w.saveBand();
1142             }
1143         }
1144 
1145         sleep(1);
1146         w.endOfInput();
1147 
1148         /* let the thread consume the loaded set; make sure that the load
1149         doesn't happen until the main thread finishes with the loaded set */
1150 
1151         sleep(5);
1152         size = w.totalSize();
1153         id = w.getIterator();
1154 
1155         for (i = 0; i < ::count; i++)
1156         {
1157             nextRet = w.next(id, &dle);
1158 //    			cout << "got " << dle.i << endl;
1159             CPPUNIT_ASSERT(nextRet == true);
1160             CPPUNIT_ASSERT(dle.first == i);
1161         }
1162 
1163         pthread_join(consumer1, NULL);
1164     }
1165 
BandedDL_2()1166     void BandedDL_2()
1167     {
1168         BandedDL<StringElementType> w(2);
1169         StringElementType dle;
1170         uint32_t i, id, size;
1171         bool nextRet;
1172         pthread_t consumer1;
1173 
1174         pthread_create(&consumer1, NULL, BandedDL_2_helper, &w);
1175 
1176         // thread should wait here waiting on endOfInput()
1177 
1178         for (i = 0; i < ::count; i++)
1179         {
1180             ostringstream os;
1181 
1182             os << "blah blah" << i;
1183 
1184             dle.first = i;
1185             dle.second = os.str();
1186             w.insert(dle);
1187 
1188             if (((i + 1) % (::count / 10)) == 0)
1189             {
1190                 cout << "inserted " << i + 1 << "/" << ::count << endl;
1191                 w.saveBand();
1192             }
1193         }
1194 
1195         sleep(1);
1196         w.endOfInput();
1197 
1198         /* let the thread consume the loaded set; make sure that the load
1199         doesn't happen until the main thread finishes with the loaded set */
1200 
1201         cout << "endofInput finished\n";
1202 
1203         sleep(5);
1204         size = w.totalSize();
1205         id = w.getIterator();
1206 
1207         for (i = 0; i < ::count; i++)
1208         {
1209             ostringstream os;
1210 
1211             os << "blah blah" << i;
1212             nextRet = w.next(id, &dle);
1213 //    			cout << "got " << dle.i << endl;
1214             CPPUNIT_ASSERT(nextRet == true);
1215             CPPUNIT_ASSERT(dle.first == i && dle.second == os.str());
1216         }
1217 
1218         pthread_join(consumer1, NULL);
1219     }
1220 
BandedDL_as_WSDL_1()1221     void BandedDL_as_WSDL_1()
1222     {
1223         BandedDL<ElementType> bdl(1);
1224         ElementType e;
1225         uint32_t i, it;
1226         bool more;
1227 
1228         for (i = 1; i <= ::count; i++)
1229         {
1230             e.first = e.second = i;
1231             bdl.insert(e);
1232 
1233             if (i % (::count / 10) == 0)
1234                 bdl.saveBand();
1235         }
1236 
1237         bdl.endOfInput();
1238 
1239         it = bdl.getIterator();
1240 
1241         for (i = 1; i <= ::count; i++)
1242         {
1243             more = bdl.next(it, &e);
1244             CPPUNIT_ASSERT(more == true);
1245             CPPUNIT_ASSERT(e.first == i && e.second == i);
1246         }
1247 
1248         more = bdl.next(it, &e);
1249         CPPUNIT_ASSERT(more == false);
1250 
1251         bdl.restart();
1252 
1253         /* make sure it can be read again */
1254         for (i = 1; i <= ::count; i++)
1255         {
1256             more = bdl.next(it, &e);
1257 
1258             if (!more)
1259                 cerr << i << endl;
1260 
1261             CPPUNIT_ASSERT(more == true);
1262             CPPUNIT_ASSERT(e.first == i && e.second == i);
1263         }
1264 
1265         more = bdl.next(it, &e);
1266         CPPUNIT_ASSERT(more == false);
1267     }
1268 
BandedDL_as_WSDL_2()1269     void BandedDL_as_WSDL_2()
1270     {
1271         BucketDL<ElementType> bucketDL(::buckets, 1, 1000, BandGrouper());
1272         uint32_t last, i, it;
1273         ElementType dle;
1274         bool more;
1275 
1276         srand(time(NULL));
1277 
1278         for (i = 0; i < ::count; i++)
1279         {
1280             dle.first = dle.second = rand() % ::count;   // artificial max
1281             bucketDL.insert(dle);
1282         }
1283 
1284         bucketDL.endOfInput();
1285 
1286 // 		cout << "made bucketdl" << endl;
1287 
1288         BandedDL<ElementType> bdl(bucketDL, 1);
1289 
1290 //  		cout << "made bandeddl" << endl;
1291 
1292         it = bdl.getIterator();
1293         last = 0;
1294         // duplicates were removed, there won't be ::count elements in bdl
1295         more = bdl.next(it, &dle);
1296 
1297         while (more)
1298         {
1299             CPPUNIT_ASSERT(dle.first < (uint64_t) ::count);
1300 //  			cout << dle.first << " >= " << last << endl;
1301             CPPUNIT_ASSERT(dle.first >= last);
1302             last = dle.first;
1303             more = bdl.next(it, &dle);
1304         }
1305 
1306 // 		cerr << "read through bandeddl" << endl;
1307 
1308         more = bdl.next(it, &dle);
1309         CPPUNIT_ASSERT(more == false);
1310 
1311     }
1312 
ZDL_bench()1313     void ZDL_bench()
1314     {
1315         ZDL<ElementType> zdl(4);
1316         zdl.setMultipleProducers(true);
1317         ElementType dle;
1318         uint32_t i, id;
1319         bool nextRet;
1320         uint32_t numOfProducers = 8;
1321         uint32_t numOfConsumers = 4;
1322         pthread_t producer[numOfProducers];
1323         pthread_t consumer[numOfConsumers];
1324         struct timespec ts1, ts2, diff;
1325 
1326         clock_gettime(CLOCK_REALTIME, &ts1);
1327 
1328         for (i = 0; i < numOfProducers; i++)
1329             pthread_create(&producer[i], NULL, ZDL_producer, &zdl);
1330 
1331         for (i = 0; i < numOfConsumers; i++)
1332             pthread_create(&consumer[i], NULL, ZDL_consumer, &zdl);
1333 
1334         for (i = 0; i < numOfThreads; i++)
1335             pthread_join(producer[i], NULL);
1336 
1337         zdl.endOfInput();
1338 
1339         //clock_gettime(CLOCK_REALTIME, &ts1);
1340         id = w.getIterator();
1341 
1342         for (i = 0; i < ::count * 8; i++)
1343         {
1344             nextRet = w.next(id, &dle);
1345         }
1346 
1347         clock_gettime(CLOCK_REALTIME, &ts2);
1348         timespec_sub(ts1, ts2, diff);
1349         cout << "end of input size is " << w.totalSize() << endl;
1350         cout << "ZDL_consumer_producer_bench: producer & consumer passed " <<
1351              ::count* numOfProducers << " elements in " << diff.tv_sec << "s " << diff.tv_nsec <<
1352              "ns" << endl;
1353 
1354     }
1355 
1356     /* Sanity test */
polymorphism_1()1357     void polymorphism_1()
1358     {
1359         DataList<DLElement>* dl;
1360         FIFO<DLElement>* f;
1361         DLElement dle;
1362         int it, i;
1363         bool more;
1364 
1365         f = new FIFO<DLElement>(1, 20);
1366         dl = (DataList<DLElement>*) f;
1367 
1368         it = dl->getIterator();
1369 
1370         for (i = 0; i < 10; i++)
1371         {
1372             dle.i = i;
1373             dl->insert(dle);
1374         }
1375 
1376         dl->endOfInput();
1377 
1378         for (i = 0; i < 10; i++)
1379         {
1380             more = dl->next(it, &dle);
1381 // 			cout << dle.i << endl;
1382             CPPUNIT_ASSERT(more == true);
1383             CPPUNIT_ASSERT(dle.i == i);
1384         }
1385 
1386         delete f;
1387     }
1388 
1389     /* Sanity test 2. Can we stuff basic datatypes into DataLists?  Apparently not.  WHY?*/
polymorphism_2()1390     void polymorphism_2()
1391     {
1392         DataList<int>* dl;
1393         FIFO<int>* f = new FIFO<int>(1, 20);
1394         int it, i, dle;
1395         bool more;
1396 
1397         dl = (DataList<int>*) f;
1398 
1399         it = dl->getIterator();
1400 
1401         for (i = 0; i < 10; i++)
1402             dl->insert(i);
1403 
1404         dl->endOfInput();
1405 
1406         for (i = 0; i < 10; i++)
1407         {
1408             more = dl->next(it, &dle);
1409             CPPUNIT_ASSERT(more == true);
1410             CPPUNIT_ASSERT(dle == i);
1411 // 			cout << "dle[" << i << "]: " << dle << endl;
1412         }
1413 
1414         delete f;
1415     }
1416 
polymorphism_3()1417     void polymorphism_3()
1418     {
1419         DataList<DLElement>* dl;
1420         FIFO<DLElement>* f;
1421         int it, i;
1422         DLElement dle;
1423         bool more;
1424 
1425         f = new FIFO<DLElement>(1, 20);
1426         dl = (DataList<DLElement>*) f;
1427 
1428         it = dl->getIterator();
1429 
1430         for (i = 0; i < 10; i++)
1431         {
1432             dle.i = i;
1433             f->insert(dle);
1434         }
1435 
1436         f->endOfInput();
1437 
1438         for (i = 0; i < 10; i++)
1439         {
1440 // 			cout << "next" << endl;
1441             more = dl->next(it, &dle);
1442             CPPUNIT_ASSERT(more == true);
1443             CPPUNIT_ASSERT(dle.i == i);
1444 //  			cout << "dle[" << i << "]: " << dle.i << endl;
1445         }
1446 
1447         delete f;
1448     }
1449 
1450 
1451 
1452 
1453 
1454 
1455 };
1456 
1457 CPPUNIT_TEST_SUITE_REGISTRATION(DataListDriver);
1458 
1459 
main(int argc,char ** argv)1460 int main( int argc, char** argv)
1461 {
1462     CppUnit::TextUi::TestRunner runner;
1463     CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
1464     runner.addTest( registry.makeTest() );
1465     bool wasSuccessful = runner.run( "", false );
1466     return (wasSuccessful ? 0 : 1);
1467 }
1468 
1469 
1470