00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #if !defined(OO_DDL_TRANSLATION)
00012 #include "CdbBdbShared/CdbBdbSPagedVarrayP.hh"
00013 #endif // OO_DDL_TRANSLATION
00014
00015 #include "BdbApplication/BdbDomain.hh"
00016
00017 #include <assert.h>
00018 using std::endl;
00019 using std::ostream;
00020
00021 template< typename E >
00022 CdbBdbSPagedVarrayP<E>::CdbBdbSPagedVarrayP( d_ULong theInitialSize,
00023 d_ULong theNumPerLeaf,
00024 d_ULong theNumPerDirectory ) :
00025 _numPerLeaf(theNumPerLeaf),
00026 _numPerDirectory(theNumPerDirectory),
00027 _numLevels(0),
00028 _size(theInitialSize),
00029 _leafNode(0),
00030 _directoryNode(0)
00031 {
00032
00033
00034
00035 if( ! _numPerLeaf ) _numPerLeaf = defaultNumPerLeaf( );
00036 if( ! _numPerDirectory ) _numPerDirectory = defaultNumPerDirectory( );
00037
00038
00039
00040 _numLevels = calculateNumLevels( theInitialSize );
00041 if( _numLevels ) {
00042 _directoryNode = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( _numLevels );
00043 _directoryNode->resize( theInitialSize,
00044 _numPerLeaf,
00045 _numPerDirectory );
00046 } else {
00047 _leafNode = new( ooThis( )) CdbBdbSLeafNodeP<E>( theInitialSize );
00048 }
00049 }
00050
00051 template< typename E >
00052 CdbBdbSPagedVarrayP<E>::~CdbBdbSPagedVarrayP( )
00053 {
00054
00055
00056 if( ! BdbIsNull( _leafNode )) BdbDelete( _leafNode );
00057 if( ! BdbIsNull( _directoryNode )) BdbDelete( _directoryNode );
00058 }
00059
00060 template< typename E >
00061 d_ULong
00062 CdbBdbSPagedVarrayP<E>::size( ) const
00063 {
00064 return _size;
00065 }
00066
00067 template< typename E >
00068 BdbStatus
00069 CdbBdbSPagedVarrayP<E>::resize( d_ULong theNewSize )
00070 {
00071 if( theNewSize == _size ) return BdbcSuccess;
00072
00073 ooUpdate( );
00074
00075 BdbStatus result = BdbcError;
00076 {
00077 d_ULong newNumLevels = calculateNumLevels( theNewSize );
00078
00079 if( theNewSize < _size ) {
00080 if( _numLevels == 0 ) {
00081 result = _leafNode->resize( theNewSize,
00082 _numPerLeaf,
00083 _numPerDirectory );
00084 } else {
00085 result = _directoryNode->resize( theNewSize,
00086 _numPerLeaf,
00087 _numPerDirectory );
00088 if( BdbcSuccess == result ) {
00089
00090 if( newNumLevels == _numLevels ) {
00091
00092
00093
00094
00095 ;
00096
00097 } else {
00098
00099
00100
00101
00102
00103 BdbRef(CdbBdbSNodeP<E>) prevNode = _directoryNode;
00104 BdbRef(CdbBdbSNodeP<E>) node = ((const BdbRef(CdbBdbSDirectoryNodeP<E>)&) prevNode)->_nodes[0];
00105
00106 for( d_ULong i = 1; i < _numLevels - newNumLevels; ++i ) {
00107 prevNode = node;
00108 node = ((const BdbRef(CdbBdbSDirectoryNodeP<E>)&) prevNode)->_nodes[0];
00109 }
00110
00111
00112
00113
00114 ((const BdbRef(CdbBdbSDirectoryNodeP<E>)&) prevNode)->_nodes[0] = 0;
00115 BdbDelete( _directoryNode );
00116 _directoryNode = 0;
00117
00118
00119
00120 if( newNumLevels ) _directoryNode = (const BdbRef(CdbBdbSDirectoryNodeP<E>)&) node;
00121 else _leafNode = (const BdbRef(CdbBdbSLeafNodeP<E>)&) node;
00122 }
00123 }
00124 }
00125
00126 } else {
00127
00128 if( newNumLevels == 0 ) {
00129 result = _leafNode->resize( theNewSize,
00130 _numPerLeaf,
00131 _numPerDirectory );
00132 } else {
00133
00134 if( newNumLevels == _numLevels ) {
00135 result = _directoryNode->resize( theNewSize,
00136 _numPerLeaf,
00137 _numPerDirectory );
00138 } else {
00139
00140
00141
00142
00143
00144 BdbRef(CdbBdbSDirectoryNodeP<E>) newDirectoryNode = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( newNumLevels );
00145 if( _numLevels ) {
00146 result = newDirectoryNode->resize( theNewSize,
00147 _numPerLeaf,
00148 _numPerDirectory,
00149 _directoryNode );
00150 if( BdbcSuccess == result ) {
00151 _directoryNode = newDirectoryNode;
00152 }
00153 } else {
00154 result = newDirectoryNode->resize( theNewSize,
00155 _numPerLeaf,
00156 _numPerDirectory,
00157 _leafNode );
00158 if( BdbcSuccess == result ) {
00159 _leafNode = 0;
00160 _directoryNode = newDirectoryNode;
00161 }
00162 }
00163 }
00164 }
00165 }
00166 if( BdbcSuccess == result ) {
00167 _numLevels = newNumLevels;
00168 _size = theNewSize;
00169 }
00170 }
00171 return result;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 template< typename E >
00199 void
00200 CdbBdbSPagedVarrayP<E>::setElementAt( d_ULong theIndex,
00201 const E& value )
00202 {
00203 assert( theIndex < _size );
00204
00205 BdbRef( CdbBdbSNodeP<E> ) nodeRef;
00206 if( _numLevels ) nodeRef = _directoryNode;
00207 else nodeRef = _leafNode;
00208
00209 nodeRef->setElementAt( theIndex,
00210 value,
00211 _numPerLeaf,
00212 _numPerDirectory );
00213 }
00214
00215 template< typename E >
00216 E
00217 CdbBdbSPagedVarrayP<E>::elementAt( d_ULong theIndex ) const
00218 {
00219 assert( theIndex < _size );
00220
00221 BdbRef( CdbBdbSNodeP<E> ) nodeRef;
00222 if( _numLevels ) nodeRef = _directoryNode;
00223 else nodeRef = _leafNode;
00224
00225 return nodeRef->elementAt( theIndex,
00226 _numPerLeaf,
00227 _numPerDirectory );
00228 }
00229
00230 template< typename E >
00231 void
00232 CdbBdbSPagedVarrayP<E>::dump( ostream& o,
00233 bool dumpContentsFlag ) const
00234 {
00235 o << ooThis( ).sprint( ) << " : <PAGED V-ARRAY>" << endl
00236 << " numPerLeaf = " << _numPerLeaf << endl
00237 << " numPerDirectory = " << _numPerDirectory << endl
00238 << " numLevels = " << _numLevels << endl
00239 << " size = " << _size << endl
00240 << " leafNode = " << _leafNode.sprint( ) << endl
00241 << " directoryNode = " << _directoryNode.sprint( ) << endl
00242 << " ";
00243
00244 if( _numLevels ) _directoryNode->dump( 4, o, dumpContentsFlag );
00245 else _leafNode->dump ( 4, o, dumpContentsFlag );
00246 }
00247
00248 template< typename E >
00249 d_ULong
00250 CdbBdbSPagedVarrayP<E>::calculateNumLevels( d_ULong theSize ) const
00251 {
00252 if( theSize <= _numPerLeaf ) return 0;
00253
00254 d_ULong result = 0;
00255 {
00256 d_ULong numPerNode = _numPerLeaf;
00257 do {
00258 ++result;
00259 numPerNode = numPerNode * _numPerDirectory;
00260 } while(( theSize - 1 ) / numPerNode );
00261 }
00262 return result;
00263 }
00264
00265 template< typename E >
00266 d_ULong
00267 CdbBdbSPagedVarrayP<E>::defaultNumPerLeaf( ) const
00268 {
00269 ooHandle(ooFDObj) fdH;
00270 fdH = BdbApplicationOrDomain::activeInstance()->fd( );
00271
00272 assert( ! BdbIsNull( fdH ));
00273
00274
00275
00276
00277
00278
00279
00280 E e;
00281 d_ULong eSize = sizeof( e );
00282
00283
00284
00285 return ( fdH.pageSize( ) - 256 ) / eSize;
00286 }
00287
00288 template< typename E >
00289 d_ULong
00290 CdbBdbSPagedVarrayP<E>::defaultNumPerDirectory( ) const
00291 {
00292 ooHandle(ooFDObj) fdH;
00293 fdH = BdbApplicationOrDomain::activeInstance()->fd( );
00294
00295 assert( ! BdbIsNull( fdH ));
00296
00297
00298
00299
00300
00301
00302
00303 ooRef(CdbBdbSNodeP<E>) nH;
00304 d_ULong nSize = sizeof( nH );
00305
00306
00307
00308 return ( fdH.pageSize( ) - 256 ) / nSize;
00309 }
00310
00311
00312
00313