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