Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbBdbSAbsBtreeItr.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbBdbSAbsBtreeItr.cc,v 1.6 2004/12/08 09:26:54 gapon Exp $
00003 
00004 /// Implementation file for the CdbBdbSAbsBtreeItr class
00005 /**
00006   * @see CdbBdbSAbsBtreeItr
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #if !defined(OO_DDL_TRANSLATION)
00012 #include "CdbBdbShared/CdbBdbSAbsBtreeItr.hh"
00013 #endif // OO_DDL_TRANSLATION
00014 
00015 #include "CdbBdbShared/CdbBdbSAbsBtree.hh"
00016 
00017 #include <assert.h>
00018 
00019 template< class K,
00020           class FCP,
00021           class ORDER >
00022 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::CdbBdbSAbsBtreeItr( const CdbBdbSAbsBtree<K,FCP,ORDER>* theTreePtr ) :
00023     _myTreePtr(theTreePtr),
00024     _isValid(false),
00025     _hasEverBeenAdvanced(false)
00026 {
00027     assert( 0 != theTreePtr );
00028 }
00029 
00030 template< class K,
00031           class FCP,
00032           class ORDER >
00033 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::CdbBdbSAbsBtreeItr( const CdbBdbSAbsBtreeItr<K,FCP,ORDER>& theItr ) :
00034     _myTreePtr(theItr._myTreePtr),
00035     _isValid(theItr._isValid),
00036     _hasEverBeenAdvanced(theItr._hasEverBeenAdvanced),
00037     _node(theItr._node),
00038     _nodeValue(theItr._nodeValue),
00039     _currentElement(theItr._currentElement)
00040 { }
00041 
00042 template< class K,
00043           class FCP,
00044           class ORDER >
00045 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::~CdbBdbSAbsBtreeItr( )
00046 { }
00047 
00048 template< class K,
00049           class FCP,
00050           class ORDER >
00051 CdbStatus
00052 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::reset( )
00053 {
00054     _isValid             = false;
00055     _hasEverBeenAdvanced = false;
00056 
00057     return CdbStatus::Success;
00058 }
00059 
00060 template< class K,
00061           class FCP,
00062           class ORDER >
00063 bool
00064 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::backToParent( )
00065 {
00066     bool result = false;
00067     do {
00068 
00069       // Check if the current node has any parent the ROOT node does not).
00070 
00071         if( 0 == _nodeValue.parent ) break;
00072 
00073         d_ULong subjectNode = _node;
00074 
00075         _node      = _nodeValue.parent;
00076         _nodeValue = _myTreePtr->readNode( _node );
00077 
00078         for( int i = 0; i <= _nodeValue.n; ++i ) {
00079             if( subjectNode == _nodeValue.child[i] ) {
00080 
00081                 if( i == _nodeValue.n ) {
00082 
00083                   // The subject node was the last child in the list of the parent
00084                   // node. It means that there is no keys next to it. Therefore we shoudl
00085                   // proceed up to the parent of the parent.
00086 
00087                     result = backToParent( );
00088 
00089                 } else {
00090 
00091                   // Okay. The key right to the subject node's link is what we're
00092                   // loking for.
00093                   //
00094                   //        <input>
00095                   //           |
00096                   //           V
00097                   //  [L1]    [L2]    ...      [Ln]
00098                   //      [k1]    [k2]...[kn-1]
00099                   //                |
00100                   //                V
00101                   //             <output>
00102 
00103                     _currentElement = i;
00104 
00105                     result = true;
00106                 }
00107                 break;
00108             }
00109         }
00110 
00111     } while( false );
00112 
00113     return result;
00114 }
00115 
00116 template< class K,
00117           class FCP,
00118           class ORDER >
00119 bool
00120 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::next( )
00121 {
00122     if( _hasEverBeenAdvanced ) {
00123 
00124         ++_currentElement;  // Works well for both LEAF and non-LEAF nodes.
00125 
00126         if( _nodeValue.isLeaf ) {
00127 
00128           // The LEAF node
00129 
00130           // If we're past the end of the leaf's keys then we'll
00131           // try making one step back and keep searching through
00132           // the parent node.
00133 
00134             if( _currentElement >= _nodeValue.n ) {
00135 
00136                 if( ! backToParent( )) {
00137 
00138                   // Okay, we've finished. Put the iterator's state beyond
00139                   // the last key of the tree.
00140 
00141                     _isValid             = false;
00142                     _hasEverBeenAdvanced = false;
00143                 }
00144             }
00145 
00146         } else {
00147 
00148           // Not the LEAF node.
00149 
00150           // Then we propagate down to the child node, which is next
00151           // to the current key.
00152           //
00153           // NOTE: Remember that we've already incremented the index of the element
00154           //       above. So it refers to the appropriate child.
00155 
00156             _node      = _nodeValue.child[_currentElement];
00157             _nodeValue = _myTreePtr->readNode( _node );
00158 
00159           // Finally we go down to the key element at the leftmost sub-branch
00160           // of the tree growing from the above discovered child node.
00161           //
00162           // NOTE: The situation is almost (it's a sub-branch) exactly the same
00163           //       as when we just started iterating from the "root" node
00164           //       at the very first call to the "next".
00165 
00166             while( ! _nodeValue.isLeaf ) {
00167                 _node      = _nodeValue.child[0];
00168                 _nodeValue = _myTreePtr->readNode( _node );
00169             }
00170             _currentElement = 0;
00171         }
00172 
00173     } else {
00174 
00175       // The very first call to the "next"
00176 
00177       // Then we go down to the smaller key at the leftmost branch
00178       // of the tree.
00179 
00180         _node      = _myTreePtr->root( );
00181         _nodeValue = _myTreePtr->readNode( _node );
00182 
00183         while( ! _nodeValue.isLeaf ) {
00184             _node      = _nodeValue.child[0];
00185             _nodeValue = _myTreePtr->readNode( _node );
00186         }
00187 
00188       // The final check, which only makes sense for the ROOT node
00189       // if it's the only node in the tree (then ROOT also becomes
00190       // a LEAF node).
00191 
00192         if( _nodeValue.n > 0 ) {
00193 
00194             _isValid             = true;
00195             _hasEverBeenAdvanced = true;
00196 
00197             _currentElement = 0;
00198         }
00199     }
00200     return _isValid;
00201 }
00202 
00203 template< class K,
00204           class FCP,
00205           class ORDER >
00206 typename CdbBdbSAbsBtreeItr<K,FCP,ORDER>::ValueType
00207 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::value( )
00208 {
00209     assert( _isValid );     // Inproper use of the iterator if not advanced or beyond the end.
00210 
00211     return _nodeValue.key[_currentElement];
00212 }
00213 
00214 template< class K,
00215           class FCP,
00216           class ORDER >
00217 bool
00218 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::isValid( )
00219 {
00220     return _isValid;
00221 }
00222 
00223 template< class K,
00224           class FCP,
00225           class ORDER >
00226 typename CdbBdbSAbsBtreeItr<K,FCP,ORDER>::InterfaceType*
00227 CdbBdbSAbsBtreeItr<K,FCP,ORDER>::clone( ) const
00228 {
00229     return new CdbBdbSAbsBtreeItr<K,FCP,ORDER>( *this );
00230 }
00231 
00232 /////////////////
00233 // End Of File //
00234 /////////////////

Generated on Mon Dec 5 18:22:00 2005 for CDB by doxygen1.3-rc3