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 /*****************************************************************************
19 * $Id: tdriver-brm.cpp 1823 2013-01-21 14:13:09Z rdempsey $
20 *
21 ****************************************************************************/
22
23 #include <iostream>
24 #include <pthread.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/ipc.h>
28 #include <sys/sem.h>
29 #include <sys/shm.h>
30 #include <stdexcept>
31 #include <pthread.h>
32 #include <sys/time.h>
33 #include <values.h>
34
35 #include <cppunit/extensions/HelperMacros.h>
36
37 #include "brm.h"
38 #include "IDBPolicy.h"
39
40 using namespace BRM;
41 using namespace std;
42
43 int threadStop;
44 int oid = 1;
45 uint64_t opCount = 0;
46 LBID_t lbidCounter = 0;
47 VER_t nextTxnID = 1;
48 u_int64_t vbOffset = 0;
49 pthread_mutex_t mutex;
50
51 struct Range
52 {
53 LBID_t start, end, nextBlock;
54 VER_t txnID;
RangeRange55 Range()
56 {
57 start = end = nextBlock = 0;
58 txnID = 0;
59 }
60 };
61
BRMRunner_2(void * arg)62 static void* BRMRunner_2(void* arg)
63 {
64
65 vector<Range> copyList, copiedList, committedList;
66 vector<Range>::iterator rit;
67 vector<LBID_t> writtenList;
68 vector<LBID_t>::iterator lit;
69
70 pthread_mutex_t listMutex;
71 int op;
72 uint32_t randstate;
73 BlockResolutionManager* brm;
74 struct timeval tv;
75
76 pthread_mutex_init(&listMutex, NULL);
77 gettimeofday(&tv, NULL);
78 randstate = static_cast<uint32_t>(tv.tv_usec);
79 brm = new BlockResolutionManager();
80
81 while (!threadStop)
82 {
83 op = rand_r(&randstate) % 9;
84
85 switch (op)
86 {
87 case 0: // beginVBCopy
88 {
89 int blockCount, size, err;
90 Range newEntry;
91 VBRange_v vbRanges;
92 VBRange_v::iterator vit;
93 LBIDRange_v ranges;
94 LBIDRange range;
95 VER_t txnID;
96
97 size = rand_r(&randstate) % 10000;
98
99 pthread_mutex_lock(&mutex);
100 newEntry.start = lbidCounter;
101 lbidCounter += size;
102 txnID = nextTxnID++;
103 pthread_mutex_unlock(&mutex);
104
105 newEntry.nextBlock = newEntry.start;
106 newEntry.end = newEntry.start + size;
107 range.start = newEntry.start;
108 range.size = size;
109
110 err = brm->beginVBCopy(txnID, ranges, vbRanges);
111 CPPUNIT_ASSERT(err == 0);
112
113 for (blockCount = 0, vit = vbRanges.begin(); vit != vbRanges.end(); vit++)
114 blockCount += (*vit).size;
115
116 CPPUNIT_ASSERT(blockCount == size);
117
118 pthread_mutex_lock(&listMutex);
119 copyList.push_back(newEntry);
120 pthread_mutex_unlock(&listMutex);
121
122 err = brm->beginVBCopy(txnID, ranges, vbRanges);
123 CPPUNIT_ASSERT(err == -1);
124 break;
125 }
126
127 case 1: // writeVBEntry
128 {
129 int randIndex;
130 VER_t txnID;
131 Range* entry;
132
133 pthread_mutex_lock(&listMutex);
134
135 if (copyList.size() == 0)
136 break;
137
138 randIndex = rand_r(&randstate) % copyList.size();
139 entry = &(copyList[randIndex]);
140 entry->nextBlock++;
141 txnID = entry->txnID;
142 /********** WORKING HERE **********/
143 }
144
145 default:
146 cerr << "not finished yet" << endl;
147 }
148 }
149
150 return NULL;
151 }
152
153
154
BRMRunner_1(void * arg)155 static void* BRMRunner_1(void* arg)
156 {
157
158 // keep track of LBID ranges allocated here and
159 // randomly allocate, lookup, delete, get/set HWM, and
160 // destroy the EM object.
161
162 struct EMEntries
163 {
164 u_int64_t LBIDstart;
165 uint32_t size;
166 int OID;
167 uint32_t FBO;
168 uint32_t HWM;
169 uint32_t secondHWM;
170 uint32_t txnID;
171 struct EMEntries* next;
172 EMEntries()
173 {
174 next = NULL;
175 HWM = 0;
176 secondHWM = 0;
177 txnID = 0;
178 }
179 };
180
181 #ifdef BRM_VERBOSE
182 int threadNum = reinterpret_cast<int>(arg);
183 #endif
184 int op, listSize = 0, i;
185 uint32_t randstate;
186 struct EMEntries* head = NULL, *tmp;
187 struct timeval tv;
188 BlockResolutionManager* brm;
189 ExtentMap em;
190 vector<LBID_t> lbids;
191
192 #ifdef BRM_VERBOSE
193 cerr << "thread number " << threadNum << " started." << endl;
194 #endif
195
196 gettimeofday(&tv, NULL);
197 randstate = static_cast<uint32_t>(tv.tv_usec);
198 brm = new BlockResolutionManager();
199
200 while (!threadStop)
201 {
202 op = rand_r(&randstate) % 10;
203 #ifdef BRM_VERBOSE
204 cerr << "next op is " << op << endl;
205 #endif
206
207 switch (op)
208 {
209 case 0: //allocate space for a new file
210 {
211 struct EMEntries* newEm;
212 int size = rand_r(&randstate) % 102399 + 1;
213 int entries, OID, allocdSize, err;
214
215 pthread_mutex_lock(&mutex);
216 OID = oid++;
217 opCount++;
218 pthread_mutex_unlock(&mutex);
219
220 err = brm->createExtent(size, OID, lbids, allocdSize);
221 CPPUNIT_ASSERT(err == 0);
222
223 entries = size / brm->getExtentSize();
224
225 if ((size % brm->getExtentSize()) != 0)
226 entries++;
227
228 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
229
230 for (i = 0 ; i < entries; i++)
231 {
232
233 newEm = new EMEntries();
234 newEm->size = brm->getExtentSize();
235 newEm->OID = OID;
236 newEm->FBO = i * brm->getExtentSize();
237 newEm->LBIDstart = lbids[i];
238
239 newEm->next = head;
240 head = newEm;
241 listSize++;
242 }
243
244 #ifdef BRM_VERBOSE
245 cerr << "created new space for OID " << newEm->OID << endl;
246 #endif
247 em.checkConsistency();
248 break;
249 }
250
251 case 1: //allocate space for an existing file
252 {
253 if (listSize == 0)
254 break;
255
256 struct EMEntries* newEm, *tmp;
257 int size = rand_r(&randstate) % 102399 + 1;
258 int fileRand = rand_r(&randstate) % listSize;
259 int i, lastExtent, blockEnd, oid;
260 int tmpHWM, entries, allocdSize, err;
261 vector<LBID_t> lbids;
262
263 for (i = 0, tmp = head; i < fileRand; i++)
264 tmp = tmp->next;
265
266 oid = tmp->OID;
267
268 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
269 {
270 if (tmp->OID != oid)
271 continue;
272
273 tmpHWM = tmp->HWM;
274 blockEnd = tmp->FBO + tmp->size;
275
276 if (lastExtent < blockEnd)
277 lastExtent = blockEnd;
278 }
279
280 err = brm->createExtent(size, oid, lbids, allocdSize);
281 pthread_mutex_lock(&mutex);
282 opCount++;
283 pthread_mutex_unlock(&mutex);
284 CPPUNIT_ASSERT(err == 0);
285
286 entries = size / brm->getExtentSize();
287
288 if ((size % brm->getExtentSize()) != 0)
289 entries++;
290
291 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
292
293 for (i = 0; i < entries; i++)
294 {
295
296 newEm = new EMEntries();
297
298 if (i != entries)
299 newEm->size = brm->getExtentSize();
300 else
301 newEm->size = size % brm->getExtentSize();
302
303 newEm->OID = oid;
304 newEm->FBO = lastExtent + (i * brm->getExtentSize());
305 newEm->LBIDstart = lbids[i];
306 newEm->HWM = tmpHWM;
307
308 newEm->next = head;
309 head = newEm;
310 listSize++;
311 }
312
313 #ifdef BRM_VERBOSE
314 cerr << "created another extent for OID " << newEm->OID << endl;
315 #endif
316 em.checkConsistency();
317 break;
318 }
319
320 case 2: //delete an OID
321 {
322 if (listSize == 0)
323 break;
324
325 struct EMEntries* tmp, *prev;
326 int fileRand = rand_r(&randstate) % listSize;
327 int i, oid, err;
328
329 for (i = 0, tmp = head; i < fileRand; i++)
330 tmp = tmp->next;
331
332 oid = tmp->OID;
333
334 err = brm->deleteOID(oid);
335 pthread_mutex_lock(&mutex);
336 opCount++;
337 pthread_mutex_unlock(&mutex);
338 CPPUNIT_ASSERT(err == 0);
339
340 for (tmp = head; tmp != NULL;)
341 {
342 if (tmp->OID == oid)
343 {
344 if (tmp == head)
345 {
346 head = head->next;
347 delete tmp;
348 tmp = head;
349 }
350 else
351 {
352 prev->next = tmp->next;
353 delete tmp;
354 tmp = prev->next;
355 }
356
357 listSize--;
358 }
359 else
360 {
361 prev = tmp;
362 tmp = tmp->next;
363 }
364 }
365
366 #ifdef BRM_VERBOSE
367 cerr << "deleted OID " << oid << endl;
368 #endif
369 em.checkConsistency();
370 break;
371 }
372
373 case 3: //lookup by LBID
374 {
375 if (listSize == 0)
376 break;
377
378 int entryRand = rand_r(&randstate) % listSize;
379 int i, err, offset, oid;
380 struct EMEntries* tmp;
381 LBID_t target;
382 uint32_t fbo;
383
384 for (i = 0, tmp = head; i < entryRand; i++)
385 tmp = tmp->next;
386
387 offset = rand_r(&randstate) % tmp->size;
388
389 target = tmp->LBIDstart + offset;
390 err = brm->lookup(target, 0, false, oid, fbo);
391 pthread_mutex_lock(&mutex);
392 opCount++;
393 pthread_mutex_unlock(&mutex);
394 #ifdef BRM_VERBOSE
395 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
396 cerr << " oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
397 #endif
398 CPPUNIT_ASSERT(err == 0);
399 CPPUNIT_ASSERT(oid == tmp->OID);
400 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
401 em.checkConsistency();
402 break;
403 }
404
405 case 4: //lookup by OID, FBO
406 {
407 if (listSize == 0)
408 break;
409
410 int entryRand = rand_r(&randstate) % listSize;
411 int i, oid, err, offset;
412 struct EMEntries* tmp;
413 LBID_t lbid;
414
415 for (i = 0, tmp = head; i < entryRand; i++)
416 tmp = tmp->next;
417
418 offset = rand_r(&randstate) % tmp->size;
419 oid = tmp->OID;
420
421 err = brm->lookup(oid, offset + tmp->FBO, lbid);
422 pthread_mutex_lock(&mutex);
423 opCount++;
424 pthread_mutex_unlock(&mutex);
425 #ifdef BRM_VERBOSE
426 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
427 " got lbid " << lbid << endl;
428 cerr << " lbid should be " << tmp->LBIDstart + offset << endl;
429 #endif
430 CPPUNIT_ASSERT(err == 0);
431 CPPUNIT_ASSERT(lbid == static_cast<LBID_t>(tmp->LBIDstart + offset));
432 em.checkConsistency();
433 break;
434 }
435
436 case 5: //getHWM
437 {
438 if (listSize == 0)
439 break;
440
441 int entryRand = rand_r(&randstate) % listSize;
442 int i, err;
443 struct EMEntries* tmp;
444 uint32_t hwm;
445
446 for (i = 0, tmp = head; i < entryRand; i++)
447 tmp = tmp->next;
448
449 err = brm->getHWM(tmp->OID, hwm);
450 pthread_mutex_lock(&mutex);
451 opCount++;
452 pthread_mutex_unlock(&mutex);
453 CPPUNIT_ASSERT(err == 0);
454 #ifdef BRM_VERBOSE
455 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
456 << " BRM says it's " << hwm << endl;
457 #endif
458 CPPUNIT_ASSERT(hwm == tmp->HWM);
459 em.checkConsistency();
460 break;
461 }
462
463 case 6: //setHWM
464 {
465 if (listSize == 0)
466 break;
467
468 int entryRand = rand_r(&randstate) % listSize;
469 int i, hwm, oid, err;
470 struct EMEntries* tmp;
471
472 for (i = 0, tmp = head; i < entryRand; i++)
473 tmp = tmp->next;
474
475 oid = tmp->OID;
476 hwm = rand_r(&randstate) % (tmp->FBO + brm->getExtentSize());
477 err = brm->setHWM(oid, hwm);
478 pthread_mutex_lock(&mutex);
479 opCount++;
480 pthread_mutex_unlock(&mutex);
481 CPPUNIT_ASSERT(err == 0);
482
483 for (tmp = head; tmp != NULL; tmp = tmp->next)
484 if (tmp->OID == oid)
485 tmp->HWM = hwm;
486
487 #ifdef BRM_VERBOSE
488 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
489 #endif
490 em.checkConsistency();
491 break;
492 }
493
494 case 7: // renew this EM object
495 {
496 delete brm;
497 brm = new BlockResolutionManager();
498 pthread_mutex_lock(&mutex);
499 opCount++;
500 pthread_mutex_unlock(&mutex);
501 #ifdef BRM_VERBOSE
502 cerr << "got a new BRM instance" << endl;
503 #endif
504 em.checkConsistency();
505 break;
506 }
507
508 case 8: //getBulkInsertVars
509 {
510 if (listSize == 0)
511 break;
512
513 HWM_t hwm;
514 VER_t txnID;
515 int entryRand = rand_r(&randstate) % listSize;
516 int i, err, offset;
517 EMEntries* tmp;
518 LBID_t lbid;
519
520 for (i = 0, tmp = head; i < entryRand; i++)
521 tmp = tmp->next;
522
523 offset = rand_r(&randstate) % tmp->size;
524 lbid = tmp->LBIDstart + offset;
525 err = brm->getBulkInsertVars(lbid, hwm, txnID);
526 pthread_mutex_lock(&mutex);
527 opCount++;
528 pthread_mutex_unlock(&mutex);
529 CPPUNIT_ASSERT(err == 0);
530 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
531 CPPUNIT_ASSERT(txnID == tmp->txnID);
532 break;
533 }
534
535 case 9: //setBulkInsertVars
536 {
537 if (listSize == 0)
538 break;
539
540 int entryRand = rand_r(&randstate) % listSize;
541 int i, err, offset;
542 EMEntries* tmp;
543
544 for (i = 0, tmp = head; i < entryRand; i++)
545 tmp = tmp->next;
546
547 offset = rand_r(&randstate) % tmp->size;
548 tmp->secondHWM = rand_r(&randstate) % MAXINT;
549 tmp->txnID = rand_r(&randstate) % MAXINT;
550 err = brm->setBulkInsertVars(tmp->LBIDstart + offset,
551 tmp->secondHWM, tmp->txnID);
552 pthread_mutex_lock(&mutex);
553 opCount++;
554 pthread_mutex_unlock(&mutex);
555 CPPUNIT_ASSERT(err == 0);
556 break;
557 }
558
559 default:
560 break;
561 }
562 }
563
564 delete brm;
565
566 while (head != NULL)
567 {
568 tmp = head->next;
569 delete head;
570 head = tmp;
571 }
572
573 #ifdef BRM_VERBOSE
574 cerr << "thread " << threadNum << " exiting" << endl;
575 #endif
576 return NULL;
577 }
578
579 BlockResolutionManager brm_si;
580
BRMRunner_si(void * arg)581 static void* BRMRunner_si(void* arg)
582 {
583
584 // keep track of LBID ranges allocated here and
585 // randomly allocate, lookup, delete, get/set HWM, and
586 // destroy the EM object.
587
588 struct EMEntries
589 {
590 u_int64_t LBIDstart;
591 uint32_t size;
592 int OID;
593 uint32_t FBO;
594 uint32_t HWM;
595 uint32_t secondHWM;
596 uint32_t txnID;
597 struct EMEntries* next;
598 EMEntries()
599 {
600 next = NULL;
601 HWM = 0;
602 secondHWM = 0;
603 txnID = 0;
604 }
605 };
606
607 #ifdef BRM_VERBOSE
608 int threadNum = reinterpret_cast<int>(arg);
609 #endif
610 int op, listSize = 0, i;
611 uint32_t randstate;
612 struct EMEntries* head = NULL, *tmp;
613 struct timeval tv;
614 ExtentMap em;
615 vector<LBID_t> lbids;
616
617 #ifdef BRM_VERBOSE
618 cerr << "thread number " << threadNum << " started." << endl;
619 #endif
620
621 gettimeofday(&tv, NULL);
622 randstate = static_cast<uint32_t>(tv.tv_usec);
623
624 while (!threadStop)
625 {
626 op = rand_r(&randstate) % 10;
627 #ifdef BRM_VERBOSE
628 cerr << "next op is " << op << endl;
629 #endif
630
631 switch (op)
632 {
633 case 0: //allocate space for a new file
634 {
635 struct EMEntries* newEm;
636 int size = rand_r(&randstate) % 102399 + 1;
637 int entries, OID, allocdSize, err;
638
639 pthread_mutex_lock(&mutex);
640 OID = oid++;
641 opCount++;
642 pthread_mutex_unlock(&mutex);
643
644 err = brm_si.createExtent(size, OID, lbids, allocdSize);
645 CPPUNIT_ASSERT(err == 0);
646
647 entries = size / brm_si.getExtentSize();
648
649 if ((size % brm_si.getExtentSize()) != 0)
650 entries++;
651
652 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
653
654 for (i = 0 ; i < entries; i++)
655 {
656
657 newEm = new EMEntries();
658 newEm->size = brm_si.getExtentSize();
659 newEm->OID = OID;
660 newEm->FBO = i * brm_si.getExtentSize();
661 newEm->LBIDstart = lbids[i];
662
663 newEm->next = head;
664 head = newEm;
665 listSize++;
666 }
667
668 #ifdef BRM_VERBOSE
669 cerr << "created new space for OID " << newEm->OID << endl;
670 #endif
671 em.checkConsistency();
672 break;
673 }
674
675 case 1: //allocate space for an existing file
676 {
677 if (listSize == 0)
678 break;
679
680 struct EMEntries* newEm, *tmp;
681 int size = rand_r(&randstate) % 102399 + 1;
682 int fileRand = rand_r(&randstate) % listSize;
683 int i, lastExtent, blockEnd, oid;
684 int tmpHWM, entries, allocdSize, err;
685 vector<LBID_t> lbids;
686
687 for (i = 0, tmp = head; i < fileRand; i++)
688 tmp = tmp->next;
689
690 oid = tmp->OID;
691
692 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
693 {
694 if (tmp->OID != oid)
695 continue;
696
697 tmpHWM = tmp->HWM;
698 blockEnd = tmp->FBO + tmp->size;
699
700 if (lastExtent < blockEnd)
701 lastExtent = blockEnd;
702 }
703
704 err = brm_si.createExtent(size, oid, lbids, allocdSize);
705 pthread_mutex_lock(&mutex);
706 opCount++;
707 pthread_mutex_unlock(&mutex);
708 CPPUNIT_ASSERT(err == 0);
709
710 entries = size / brm_si.getExtentSize();
711
712 if ((size % brm_si.getExtentSize()) != 0)
713 entries++;
714
715 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
716
717 for (i = 0; i < entries; i++)
718 {
719
720 newEm = new EMEntries();
721
722 if (i != entries)
723 newEm->size = brm_si.getExtentSize();
724 else
725 newEm->size = size % brm_si.getExtentSize();
726
727 newEm->OID = oid;
728 newEm->FBO = lastExtent + (i * brm_si.getExtentSize());
729 newEm->LBIDstart = lbids[i];
730 newEm->HWM = tmpHWM;
731
732 newEm->next = head;
733 head = newEm;
734 listSize++;
735 }
736
737 #ifdef BRM_VERBOSE
738 cerr << "created another extent for OID " << newEm->OID << endl;
739 #endif
740 em.checkConsistency();
741 break;
742 }
743
744 case 2: //delete an OID
745 {
746 if (listSize == 0)
747 break;
748
749 struct EMEntries* tmp, *prev;
750 int fileRand = rand_r(&randstate) % listSize;
751 int i, oid, err;
752
753 for (i = 0, tmp = head; i < fileRand; i++)
754 tmp = tmp->next;
755
756 oid = tmp->OID;
757
758 err = brm_si.deleteOID(oid);
759 pthread_mutex_lock(&mutex);
760 opCount++;
761 pthread_mutex_unlock(&mutex);
762 CPPUNIT_ASSERT(err == 0);
763
764 for (tmp = head; tmp != NULL;)
765 {
766 if (tmp->OID == oid)
767 {
768 if (tmp == head)
769 {
770 head = head->next;
771 delete tmp;
772 tmp = head;
773 }
774 else
775 {
776 prev->next = tmp->next;
777 delete tmp;
778 tmp = prev->next;
779 }
780
781 listSize--;
782 }
783 else
784 {
785 prev = tmp;
786 tmp = tmp->next;
787 }
788 }
789
790 #ifdef BRM_VERBOSE
791 cerr << "deleted OID " << oid << endl;
792 #endif
793 em.checkConsistency();
794 break;
795 }
796
797 case 3: //lookup by LBID
798 {
799 if (listSize == 0)
800 break;
801
802 int entryRand = rand_r(&randstate) % listSize;
803 int i, err, offset, oid;
804 struct EMEntries* tmp;
805 LBID_t target;
806 uint32_t fbo;
807
808 for (i = 0, tmp = head; i < entryRand; i++)
809 tmp = tmp->next;
810
811 offset = rand_r(&randstate) % tmp->size;
812
813 target = tmp->LBIDstart + offset;
814 err = brm_si.lookup(target, 0, false, oid, fbo);
815 pthread_mutex_lock(&mutex);
816 opCount++;
817 pthread_mutex_unlock(&mutex);
818 #ifdef BRM_VERBOSE
819 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
820 cerr << " oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
821 #endif
822 CPPUNIT_ASSERT(err == 0);
823 CPPUNIT_ASSERT(oid == tmp->OID);
824 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
825 em.checkConsistency();
826 break;
827 }
828
829 case 4: //lookup by OID, FBO
830 {
831 if (listSize == 0)
832 break;
833
834 int entryRand = rand_r(&randstate) % listSize;
835 int i, oid, err, offset;
836 struct EMEntries* tmp;
837 LBID_t lbid;
838
839 for (i = 0, tmp = head; i < entryRand; i++)
840 tmp = tmp->next;
841
842 offset = rand_r(&randstate) % tmp->size;
843 oid = tmp->OID;
844
845 err = brm_si.lookup(oid, offset + tmp->FBO, lbid);
846 pthread_mutex_lock(&mutex);
847 opCount++;
848 pthread_mutex_unlock(&mutex);
849 #ifdef BRM_VERBOSE
850 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
851 " got lbid " << lbid << endl;
852 cerr << " lbid should be " << tmp->LBIDstart + offset << endl;
853 #endif
854 CPPUNIT_ASSERT(err == 0);
855 CPPUNIT_ASSERT(lbid == static_cast<LBID_t>(tmp->LBIDstart + offset));
856 em.checkConsistency();
857 break;
858 }
859
860 case 5: //getHWM
861 {
862 if (listSize == 0)
863 break;
864
865 int entryRand = rand_r(&randstate) % listSize;
866 int i, err;
867 struct EMEntries* tmp;
868 uint32_t hwm;
869
870 for (i = 0, tmp = head; i < entryRand; i++)
871 tmp = tmp->next;
872
873 err = brm_si.getHWM(tmp->OID, hwm);
874 pthread_mutex_lock(&mutex);
875 opCount++;
876 pthread_mutex_unlock(&mutex);
877 CPPUNIT_ASSERT(err == 0);
878 #ifdef BRM_VERBOSE
879 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
880 << " BRM says it's " << hwm << endl;
881 #endif
882 CPPUNIT_ASSERT(hwm == tmp->HWM);
883 em.checkConsistency();
884 break;
885 }
886
887 case 6: //setHWM
888 {
889 if (listSize == 0)
890 break;
891
892 int entryRand = rand_r(&randstate) % listSize;
893 int i, hwm, oid, err;
894 struct EMEntries* tmp;
895
896 for (i = 0, tmp = head; i < entryRand; i++)
897 tmp = tmp->next;
898
899 oid = tmp->OID;
900 hwm = rand_r(&randstate) % (tmp->FBO + brm_si.getExtentSize());
901 err = brm_si.setHWM(oid, hwm);
902 pthread_mutex_lock(&mutex);
903 opCount++;
904 pthread_mutex_unlock(&mutex);
905 CPPUNIT_ASSERT(err == 0);
906
907 for (tmp = head; tmp != NULL; tmp = tmp->next)
908 if (tmp->OID == oid)
909 tmp->HWM = hwm;
910
911 #ifdef BRM_VERBOSE
912 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
913 #endif
914 em.checkConsistency();
915 break;
916 }
917
918 case 7: //getBulkInsertVars
919 {
920 if (listSize == 0)
921 break;
922
923 HWM_t hwm;
924 VER_t txnID;
925 int entryRand = rand_r(&randstate) % listSize;
926 int i, err, offset;
927 EMEntries* tmp;
928 LBID_t lbid;
929
930 for (i = 0, tmp = head; i < entryRand; i++)
931 tmp = tmp->next;
932
933 offset = rand_r(&randstate) % tmp->size;
934 lbid = tmp->LBIDstart + offset;
935 err = brm_si.getBulkInsertVars(lbid, hwm, txnID);
936 pthread_mutex_lock(&mutex);
937 opCount++;
938 pthread_mutex_unlock(&mutex);
939 CPPUNIT_ASSERT(err == 0);
940 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
941 CPPUNIT_ASSERT(txnID == tmp->txnID);
942 break;
943 }
944
945 case 8: //setBulkInsertVars
946 {
947 if (listSize == 0)
948 break;
949
950 int entryRand = rand_r(&randstate) % listSize;
951 int i, err, offset;
952 EMEntries* tmp;
953
954 for (i = 0, tmp = head; i < entryRand; i++)
955 tmp = tmp->next;
956
957 offset = rand_r(&randstate) % tmp->size;
958 tmp->secondHWM = rand_r(&randstate) % MAXINT;
959 tmp->txnID = rand_r(&randstate) % MAXINT;
960 err = brm_si.setBulkInsertVars(tmp->LBIDstart + offset,
961 tmp->secondHWM, tmp->txnID);
962 pthread_mutex_lock(&mutex);
963 opCount++;
964 pthread_mutex_unlock(&mutex);
965 CPPUNIT_ASSERT(err == 0);
966 break;
967 }
968
969 default:
970 break;
971 }
972 }
973
974 while (head != NULL)
975 {
976 tmp = head->next;
977 delete head;
978 head = tmp;
979 }
980
981 #ifdef BRM_VERBOSE
982 cerr << "thread " << threadNum << " exiting" << endl;
983 #endif
984 return NULL;
985 }
986
EMRunner(void * arg)987 static void* EMRunner(void* arg)
988 {
989
990 // keep track of LBID ranges allocated here and
991 // randomly allocate, lookup, delete, get/set HWM, and
992 // destroy the EM object.
993
994 struct EMEntries
995 {
996 u_int64_t LBIDstart;
997 uint32_t size;
998 int OID;
999 uint32_t FBO;
1000 uint32_t HWM;
1001 uint32_t secondHWM;
1002 uint32_t txnID;
1003 struct EMEntries* next;
1004 EMEntries()
1005 {
1006 next = NULL;
1007 HWM = 0;
1008 secondHWM = 0;
1009 txnID = 0;
1010 }
1011 };
1012
1013 #ifdef BRM_VERBOSE
1014 int threadNum = reinterpret_cast<int>(arg);
1015 #endif
1016 int op, listSize = 0, i;
1017 uint32_t randstate;
1018 struct EMEntries* head = NULL, *tmp;
1019 struct timeval tv;
1020 ExtentMap* em;
1021 vector<LBID_t> lbids;
1022
1023 #ifdef BRM_VERBOSE
1024 cerr << "thread number " << threadNum << " started." << endl;
1025 #endif
1026
1027 gettimeofday(&tv, NULL);
1028 randstate = static_cast<uint32_t>(tv.tv_usec);
1029 em = new ExtentMap();
1030
1031 while (!threadStop)
1032 {
1033 op = rand_r(&randstate) % 10;
1034 #ifdef BRM_VERBOSE
1035 cerr << "next op is " << op << endl;
1036 #endif
1037
1038 switch (op)
1039 {
1040 case 0: //allocate space for a new file
1041 {
1042 struct EMEntries* newEm;
1043 int size = rand_r(&randstate) % 102399 + 1;
1044 int entries, OID, allocdSize;
1045
1046 pthread_mutex_lock(&mutex);
1047 OID = oid++;
1048 pthread_mutex_unlock(&mutex);
1049
1050 em->createExtent(size, OID, lbids, allocdSize);
1051 em->confirmChanges();
1052
1053 entries = size / em->getExtentSize();
1054
1055 if ((size % em->getExtentSize()) != 0)
1056 entries++;
1057
1058 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1059
1060 for (i = 0 ; i < entries; i++)
1061 {
1062
1063 newEm = new EMEntries();
1064 newEm->size = em->getExtentSize();
1065 newEm->OID = OID;
1066 newEm->FBO = i * em->getExtentSize();
1067 newEm->LBIDstart = lbids[i];
1068
1069 newEm->next = head;
1070 head = newEm;
1071 listSize++;
1072 }
1073
1074 #ifdef BRM_VERBOSE
1075 cerr << "created new space for OID " << newEm->OID << endl;
1076 #endif
1077 em->checkConsistency();
1078 break;
1079 }
1080
1081 case 1: //allocate space for an existing file
1082 {
1083 if (listSize == 0)
1084 break;
1085
1086 struct EMEntries* newEm, *tmp;
1087 int size = rand_r(&randstate) % 102399 + 1;
1088 int fileRand = rand_r(&randstate) % listSize;
1089 int i, lastExtent, blockEnd, oid;
1090 int tmpHWM, entries, allocdSize;
1091 vector<LBID_t> lbids;
1092
1093 for (i = 0, tmp = head; i < fileRand; i++)
1094 tmp = tmp->next;
1095
1096 oid = tmp->OID;
1097
1098 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
1099 {
1100 if (tmp->OID != oid)
1101 continue;
1102
1103 tmpHWM = tmp->HWM;
1104 blockEnd = tmp->FBO + tmp->size;
1105
1106 if (lastExtent < blockEnd)
1107 lastExtent = blockEnd;
1108 }
1109
1110 em->createExtent(size, oid, lbids, allocdSize);
1111 em->confirmChanges();
1112
1113 entries = size / em->getExtentSize();
1114
1115 if ((size % em->getExtentSize()) != 0)
1116 entries++;
1117
1118 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1119
1120 for (i = 0; i < entries; i++)
1121 {
1122
1123 newEm = new EMEntries();
1124
1125 if (i != entries)
1126 newEm->size = em->getExtentSize();
1127 else
1128 newEm->size = size % em->getExtentSize();
1129
1130 newEm->OID = oid;
1131 newEm->FBO = lastExtent + (i * em->getExtentSize());
1132 newEm->LBIDstart = lbids[i];
1133 newEm->HWM = tmpHWM;
1134
1135 newEm->next = head;
1136 head = newEm;
1137 listSize++;
1138 }
1139
1140 #ifdef BRM_VERBOSE
1141 cerr << "created another extent for OID " << newEm->OID << endl;
1142 #endif
1143 em->checkConsistency();
1144 break;
1145 }
1146
1147 case 2: //delete an OID
1148 {
1149 if (listSize == 0)
1150 break;
1151
1152 struct EMEntries* tmp, *prev;
1153 int fileRand = rand_r(&randstate) % listSize;
1154 int i, oid;
1155
1156 for (i = 0, tmp = head; i < fileRand; i++)
1157 tmp = tmp->next;
1158
1159 oid = tmp->OID;
1160
1161 em->deleteOID(oid);
1162 em->confirmChanges();
1163
1164 for (tmp = head; tmp != NULL;)
1165 {
1166 if (tmp->OID == oid)
1167 {
1168 if (tmp == head)
1169 {
1170 head = head->next;
1171 delete tmp;
1172 tmp = head;
1173 }
1174 else
1175 {
1176 prev->next = tmp->next;
1177 delete tmp;
1178 tmp = prev->next;
1179 }
1180
1181 listSize--;
1182 }
1183 else
1184 {
1185 prev = tmp;
1186 tmp = tmp->next;
1187 }
1188 }
1189
1190 #ifdef BRM_VERBOSE
1191 cerr << "deleted OID " << oid << endl;
1192 #endif
1193 em->checkConsistency();
1194 break;
1195 }
1196
1197 case 3: //lookup by LBID
1198 {
1199 if (listSize == 0)
1200 break;
1201
1202 int entryRand = rand_r(&randstate) % listSize;
1203 int i, err, offset, oid;
1204 struct EMEntries* tmp;
1205 LBID_t target;
1206 uint32_t fbo;
1207
1208 for (i = 0, tmp = head; i < entryRand; i++)
1209 tmp = tmp->next;
1210
1211 offset = rand_r(&randstate) % tmp->size;
1212
1213 target = tmp->LBIDstart + offset;
1214 err = em->lookup(target, oid, fbo);
1215 #ifdef BRM_VERBOSE
1216 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
1217 cerr << " oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
1218 #endif
1219 CPPUNIT_ASSERT(err == 0);
1220 CPPUNIT_ASSERT(oid == tmp->OID);
1221 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
1222 em->checkConsistency();
1223 break;
1224 }
1225
1226 case 4: //lookup by OID, FBO
1227 {
1228 if (listSize == 0)
1229 break;
1230
1231 int entryRand = rand_r(&randstate) % listSize;
1232 int i, oid, err, offset;
1233 struct EMEntries* tmp;
1234 LBID_t lbid;
1235
1236 for (i = 0, tmp = head; i < entryRand; i++)
1237 tmp = tmp->next;
1238
1239 offset = rand_r(&randstate) % tmp->size;
1240 oid = tmp->OID;
1241
1242 err = em->lookup(oid, offset + tmp->FBO, lbid);
1243 #ifdef BRM_VERBOSE
1244 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
1245 " got lbid " << lbid << endl;
1246 cerr << " lbid should be " << tmp->LBIDstart + offset << endl;
1247 #endif
1248 CPPUNIT_ASSERT(err == 0);
1249 CPPUNIT_ASSERT(lbid == tmp->LBIDstart + offset);
1250 em->checkConsistency();
1251 break;
1252 }
1253
1254 case 5: //getHWM
1255 {
1256 if (listSize == 0)
1257 break;
1258
1259 int entryRand = rand_r(&randstate) % listSize;
1260 int i;
1261 struct EMEntries* tmp;
1262 uint32_t hwm;
1263
1264 for (i = 0, tmp = head; i < entryRand; i++)
1265 tmp = tmp->next;
1266
1267 hwm = em->getHWM(tmp->OID);
1268 #ifdef BRM_VERBOSE
1269 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
1270 << " BRM says it's " << hwm << endl;
1271 #endif
1272 CPPUNIT_ASSERT(hwm == tmp->HWM);
1273 em->checkConsistency();
1274 break;
1275 }
1276
1277 case 6: //setHWM
1278 {
1279 if (listSize == 0)
1280 break;
1281
1282 int entryRand = rand_r(&randstate) % listSize;
1283 int i, hwm, oid;
1284 struct EMEntries* tmp;
1285
1286 for (i = 0, tmp = head; i < entryRand; i++)
1287 tmp = tmp->next;
1288
1289 oid = tmp->OID;
1290 hwm = rand_r(&randstate) % (tmp->FBO + em->getExtentSize());
1291 em->setHWM(oid, hwm);
1292 em->confirmChanges();
1293
1294 for (tmp = head; tmp != NULL; tmp = tmp->next)
1295 if (tmp->OID == oid)
1296 tmp->HWM = hwm;
1297
1298 #ifdef BRM_VERBOSE
1299 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
1300 #endif
1301 em->checkConsistency();
1302 break;
1303 }
1304
1305 case 7: // renew this EM object
1306 {
1307 delete em;
1308 em = new ExtentMap();
1309 #ifdef BRM_VERBOSE
1310 cerr << "got a new EM instance" << endl;
1311 #endif
1312 em->checkConsistency();
1313 break;
1314 }
1315
1316 case 8: //getBulkInsertVars
1317 {
1318 if (listSize == 0)
1319 break;
1320
1321 HWM_t hwm;
1322 VER_t txnID;
1323 int entryRand = rand_r(&randstate) % listSize;
1324 int i, err, offset;
1325 EMEntries* tmp;
1326 LBID_t lbid;
1327
1328 for (i = 0, tmp = head; i < entryRand; i++)
1329 tmp = tmp->next;
1330
1331 offset = rand_r(&randstate) % tmp->size;
1332 lbid = tmp->LBIDstart + offset;
1333 err = em->getBulkInsertVars(lbid, hwm, txnID);
1334 CPPUNIT_ASSERT(err == 0);
1335 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
1336 CPPUNIT_ASSERT(txnID == tmp->txnID);
1337 break;
1338 }
1339
1340 case 9: //setBulkInsertVars
1341 {
1342 if (listSize == 0)
1343 break;
1344
1345 int entryRand = rand_r(&randstate) % listSize;
1346 int i, err, offset;
1347 EMEntries* tmp;
1348
1349 for (i = 0, tmp = head; i < entryRand; i++)
1350 tmp = tmp->next;
1351
1352 offset = rand_r(&randstate) % tmp->size;
1353 tmp->secondHWM = rand_r(&randstate) % MAXINT;
1354 tmp->txnID = rand_r(&randstate) % MAXINT;
1355 err = em->setBulkInsertVars(tmp->LBIDstart + offset,
1356 tmp->secondHWM, tmp->txnID);
1357 em->confirmChanges();
1358 CPPUNIT_ASSERT(err == 0);
1359 break;
1360 }
1361
1362 default:
1363 break;
1364 }
1365 }
1366
1367 delete em;
1368
1369 while (head != NULL)
1370 {
1371 tmp = head->next;
1372 delete head;
1373 head = tmp;
1374 }
1375
1376 #ifdef BRM_VERBOSE
1377 cerr << "thread " << threadNum << " exiting" << endl;
1378 #endif
1379 return NULL;
1380 }
1381
1382 ExtentMap em_si;
EMRunner_si(void * arg)1383 static void* EMRunner_si(void* arg)
1384 {
1385
1386 // keep track of LBID ranges allocated here and
1387 // randomly allocate, lookup, delete, get/set HWM, and
1388 // destroy the EM object.
1389
1390 struct EMEntries
1391 {
1392 u_int64_t LBIDstart;
1393 uint32_t size;
1394 int OID;
1395 uint32_t FBO;
1396 uint32_t HWM;
1397 uint32_t secondHWM;
1398 uint32_t txnID;
1399 struct EMEntries* next;
1400 EMEntries()
1401 {
1402 next = NULL;
1403 HWM = 0;
1404 secondHWM = 0;
1405 txnID = 0;
1406 }
1407 };
1408
1409 #ifdef BRM_VERBOSE
1410 int threadNum = reinterpret_cast<int>(arg);
1411 #endif
1412 int op, listSize = 0, i;
1413 uint32_t randstate;
1414 struct EMEntries* head = NULL, *tmp;
1415 struct timeval tv;
1416 vector<LBID_t> lbids;
1417
1418 #ifdef BRM_VERBOSE
1419 cerr << "thread number " << threadNum << " started." << endl;
1420 #endif
1421
1422 gettimeofday(&tv, NULL);
1423 randstate = static_cast<uint32_t>(tv.tv_usec);
1424
1425 while (!threadStop)
1426 {
1427 op = rand_r(&randstate) % 9;
1428 #ifdef BRM_VERBOSE
1429 cerr << "next op is " << op << endl;
1430 #endif
1431
1432 switch (op)
1433 {
1434 case 0: //allocate space for a new file
1435 {
1436 struct EMEntries* newEm;
1437 int size = rand_r(&randstate) % 102399 + 1;
1438 int entries, OID, allocdSize;
1439
1440 pthread_mutex_lock(&mutex);
1441 OID = oid++;
1442 pthread_mutex_unlock(&mutex);
1443
1444 em_si.createExtent(size, OID, lbids, allocdSize);
1445 em_si.confirmChanges();
1446
1447 entries = size / em_si.getExtentSize();
1448
1449 if ((size % em_si.getExtentSize()) != 0)
1450 entries++;
1451
1452 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1453
1454 for (i = 0 ; i < entries; i++)
1455 {
1456
1457 newEm = new EMEntries();
1458 newEm->size = em_si.getExtentSize();
1459 newEm->OID = OID;
1460 newEm->FBO = i * em_si.getExtentSize();
1461 newEm->LBIDstart = lbids[i];
1462
1463 newEm->next = head;
1464 head = newEm;
1465 listSize++;
1466 }
1467
1468 #ifdef BRM_VERBOSE
1469 cerr << "created new space for OID " << newEm->OID << endl;
1470 #endif
1471 em_si.checkConsistency();
1472 break;
1473 }
1474
1475 case 1: //allocate space for an existing file
1476 {
1477 if (listSize == 0)
1478 break;
1479
1480 struct EMEntries* newEm, *tmp;
1481 int size = rand_r(&randstate) % 102399 + 1;
1482 int fileRand = rand_r(&randstate) % listSize;
1483 int i, lastExtent, blockEnd, oid;
1484 int tmpHWM, entries, allocdSize;
1485 vector<LBID_t> lbids;
1486
1487 for (i = 0, tmp = head; i < fileRand; i++)
1488 tmp = tmp->next;
1489
1490 oid = tmp->OID;
1491
1492 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
1493 {
1494 if (tmp->OID != oid)
1495 continue;
1496
1497 tmpHWM = tmp->HWM;
1498 blockEnd = tmp->FBO + tmp->size;
1499
1500 if (lastExtent < blockEnd)
1501 lastExtent = blockEnd;
1502 }
1503
1504 em_si.createExtent(size, oid, lbids, allocdSize);
1505 em_si.confirmChanges();
1506
1507 entries = size / em_si.getExtentSize();
1508
1509 if ((size % em_si.getExtentSize()) != 0)
1510 entries++;
1511
1512 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1513
1514 for (i = 0; i < entries; i++)
1515 {
1516
1517 newEm = new EMEntries();
1518
1519 if (i != entries)
1520 newEm->size = em_si.getExtentSize();
1521 else
1522 newEm->size = size % em_si.getExtentSize();
1523
1524 newEm->OID = oid;
1525 newEm->FBO = lastExtent + (i * em_si.getExtentSize());
1526 newEm->LBIDstart = lbids[i];
1527 newEm->HWM = tmpHWM;
1528
1529 newEm->next = head;
1530 head = newEm;
1531 listSize++;
1532 }
1533
1534 #ifdef BRM_VERBOSE
1535 cerr << "created another extent for OID " << newEm->OID << endl;
1536 #endif
1537 em_si.checkConsistency();
1538 break;
1539 }
1540
1541 case 2: //delete an OID
1542 {
1543 if (listSize == 0)
1544 break;
1545
1546 struct EMEntries* tmp, *prev;
1547 int fileRand = rand_r(&randstate) % listSize;
1548 int i, oid;
1549
1550 for (i = 0, tmp = head; i < fileRand; i++)
1551 tmp = tmp->next;
1552
1553 oid = tmp->OID;
1554
1555 em_si.deleteOID(oid);
1556 em_si.confirmChanges();
1557
1558 for (tmp = head; tmp != NULL;)
1559 {
1560 if (tmp->OID == oid)
1561 {
1562 if (tmp == head)
1563 {
1564 head = head->next;
1565 delete tmp;
1566 tmp = head;
1567 }
1568 else
1569 {
1570 prev->next = tmp->next;
1571 delete tmp;
1572 tmp = prev->next;
1573 }
1574
1575 listSize--;
1576 }
1577 else
1578 {
1579 prev = tmp;
1580 tmp = tmp->next;
1581 }
1582 }
1583
1584 #ifdef BRM_VERBOSE
1585 cerr << "deleted OID " << oid << endl;
1586 #endif
1587 em_si.checkConsistency();
1588 break;
1589 }
1590
1591 case 3: //lookup by LBID
1592 {
1593 if (listSize == 0)
1594 break;
1595
1596 int entryRand = rand_r(&randstate) % listSize;
1597 int i, err, offset, oid;
1598 struct EMEntries* tmp;
1599 LBID_t target;
1600 uint32_t fbo;
1601
1602 for (i = 0, tmp = head; i < entryRand; i++)
1603 tmp = tmp->next;
1604
1605 offset = rand_r(&randstate) % tmp->size;
1606
1607 target = tmp->LBIDstart + offset;
1608 err = em_si.lookup(target, oid, fbo);
1609 #ifdef BRM_VERBOSE
1610 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
1611 cerr << " oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
1612 #endif
1613 CPPUNIT_ASSERT(err == 0);
1614 CPPUNIT_ASSERT(oid == tmp->OID);
1615 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
1616 em_si.checkConsistency();
1617 break;
1618 }
1619
1620 case 4: //lookup by OID, FBO
1621 {
1622 if (listSize == 0)
1623 break;
1624
1625 int entryRand = rand_r(&randstate) % listSize;
1626 int i, oid, err, offset;
1627 struct EMEntries* tmp;
1628 LBID_t lbid;
1629
1630 for (i = 0, tmp = head; i < entryRand; i++)
1631 tmp = tmp->next;
1632
1633 offset = rand_r(&randstate) % tmp->size;
1634 oid = tmp->OID;
1635
1636 err = em_si.lookup(oid, offset + tmp->FBO, lbid);
1637 #ifdef BRM_VERBOSE
1638 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
1639 " got lbid " << lbid << endl;
1640 cerr << " lbid should be " << tmp->LBIDstart + offset << endl;
1641 #endif
1642 CPPUNIT_ASSERT(err == 0);
1643 CPPUNIT_ASSERT(lbid == tmp->LBIDstart + offset);
1644 em_si.checkConsistency();
1645 break;
1646 }
1647
1648 case 5: //getHWM
1649 {
1650 if (listSize == 0)
1651 break;
1652
1653 int entryRand = rand_r(&randstate) % listSize;
1654 int i;
1655 struct EMEntries* tmp;
1656 uint32_t hwm;
1657
1658 for (i = 0, tmp = head; i < entryRand; i++)
1659 tmp = tmp->next;
1660
1661 hwm = em_si.getHWM(tmp->OID);
1662 #ifdef BRM_VERBOSE
1663 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
1664 << " BRM says it's " << hwm << endl;
1665 #endif
1666 CPPUNIT_ASSERT(hwm == tmp->HWM);
1667 em_si.checkConsistency();
1668 break;
1669 }
1670
1671 case 6: //setHWM
1672 {
1673 if (listSize == 0)
1674 break;
1675
1676 int entryRand = rand_r(&randstate) % listSize;
1677 int i, hwm, oid;
1678 struct EMEntries* tmp;
1679
1680 for (i = 0, tmp = head; i < entryRand; i++)
1681 tmp = tmp->next;
1682
1683 oid = tmp->OID;
1684 hwm = rand_r(&randstate) % (tmp->FBO + em_si.getExtentSize());
1685 em_si.setHWM(oid, hwm);
1686 em_si.confirmChanges();
1687
1688 for (tmp = head; tmp != NULL; tmp = tmp->next)
1689 if (tmp->OID == oid)
1690 tmp->HWM = hwm;
1691
1692 #ifdef BRM_VERBOSE
1693 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
1694 #endif
1695 em_si.checkConsistency();
1696 break;
1697 }
1698
1699 case 7: //getBulkInsertVars
1700 {
1701 if (listSize == 0)
1702 break;
1703
1704 HWM_t hwm;
1705 VER_t txnID;
1706 int entryRand = rand_r(&randstate) % listSize;
1707 int i, err, offset;
1708 EMEntries* tmp;
1709 LBID_t lbid;
1710
1711 for (i = 0, tmp = head; i < entryRand; i++)
1712 tmp = tmp->next;
1713
1714 offset = rand_r(&randstate) % tmp->size;
1715 lbid = tmp->LBIDstart + offset;
1716 err = em_si.getBulkInsertVars(lbid, hwm, txnID);
1717 CPPUNIT_ASSERT(err == 0);
1718 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
1719 CPPUNIT_ASSERT(txnID == tmp->txnID);
1720 break;
1721 }
1722
1723 case 8: //setBulkInsertVars
1724 {
1725 if (listSize == 0)
1726 break;
1727
1728 int entryRand = rand_r(&randstate) % listSize;
1729 int i, err, offset;
1730 EMEntries* tmp;
1731
1732 for (i = 0, tmp = head; i < entryRand; i++)
1733 tmp = tmp->next;
1734
1735 offset = rand_r(&randstate) % tmp->size;
1736 tmp->secondHWM = rand_r(&randstate) % MAXINT;
1737 tmp->txnID = rand_r(&randstate) % MAXINT;
1738 err = em_si.setBulkInsertVars(tmp->LBIDstart + offset,
1739 tmp->secondHWM, tmp->txnID);
1740 em_si.confirmChanges();
1741 CPPUNIT_ASSERT(err == 0);
1742 break;
1743 }
1744
1745 default:
1746 break;
1747 }
1748 }
1749
1750 while (head != NULL)
1751 {
1752 tmp = head->next;
1753 delete head;
1754 head = tmp;
1755 }
1756
1757 #ifdef BRM_VERBOSE
1758 cerr << "thread " << threadNum << " exiting" << endl;
1759 #endif
1760 return NULL;
1761 }
1762
1763 #ifdef PARTITIONING
1764 ExtentMap emrange_si;
EMRangeRunner_si(void * arg)1765 static void* EMRangeRunner_si(void* arg)
1766 {
1767
1768 // keep track of LBID ranges allocated here and
1769 // randomly allocate, lookup, delete, get/set HWM, and
1770 // destroy the EM object.
1771
1772 struct EMEntries
1773 {
1774 u_int64_t LBIDstart;
1775 uint32_t size;
1776 int OID;
1777 int64_t lo_val; // low value for this partition
1778 int64_t hi_val; // hi value for this partition
1779 uint32_t extCnt; // number of extents in this partition
1780 uint32_t FBO;
1781 uint32_t HWM;
1782 uint32_t secondHWM;
1783 uint32_t txnID;
1784 struct EMEntries* next;
1785 EMEntries()
1786 {
1787 next = NULL;
1788 HWM = 0;
1789 secondHWM = 0;
1790 txnID = 0;
1791 }
1792 };
1793
1794 #ifdef BRM_VERBOSE
1795 int threadNum = reinterpret_cast<int>(arg);
1796 #endif
1797 int op, listSize = 0, i;
1798 const int numOps = 11;
1799 int opRuns[numOps] = {0};
1800 uint32_t randstate;
1801 struct EMEntries* head = NULL, *tmp;
1802 struct timeval tv;
1803 vector<LBID_t> lbids;
1804
1805 #ifdef BRM_VERBOSE
1806 cerr << "thread number " << threadNum << " started." << endl;
1807 #endif
1808
1809 gettimeofday(&tv, NULL);
1810 randstate = static_cast<uint32_t>(tv.tv_usec);
1811 const int MaxPart = 16;
1812 static int64_t pLowValue = 0;
1813
1814 while (!threadStop)
1815 {
1816 op = rand_r(&randstate) % numOps;
1817 opRuns[op]++;
1818
1819 #ifdef BRM_VERBOSE
1820 cerr << "next op is " << op << endl;
1821 #endif
1822
1823 switch (op)
1824 {
1825 case 0: //allocate space for a new file
1826 {
1827 struct EMEntries* newEm;
1828 int size = rand_r(&randstate) % 102399 + 1;
1829 int partSize = rand_r(&randstate) % MaxPart + 1;
1830 int entries, OID, allocdSize;
1831
1832 pthread_mutex_lock(&mutex);
1833 OID = oid++;
1834 pthread_mutex_unlock(&mutex);
1835
1836 EMRangePartition_t emr(pLowValue + 1, pLowValue + 100, true, true);
1837 pthread_mutex_lock(&mutex);
1838 pLowValue += 100;
1839 pthread_mutex_unlock(&mutex);
1840
1841 emrange_si.createRangeExtent(size, OID, lbids, allocdSize, emr);
1842 emrange_si.confirmChanges();
1843
1844 entries = size / emrange_si.getExtentSize();
1845
1846 if ((size % emrange_si.getExtentSize()) != 0)
1847 entries++;
1848
1849 int partLen = entries;
1850 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1851
1852 int j = 0;
1853
1854 for (i = 0 ; i < entries && j < partSize; i++)
1855 {
1856 newEm = new EMEntries();
1857 newEm->size = emrange_si.getExtentSize();
1858 newEm->lo_val = emr.lo_val;
1859 newEm->hi_val = emr.hi_val;
1860 newEm->extCnt = partLen;
1861 newEm->OID = OID;
1862 newEm->FBO = i * emrange_si.getExtentSize();
1863 newEm->LBIDstart = lbids[i];
1864
1865 newEm->next = head;
1866 head = newEm;
1867 listSize++;
1868 }
1869
1870 #ifdef BRM_VERBOSE
1871 cerr << "created new space for OID " << newEm->OID << endl;
1872 #endif
1873
1874 emrange_si.checkConsistency();
1875 break;
1876 }
1877
1878 case 1: //allocate space for an existing file
1879 {
1880 if (listSize == 0)
1881 break;
1882
1883 struct EMEntries* newEm, *tmp;
1884 int size = rand_r(&randstate) % 102399 + 1;
1885 int partSize = rand_r(&randstate) % MaxPart + 1;
1886 int fileRand = rand_r(&randstate) % listSize;
1887 int i, lastExtent, blockEnd, oid;
1888 int tmpHWM, entries, allocdSize;
1889 vector<LBID_t> lbids;
1890
1891 EMRangePartition_t emr(pLowValue + 1, pLowValue + 100, true, true);
1892 pthread_mutex_lock(&mutex);
1893 pLowValue += 100;
1894 pthread_mutex_unlock(&mutex);
1895
1896 for (i = 0, tmp = head; i < fileRand; i++)
1897 tmp = tmp->next;
1898
1899 oid = tmp->OID;
1900
1901 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
1902 {
1903 if (tmp->OID != oid)
1904 continue;
1905
1906 tmpHWM = tmp->HWM;
1907 blockEnd = tmp->FBO + tmp->size;
1908
1909 if (lastExtent < blockEnd)
1910 lastExtent = blockEnd;
1911 }
1912
1913 emrange_si.createRangeExtent(size, oid, lbids, allocdSize, emr);
1914 emrange_si.confirmChanges();
1915
1916 entries = size / emrange_si.getExtentSize();
1917
1918 if ((size % emrange_si.getExtentSize()) != 0)
1919 entries++;
1920
1921 int partLen = entries;
1922 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
1923
1924 int j = 0;
1925
1926 for (i = 0; i < entries && j < partSize; i++)
1927 {
1928 newEm = new EMEntries();
1929
1930 if (i != entries)
1931 newEm->size = emrange_si.getExtentSize();
1932 else
1933 newEm->size = size % emrange_si.getExtentSize();
1934
1935 newEm->OID = oid;
1936 newEm->lo_val = emr.lo_val;
1937 newEm->hi_val = emr.hi_val;
1938 newEm->extCnt = partLen;
1939 newEm->FBO = lastExtent + (i * emrange_si.getExtentSize());
1940 newEm->LBIDstart = lbids[i];
1941 newEm->HWM = tmpHWM;
1942
1943 newEm->next = head;
1944 head = newEm;
1945 listSize++;
1946 }
1947
1948 #ifdef BRM_VERBOSE
1949 cerr << "created another extent for OID " << newEm->OID << endl;
1950 #endif
1951
1952 emrange_si.checkConsistency();
1953 break;
1954 }
1955
1956 case 2: //delete an OID
1957 {
1958 if (listSize == 0)
1959 break;
1960
1961 struct EMEntries* tmp, *prev;
1962 int fileRand = rand_r(&randstate) % listSize;
1963 int i, oid;
1964
1965 for (i = 0, tmp = head; i < fileRand; i++)
1966 tmp = tmp->next;
1967
1968 oid = tmp->OID;
1969
1970 emrange_si.deleteOID(oid);
1971 emrange_si.confirmChanges();
1972
1973 for (tmp = head; tmp != NULL;)
1974 {
1975 if (tmp->OID == oid)
1976 {
1977 if (tmp == head)
1978 {
1979 head = head->next;
1980 delete tmp;
1981 tmp = head;
1982 }
1983 else
1984 {
1985 prev->next = tmp->next;
1986 delete tmp;
1987 tmp = prev->next;
1988 }
1989
1990 listSize--;
1991 }
1992 else
1993 {
1994 prev = tmp;
1995 tmp = tmp->next;
1996 }
1997 }
1998
1999 #ifdef BRM_VERBOSE
2000 cerr << "deleted OID " << oid << endl;
2001 #endif
2002 emrange_si.checkConsistency();
2003 break;
2004 }
2005
2006 case 3: //lookup by LBID
2007 {
2008 if (listSize == 0)
2009 break;
2010
2011 int entryRand = rand_r(&randstate) % listSize;
2012 int i, err, offset, oid;
2013 struct EMEntries* tmp;
2014 LBID_t target;
2015 uint32_t fbo;
2016
2017 for (i = 0, tmp = head; i < entryRand; i++)
2018 tmp = tmp->next;
2019
2020 offset = rand_r(&randstate) % tmp->size;
2021
2022 target = tmp->LBIDstart + offset;
2023 err = emrange_si.lookup(target, oid, fbo);
2024 #ifdef BRM_VERBOSE
2025 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
2026 cerr << " oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
2027 #endif
2028 CPPUNIT_ASSERT(err == 0);
2029 CPPUNIT_ASSERT(oid == tmp->OID);
2030 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
2031 emrange_si.checkConsistency();
2032 break;
2033 }
2034
2035 case 4: //lookup by OID, FBO
2036 {
2037 if (listSize == 0)
2038 break;
2039
2040 int entryRand = rand_r(&randstate) % listSize;
2041 int i, oid, err, offset;
2042 struct EMEntries* tmp;
2043 LBID_t lbid;
2044
2045 for (i = 0, tmp = head; i < entryRand; i++)
2046 tmp = tmp->next;
2047
2048 offset = rand_r(&randstate) % tmp->size;
2049 oid = tmp->OID;
2050
2051 err = emrange_si.lookup(oid, offset + tmp->FBO, lbid);
2052 #ifdef BRM_VERBOSE
2053 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
2054 " got lbid " << lbid << endl;
2055 cerr << " lbid should be " << tmp->LBIDstart + offset << endl;
2056 #endif
2057 CPPUNIT_ASSERT(err == 0);
2058 CPPUNIT_ASSERT((uint32_t)lbid == tmp->LBIDstart + offset);
2059 emrange_si.checkConsistency();
2060 break;
2061 }
2062
2063 case 5: //getHWM
2064 {
2065 if (listSize == 0)
2066 break;
2067
2068 int entryRand = rand_r(&randstate) % listSize;
2069 int i;
2070 struct EMEntries* tmp;
2071 uint32_t hwm;
2072
2073 for (i = 0, tmp = head; i < entryRand; i++)
2074 tmp = tmp->next;
2075
2076 hwm = emrange_si.getHWM(tmp->OID);
2077 #ifdef BRM_VERBOSE
2078 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
2079 << " BRM says it's " << hwm << endl;
2080 #endif
2081 CPPUNIT_ASSERT(hwm == tmp->HWM);
2082 emrange_si.checkConsistency();
2083 break;
2084 }
2085
2086 case 6: //setHWM
2087 {
2088 if (listSize == 0)
2089 break;
2090
2091 int entryRand = rand_r(&randstate) % listSize;
2092 int i, hwm, oid;
2093 struct EMEntries* tmp;
2094
2095 for (i = 0, tmp = head; i < entryRand; i++)
2096 tmp = tmp->next;
2097
2098 oid = tmp->OID;
2099 hwm = rand_r(&randstate) % (tmp->FBO + emrange_si.getExtentSize());
2100 emrange_si.setHWM(oid, hwm);
2101 emrange_si.confirmChanges();
2102
2103 for (tmp = head; tmp != NULL; tmp = tmp->next)
2104 if (tmp->OID == oid)
2105 tmp->HWM = hwm;
2106
2107 #ifdef BRM_VERBOSE
2108 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
2109 #endif
2110 emrange_si.checkConsistency();
2111 break;
2112 }
2113
2114 case 7: //getBulkInsertVars
2115 {
2116 if (listSize == 0)
2117 break;
2118
2119 HWM_t hwm;
2120 VER_t txnID;
2121 int entryRand = rand_r(&randstate) % listSize;
2122 int i, err, offset;
2123 EMEntries* tmp;
2124 LBID_t lbid;
2125
2126 for (i = 0, tmp = head; i < entryRand; i++)
2127 tmp = tmp->next;
2128
2129 offset = rand_r(&randstate) % tmp->size;
2130 lbid = tmp->LBIDstart + offset;
2131 err = emrange_si.getBulkInsertVars(lbid, hwm, txnID);
2132 CPPUNIT_ASSERT(err == 0);
2133 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
2134 CPPUNIT_ASSERT((uint32_t)txnID == tmp->txnID);
2135 break;
2136 }
2137
2138 case 8: //setBulkInsertVars
2139 {
2140 if (listSize == 0)
2141 break;
2142
2143 int entryRand = rand_r(&randstate) % listSize;
2144 int i, err, offset;
2145 EMEntries* tmp;
2146
2147 for (i = 0, tmp = head; i < entryRand; i++)
2148 tmp = tmp->next;
2149
2150 offset = rand_r(&randstate) % tmp->size;
2151 tmp->secondHWM = rand_r(&randstate) % MAXINT;
2152 tmp->txnID = rand_r(&randstate) % MAXINT;
2153 err = emrange_si.setBulkInsertVars(tmp->LBIDstart + offset,
2154 tmp->secondHWM, tmp->txnID);
2155 emrange_si.confirmChanges();
2156 CPPUNIT_ASSERT(err == 0);
2157 break;
2158 }
2159
2160 case 9: //setBulkInsertVars
2161 {
2162 if (listSize == 0)
2163 break;
2164
2165 int entryRand = rand_r(&randstate) % listSize;
2166 int i, err, offset;
2167 EMEntries* tmp;
2168
2169 for (i = 0, tmp = head; i < entryRand; i++)
2170 tmp = tmp->next;
2171
2172 offset = rand_r(&randstate) % tmp->size;
2173 tmp->secondHWM = rand_r(&randstate) % MAXINT;
2174 tmp->txnID = rand_r(&randstate) % MAXINT;
2175 err = emrange_si.setBulkInsertVars(tmp->LBIDstart + offset,
2176 tmp->secondHWM, tmp->txnID);
2177 emrange_si.confirmChanges();
2178 CPPUNIT_ASSERT(err == 0);
2179 break;
2180 }
2181
2182 case 10:
2183 {
2184 if (listSize == 0)
2185 break;
2186
2187 int entryRand = rand_r(&randstate) % listSize;
2188 int target = rand_r(&randstate) % 0x0FFFFFFF;
2189 int i, err, offset;
2190 OID_t oid;
2191 struct EMEntries* tmp;
2192 LBIDRange_v lbids;
2193
2194 for (i = 0, tmp = head; i < entryRand; i++)
2195 tmp = tmp->next;
2196
2197 offset = rand_r(&randstate) % tmp->size;
2198
2199 oid = tmp->OID;
2200 target = tmp->lo_val + 1;
2201 err = emrange_si.lookup(oid, target, lbids);
2202 pthread_mutex_lock(&mutex);
2203 opCount++;
2204 pthread_mutex_unlock(&mutex);
2205
2206 #ifdef BRM_VERBOSE
2207 cout << "Lookup OID/Range " << tmp->OID << " target " << target <<
2208 " start " << tmp->LBIDstart <<
2209 " len " << tmp->size <<
2210 " found " << lbids.size() << " ranges. " <<
2211 " extLen " << tmp->extCnt <<
2212 " partLo " << tmp->lo_val <<
2213 " partHi " << tmp->hi_val << endl;
2214 #endif
2215
2216 CPPUNIT_ASSERT((uint32_t)err == lbids.size() );
2217 CPPUNIT_ASSERT((uint32_t)tmp->extCnt == lbids.size() );
2218 CPPUNIT_ASSERT(tmp->lo_val < target && tmp->hi_val >= target);
2219
2220 emrange_si.checkConsistency();
2221 lbids.clear();
2222 break;
2223 }
2224
2225 default:
2226 break;
2227 }
2228 }
2229
2230 while (head != NULL)
2231 {
2232 tmp = head->next;
2233 delete head;
2234 head = tmp;
2235 }
2236
2237 #ifdef BRM_VERBOSE
2238
2239 for (int i = 0; i < numOps; i++)
2240 {
2241 cout << "Op " << i << " was called " << opRuns[i] << " times." << endl;
2242
2243 }
2244
2245 cerr << "thread " << threadNum << " exiting" << endl;
2246 #endif
2247
2248 return NULL;
2249 }
2250 #endif
2251
2252 class LongBRMTests : public CppUnit::TestFixture
2253 {
2254
2255 CPPUNIT_TEST_SUITE(LongBRMTests);
2256
2257 CPPUNIT_TEST(longEMTest_1);
2258 CPPUNIT_TEST(longEMTest_2);
2259 #ifdef PARTITIONING
2260 CPPUNIT_TEST(longEMRangeTest_1);
2261 #endif
2262 CPPUNIT_TEST(longBRMTest_1);
2263 CPPUNIT_TEST(longBRMTest_2);
2264
2265 CPPUNIT_TEST_SUITE_END();
2266
2267 private:
2268 public:
2269
longEMTest_1()2270 void longEMTest_1()
2271 {
2272 const int threadCount = 10;
2273 int i;
2274 pthread_t threads[threadCount];
2275
2276 cerr << endl << "Multithreaded, multiple instance ExtentMap test. "
2277 << endl;
2278
2279 threadStop = 0;
2280 pthread_mutex_init(&mutex, NULL);
2281
2282 for (i = 0; i < threadCount; i++)
2283 {
2284 if (pthread_create(&threads[i], NULL, EMRunner,
2285 reinterpret_cast<void*>(i + 1)) < 0)
2286 throw logic_error("Error creating threads for the ExtentMap test");
2287
2288 usleep(1000);
2289 }
2290
2291 sleep(60);
2292 threadStop = 1;
2293
2294 for (i = 0; i < threadCount; i++)
2295 {
2296 cerr << "Waiting for thread #" << i << endl;
2297 pthread_join(threads[i], NULL);
2298 }
2299 }
2300
longEMTest_2()2301 void longEMTest_2()
2302 {
2303 const int threadCount = 10;
2304 int i;
2305 pthread_t threads[threadCount];
2306
2307 cerr << endl << "Multithreaded, single instance ExtentMap test. "
2308 << endl;
2309
2310 threadStop = 0;
2311 pthread_mutex_init(&mutex, NULL);
2312
2313 for (i = 0; i < threadCount; i++)
2314 {
2315 if (pthread_create(&threads[i], NULL, EMRunner_si,
2316 reinterpret_cast<void*>(i + 1)) < 0)
2317 throw logic_error("Error creating threads for the ExtentMap test");
2318
2319 usleep(1000);
2320 }
2321
2322 sleep(60);
2323 threadStop = 1;
2324
2325 for (i = 0; i < threadCount; i++)
2326 {
2327 cerr << "Waiting for thread #" << i << endl;
2328 pthread_join(threads[i], NULL);
2329 }
2330 }
2331
longBRMTest_1()2332 void longBRMTest_1()
2333 {
2334 const int threadCount = 10;
2335 int i;
2336 pthread_t threads[threadCount];
2337
2338 cerr << endl << "Multithreaded, multiple instance BlockResolutionManager test. "
2339 << endl;
2340
2341 threadStop = 0;
2342 pthread_mutex_init(&mutex, NULL);
2343 opCount = 0;
2344
2345 for (i = 0; i < threadCount; i++)
2346 {
2347 if (pthread_create(&threads[i], NULL, BRMRunner_1,
2348 reinterpret_cast<void*>(i + 1)) < 0)
2349 throw logic_error("Error creating threads for the BlockResolutionManager test");
2350
2351 usleep(1000);
2352 }
2353
2354 sleep(60);
2355 threadStop = 1;
2356
2357 for (i = 0; i < threadCount; i++)
2358 {
2359 cerr << "Waiting for thread #" << i << endl;
2360 pthread_join(threads[i], NULL);
2361 }
2362
2363 cerr << "opCount = " << opCount << endl;
2364 }
2365
longBRMTest_2()2366 void longBRMTest_2()
2367 {
2368 const int threadCount = 10;
2369 int i;
2370 pthread_t threads[threadCount];
2371
2372 cerr << endl << "Multithreaded, single instance BlockResolutionManager test. "
2373 << endl;
2374
2375 threadStop = 0;
2376 pthread_mutex_init(&mutex, NULL);
2377 opCount = 0;
2378
2379 for (i = 0; i < threadCount; i++)
2380 {
2381 if (pthread_create(&threads[i], NULL, BRMRunner_si,
2382 reinterpret_cast<void*>(i + 1)) < 0)
2383 throw logic_error("Error creating threads for the BlockResolutionManager test");
2384
2385 usleep(1000);
2386 }
2387
2388 sleep(60);
2389 threadStop = 1;
2390
2391 for (i = 0; i < threadCount; i++)
2392 {
2393 cerr << "Waiting for thread #" << i << endl;
2394 pthread_join(threads[i], NULL);
2395 }
2396
2397 cerr << "opCount = " << opCount << endl;
2398 }
2399
2400 #ifdef PARTITIONING
longEMRangeTest_1()2401 void longEMRangeTest_1()
2402 {
2403 const int threadCount = 10;
2404 int i;
2405 pthread_t threads[threadCount];
2406
2407 cerr << endl << "Multithreaded, single instance ExtentMap(Range) test." << endl;
2408
2409 threadStop = 0;
2410 pthread_mutex_init(&mutex, NULL);
2411
2412 for (i = 0; i < threadCount; i++)
2413 {
2414 if (pthread_create(&threads[i], NULL, EMRangeRunner_si,
2415 reinterpret_cast<void*>(i + 1)) < 0)
2416 throw logic_error("Error creating threads for the ExtentMap test");
2417
2418 usleep(100);
2419 }
2420
2421 sleep(60);
2422 threadStop = 1;
2423
2424 for (i = 0; i < threadCount; i++)
2425 {
2426 cerr << "Waiting for thread #" << i << endl;
2427 pthread_join(threads[i], NULL);
2428 }
2429 }
2430 #endif
2431
2432 };
2433
2434 CPPUNIT_TEST_SUITE_REGISTRATION( LongBRMTests );
2435
2436 #include <cppunit/extensions/TestFactoryRegistry.h>
2437 #include <cppunit/ui/text/TestRunner.h>
2438
main(int argc,char ** argv)2439 int main( int argc, char** argv)
2440 {
2441 CppUnit::TextUi::TestRunner runner;
2442 CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
2443 runner.addTest( registry.makeTest() );
2444 idbdatafile::IDBPolicy::configIDBPolicy();
2445 bool wasSuccessful = runner.run( "", false );
2446 return (wasSuccessful ? 0 : 1);
2447 }
2448
2449
2450
2451