![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbEvent/BdbGenericHdrP.cc
Go to the documentation of this file.00001 //-------------------------------------------------------------------------- 00002 // File and Version Information: 00003 // $Id: BdbGenericHdrP.cc,v 1.1 1999/04/17 15:08:05 quarrie Exp $ 00004 // 00005 // Description: 00006 // Class BdbGenericHdrP. Implementation file for generic header class. 00007 // 00008 // Environment: 00009 // Software developed for the BaBar Detector at the SLAC B-Factory. 00010 // 00011 // Author List: 00012 // David R. Quarrie Original Author 00013 // 00014 // Copyright Information: 00015 // Copyright (C) 1994, 1995 Lawrence Berkeley Laboratory 00016 // 00017 // History: 00018 // Ray F. Cowan 971217 Added binary search on ooTypeNumber and 00019 // linear search for secondary key. 00020 // Ray F. Cowan 980114 Use BdbPString objects for secondary key; 00021 // no longer add ooTypeN at front of key string. 00022 // Ray F. Cowan 980202 Fixed use of BdbPString in replace(); treat 00023 // secondary key null pointers as null strings. 00024 // 00025 //------------------------------------------------------------------------ 00026 00027 //----------------------- 00028 // This Class's Header -- 00029 //----------------------- 00030 #include "BdbEvent/BdbGenericHdrP.hh" 00031 00032 //------------- 00033 // C Headers -- 00034 //------------- 00035 extern "C" { 00036 #include <assert.h> 00037 #include <stddef.h> 00038 #include <string.h> 00039 } 00040 00041 //--------------- 00042 // C++ Headers -- 00043 //--------------- 00044 #include <iostream.h> 00045 00046 //------------------------------- 00047 // Collaborating Class Headers -- 00048 //------------------------------- 00049 #include "BdbEvent/BdbEventErrors.hh" 00050 #include "BdbUtil/BdbPString.hh" 00051 00052 //----------------------------------------------------------------------- 00053 // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- 00054 //----------------------------------------------------------------------- 00055 00056 static const char rcsid[] = "$Id: BdbGenericHdrP.cc,v 1.1 1999/04/17 15:08:05 quarrie Exp $"; 00057 00058 // ---------------------------------------- 00059 // -- Public Function Member Definitions -- 00060 // ---------------------------------------- 00061 00062 //---------------- 00063 // Constructors -- 00064 //---------------- 00065 00066 BdbGenericHdrP::BdbGenericHdrP( BdbHandle(BdbGenericHdrP)& theHeader ) 00067 { 00068 _name = theHeader->name( ); 00069 size_t size = theHeader->_data.size( ); 00070 _data.resize( size ); 00071 _keys.resize( size ); 00072 for ( size_t i = 0; i < size; i++ ) { 00073 _data[i] = theHeader->_data[i]; 00074 _keys[i] = theHeader->_keys[i]; 00075 } 00076 } 00077 00078 //--------------- 00079 // Destructors -- 00080 //--------------- 00081 00082 BdbGenericHdrP::~BdbGenericHdrP( ) 00083 { 00084 clear( ); 00085 } 00086 00087 //------------- 00088 // Selectors -- 00089 //------------- 00090 00091 const char* 00092 BdbGenericHdrP::name( ) const 00093 { 00094 return (const char*)_name; 00095 } 00096 00097 d_ULong 00098 BdbGenericHdrP::size( ) const 00099 { 00100 return _data.size( ); 00101 } 00102 00103 d_Boolean 00104 BdbGenericHdrP::isOwner( BdbHandle(BdbPersObj)& theOwner ) const 00105 { 00106 d_Boolean result = false; 00107 if ( theOwner == _owner( ) ) { 00108 result = true; 00109 } 00110 return result; 00111 } 00112 00113 BdbStatus 00114 BdbGenericHdrP::owner( BdbHandle(BdbPersObj)& theOwner ) const 00115 { 00116 BdbStatus result = BdbcError; 00117 theOwner = 0; 00118 if ( ! BdbIsNull( _owner( ) ) ) { 00119 theOwner = _owner( ); 00120 result = BdbcSuccess; 00121 } 00122 return result; 00123 } 00124 00125 BdbStatus 00126 BdbGenericHdrP::setOwner( BdbHandle(BdbPersObj)& theOwner ) 00127 { 00128 BdbStatus result = update( "BdbGenericHdrP::setOwner" ); 00129 set__owner( theOwner ); 00130 return result; 00131 } 00132 00133 //-------------- 00134 // Operations -- 00135 //-------------- 00136 00137 BdbStatus 00138 BdbGenericHdrP::add( const BdbRef(BdbPersObj)& theObj, d_ULong theIndex, 00139 const char* const theKeyString ) 00140 { 00141 // Starting at the rear, bump objects down one, then insert new object 00142 // at the indexed position. 00143 00144 BdbRef(BdbPersObj) item; 00145 BdbHandle(BdbPString) theKeyH = 0; // These will stay null unless the key 00146 BdbRef(BdbPString) theKey = 0; // is a non-null string to save time. 00147 BdbRef(BdbPString) itemKey; 00148 BdbRefAny theHint; 00149 00150 BdbStatus status = _data.update( ); 00151 if ( ! status ) { 00152 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00153 "BdbGenericHdrP::add", "_data.update( )" ); 00154 } 00155 assert( status ); 00156 status = _keys.update( ); 00157 if ( ! status ) { 00158 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00159 "BdbGenericHdrP::add", "_keys.update( )" ); 00160 } 00161 assert( status ); 00162 00163 int theSize = _data.size(); 00164 00165 // Create a new BdbPString object in same container as this tree header, 00166 // but only if the incoming char* string is not a null pointer (equal 00167 // to 0) and is not a null string (a non-null pointer pointing to a 00168 // zero-length char* string). 00169 00170 if( theKeyString != 0 ) { // Detect zero pointer. 00171 if( *theKeyString != '\0' ) { // Detect zero-length char* string. 00172 theHint = ooThis(); 00173 theKeyH = new( theHint ) BdbPString( theKeyString ); 00174 theKey = theKeyH; 00175 } 00176 } 00177 00178 // Now we have either a zero ooRefHandle or a non-zero one accessing a 00179 // non-zero length BdbPString. 00180 00181 if( theSize == 0 || theIndex == theSize ) { 00182 _data.extend( theObj ); 00183 _keys.extend( theKey ); 00184 } else { 00185 00186 int i = 0; 00187 int last = theSize - 1; 00188 00189 item = _data[last]; 00190 itemKey = _keys[last]; 00191 _data.extend( item ); 00192 _keys.extend( itemKey ); 00193 00194 // cast from d_ULong to int is necessary when i < 0 (eg., "-1 > 0" 00195 // is treated as "4294967295 >= 0" and returns true. 00196 if( theSize > 1 ) for( i = last - 1; i >= (int) theIndex; i-- ) { 00197 item = _data[i]; 00198 itemKey = _keys[i]; 00199 _data.set( i + 1, item ); 00200 _keys.set( i + 1, itemKey ); 00201 } 00202 00203 // Place the new item in the index'ed slot, along with its key. 00204 _data.set( theIndex, theObj ); 00205 _keys.set( theIndex, theKey ); 00206 } 00207 00208 return BdbcSuccess; 00209 } 00210 00211 BdbStatus 00212 BdbGenericHdrP::addItemKey( const BdbRef(BdbPersObj)& theObj, d_ULong theIndex, 00213 BdbRef(BdbPString)& theKey ) 00214 { 00215 // Starting at the rear, bump objects down one, then insert new object 00216 // at the indexed position. 00217 00218 BdbRef(BdbPersObj) item; 00219 BdbRef(BdbPString) itemKey; 00220 BdbRefAny theHint; 00221 00222 BdbStatus status = _data.update( ); 00223 if ( ! status ) { 00224 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00225 "BdbGenericHdrP::addItemKey", "_data.update( )" ); 00226 } 00227 assert( status ); 00228 status = _keys.update( ); 00229 if ( ! status ) { 00230 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00231 "BdbGenericHdrP::addItemKey", "_keys.update( )" ); 00232 } 00233 assert( status ); 00234 00235 int theSize = _data.size(); 00236 00237 if( theSize == 0 || theIndex == theSize ) { 00238 _data.extend( theObj ); 00239 _keys.extend( theKey ); 00240 } else { 00241 00242 int i = 0; 00243 int last = theSize - 1; 00244 00245 item = _data[last]; 00246 itemKey = _keys[last]; 00247 _data.extend( item ); 00248 _keys.extend( itemKey ); 00249 00250 // cast from d_ULong to int is necessary when i < 0 (eg., "-1 > 0" 00251 // is treated as "4294967295 >= 0" and returns true. 00252 if( theSize > 1 ) for( i = last - 1; i >= (int) theIndex; i-- ) { 00253 item = _data[i]; 00254 itemKey = _keys[i]; 00255 _data.set( i + 1, item ); 00256 _keys.set( i + 1, itemKey ); 00257 } 00258 00259 // Place the new item in the index'ed slot, along with its key. 00260 _data.set( theIndex, theObj ); 00261 _keys.set( theIndex, theKey ); 00262 } 00263 00264 return BdbcSuccess; 00265 } 00266 00267 BdbStatus 00268 BdbGenericHdrP::get( BdbRef(BdbPersObj)& theItem, 00269 ooTypeNumber theType, 00270 const char* const theKeyString ) const 00271 { 00272 BdbRef(BdbPersObj) anItem; 00273 BdbRef(BdbPString) aKey; 00274 BdbHandle(BdbPString) aKeyH; 00275 BdbStatus result = BdbcError; 00276 00277 int i = 0; 00278 int theSize = size(); 00279 if( theSize == 0 ) return result; 00280 00281 // Implement binary search followed by secondary key string match. 00282 int low = 0; 00283 int high = theSize - 1; 00284 00285 i = ( low + high ) / 2; // initial midpoint 00286 00287 for(;;) { 00288 item( anItem, i ); 00289 if( anItem.typeN() == theType ) { 00290 result = BdbcSuccess; 00291 break; 00292 } 00293 00294 if( i == high ) { 00295 return result; 00296 } 00297 00298 if( anItem.typeN() > theType ) { // back up halfway 00299 high = i; 00300 } else { // go forward halfway 00301 low = i; 00302 } 00303 00304 // reset index and test again 00305 if( ( i == low ) && ( high - low == 1 ) ) { 00306 i = high; 00307 } else { 00308 i = ( low + high ) / 2; 00309 } 00310 00311 } // End of for(;;) loop 00312 00313 // At this point a true result means we have matched the TypeN but 00314 // not necessarily the secondary key. Now do a linear search from 00315 // the current position back and forward of matching TypeN's. 00316 00317 // Store the key string as an BdbTString. This will create a BdbTString 00318 // object representing a zero-length string if either theKeyString is a 00319 // zero pointer, or if it is a valid pointer to a zero-length string. 00320 // Otherwise it creates a non-null BdbTString object. 00321 BdbTString theName = theKeyString; 00322 00323 // Reset success flag 00324 result = BdbcError; 00325 int start = i; 00326 00327 // Handle required for scoping object 00328 BdbHandle(BdbGenericHdrP) thisH; 00329 thisH = ooThis(); 00330 getKey( aKeyH, start ); // Use handle to allow * operation 00331 00332 // min and max ooVArray limits 00333 const int bottom = 0; 00334 const int top = theSize - 1; 00335 00336 // Search backward 00337 while( ( i >= bottom ) && ( anItem.typeN() == theType ) ) { 00338 if( aKeyH != 0 ) { // valid handle, can perform comparison 00339 if( theName == *aKeyH ) { 00340 theItem = anItem; 00341 result = BdbcSuccess; 00342 break; 00343 } 00344 } else { // zero handle implies null string 00345 if( theName == "" ) { // check for null only 00346 theItem = anItem; 00347 result = BdbcSuccess; 00348 break; 00349 } 00350 } 00351 i--; 00352 if( i < bottom ) break; 00353 item ( anItem, i ); 00354 getKey( aKeyH, i ); // Use handle to allow * operation 00355 } 00356 00357 i = ++start; 00358 if( i <= top ) { 00359 item ( anItem, i ); 00360 getKey( aKeyH, i ); // Use handle to allow * operation 00361 } 00362 00363 // Search forward 00364 if( !result ) while( ( i <= top ) && ( anItem.typeN() == theType ) ) { 00365 if( aKeyH != 0 ) { // valid handle, can perform comparison 00366 if( theName == *aKeyH ) { 00367 theItem = anItem; 00368 result = BdbcSuccess; 00369 break; 00370 } 00371 } else { // zero handle implies null string 00372 if( theName == "" ) { // check for null only 00373 theItem = anItem; 00374 result = BdbcSuccess; 00375 break; 00376 } 00377 } 00378 i++; 00379 if( i > top ) break; 00380 item ( anItem, i ); 00381 getKey( aKeyH, i ); // Use handle to allow * operation 00382 } 00383 00384 return result; 00385 } 00386 00387 BdbStatus 00388 BdbGenericHdrP::getItem( BdbRef(BdbPersObj)& theItem, 00389 d_ULong index ) const 00390 { 00391 BdbStatus result = BdbcError; 00392 00393 int theSize = size(); 00394 if( theSize == 0 ) return result; 00395 if( index > theSize - 1 ) return result; 00396 00397 result = item( theItem, index ); 00398 return result; 00399 } 00400 00401 BdbStatus 00402 BdbGenericHdrP::getKey( BdbHandle(BdbPString)& theKey, d_ULong theIndex ) const 00403 { 00404 d_Boolean result = BdbcSuccess; 00405 theKey = _keys[theIndex]; 00406 return result; 00407 } 00408 00409 BdbStatus 00410 BdbGenericHdrP::getKey( BdbRef(BdbPString)& theKey, d_ULong theIndex ) const 00411 { 00412 d_Boolean result = BdbcSuccess; 00413 theKey = _keys[theIndex]; 00414 return result; 00415 } 00416 00417 BdbStatus 00418 BdbGenericHdrP::item( BdbRef(BdbPersObj)& theItem, d_ULong theIndex ) const 00419 { 00420 BdbStatus result = BdbcSuccess; 00421 theItem = _data[theIndex]; 00422 return result; 00423 } 00424 00425 BdbStatus 00426 BdbGenericHdrP::put( BdbRef(BdbPersObj)& theObj, const char* const theKeyString ) 00427 { 00428 ooTypeNumber theType = theObj.typeN(); 00429 BdbRef(BdbPersObj) anItem( 0 ); 00430 BdbRef(BdbPString) aKey; 00431 BdbHandle(BdbPString) aKeyH; 00432 BdbRef(BdbPersObj) highItem( 0 ); 00433 00434 BdbStatus status = _data.update( ); 00435 if ( ! status ) { 00436 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00437 "BdbGenericHdrP::put", "_data.update( )" ); 00438 } 00439 assert( status ); 00440 status = _keys.update( ); 00441 if ( ! status ) { 00442 BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0, 00443 "BdbGenericHdrP::put", "_keys.update( )" ); 00444 } 00445 assert( status ); 00446 00447 int i = 0; 00448 int theSize = size( ); 00449 00450 // Perform binary sort on insertion 00451 int low = 0; 00452 int high = theSize - 1; 00453 i = ( low + high ) / 2; 00454 00455 // min and max ooVArray limits 00456 const int bottom = 0; 00457 const int top = theSize - 1; 00458 00459 // Store the key string as an BdbTString. This will create a BdbTString 00460 // object representing a zero-length string if either theKeyString is a 00461 // zero pointer, or if it is a valid pointer to a zero-length string. 00462 // Otherwise it creates a non-null BdbTString object. 00463 BdbTString theName = theKeyString; 00464 00465 if( theSize > 0 ) { 00466 for(;;) { 00467 item( anItem, i ); 00468 00469 if( anItem.typeN() == theType ) { 00470 00471 // Now search back/forward for key match, if any. If no match is 00472 // found, we add it; if a match is found, we assert an error. 00473 00474 int j = i; 00475 int start = j; // record start position for later upward search 00476 00477 getKey( aKeyH, j ); // Use handle to allow * operation 00478 00479 // Search backward 00480 while( ( j >= bottom ) && ( anItem.typeN() == theType ) ) { 00481 if( aKeyH != 0 ) { // valid handle, can perform comparison 00482 status = ( theName != *aKeyH ); 00483 } else { // zero handle implies null string 00484 status = ( theName != "" ); 00485 } 00486 if ( !status ) { 00487 BdbSignal( BdbcFatalError, BdbEventErrObjectCollision, 0, 00488 "BdbGenericHdrP::put", theObj.typeName(), 00489 theName.data(), name() ); 00490 } 00491 assert( status ); 00492 j--; 00493 if( j < bottom ) break; 00494 item ( anItem, j ); 00495 getKey( aKeyH, j ); // Use handle to allow * operation 00496 } 00497 00498 j = ++start; 00499 if( j <= top ) { 00500 item ( anItem, j ); 00501 getKey( aKeyH, j ); // Use handle to allow * operation 00502 } 00503 00504 // Search forward 00505 while( ( j <= top ) && ( anItem.typeN() == theType ) ) { 00506 if( aKeyH != 0 ) { // valid handle, can perform comparison 00507 status = ( theName != *aKeyH ); 00508 } else { // zero handle implies null string 00509 status = ( theName != "" ); 00510 } 00511 if ( !status ) { 00512 BdbSignal( BdbcFatalError, BdbEventErrObjectCollision, 0, 00513 "BdbGenericHdrP::put", theObj.typeName(), 00514 theName.data(), name() ); 00515 } 00516 assert( status ); 00517 j++; 00518 if( j > top ) break; 00519 item ( anItem, j ); 00520 getKey( aKeyH, j ); // Use handle to allow * operation 00521 } 00522 00523 // Item not in array: type number matched, but not secondary key, 00524 // so add it here 00525 add( theObj, i, theName ); 00526 break; 00527 } 00528 00529 if( i == high ) { 00530 // Item not in array: no type number match, so add it here 00531 if( anItem.typeN() > theType ) { 00532 add( theObj, i, theName ); 00533 } else { 00534 add( theObj, i+1, theName ); 00535 } 00536 break; 00537 } 00538 00539 if( anItem.typeN() > theType ) { 00540 // back up halfway 00541 high = i; 00542 } else { 00543 // advance halfway 00544 low = i; 00545 } 00546 00547 // reset index and test again 00548 if( ( i == low ) && ( high - low == 1 ) ) { 00549 i = high; 00550 } else { 00551 i = ( low + high ) / 2; 00552 } 00553 00554 } // end of for{;;} 00555 } // end of if( theSize > 0 ) 00556 else { // No elements yet: theSize is zero 00557 add( theObj, 0, theName ); 00558 } 00559 return BdbcSuccess; 00560 } 00561 00562 void 00563 BdbGenericHdrP::clear( d_Boolean destroyItems ) 00564 { 00565 BdbHandleAny theItem; 00566 BdbHandle(BdbPString) theKey; 00567 BdbStatus status = update( "BdbGenericHdrP:clear" ); 00568 d_ULong nKeys = _keys.size( ); 00569 d_ULong iKey; 00570 for ( iKey = 0; iKey < nKeys; iKey++ ) { 00571 theKey = _keys[iKey]; 00572 if ( ! BdbIsNull( theKey ) ) { 00573 BdbDelete( theKey ); 00574 _keys[iKey] = 0; 00575 if ( destroyItems ) { 00576 theItem = _data[iKey]; 00577 BdbDelete( theItem ); 00578 } 00579 _data[iKey] = 0; 00580 } 00581 } 00582 _keys.resize( 0 ); 00583 _data.resize( 0 ); 00584 } 00585 00586 void 00587 BdbGenericHdrP::clearAndDestroy( ) 00588 { 00589 clear( d_True ); 00590 } 00591 00592 // ------------------------------------------- 00593 // -- Protected Function Member Definitions -- 00594 // ------------------------------------------- 00595 00596 //---------------- 00597 // Constructors -- 00598 //---------------- 00599 00600 BdbGenericHdrP::BdbGenericHdrP( const char* const theName ) 00601 { 00602 _name = theName; 00603 } 00604 00605 BdbGenericHdrP::BdbGenericHdrP( BdbHandle(BdbPersObj)& theOwner, 00606 const char* const theName ) 00607 { 00608 _name = theName; 00609 set__owner( theOwner ); 00610 } 00611 00612 //-------------- 00613 // Operations -- 00614 //-------------- 00615 00616 BdbStatus 00617 BdbGenericHdrP::update( const char* const location ) 00618 { 00619 BdbStatus result = ooUpdate( ); 00620 if ( ! result ) { 00621 BdbSignal( BdbcFatalError, BdbEventErrObjUpdateFailed, 0, 00622 "BdbGenericHdrP::update", location ); 00623 } 00624 return result; 00625 } 00626
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002