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

src/DomainMap/DomainMap.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Index/NDIndex.h"
00028 #include "Utility/RefCounted.h"
00029 #include "Field/LField.h"
00030 #include "FieldLayout/Vnode.h"
00031 #include "Profile/Profiler.h"
00032 
00033 
00034 
00035 
00036 
00038 
00039 // Insert a new key in the DomainMap.
00040 
00041 template < class Key , class T , class Touches, class Contains, class Split > 
00042 void
00043 DomainMap<Key,T,Touches,Contains,Split>::insert(const value_type& d,
00044                                                 bool noSplit)
00045 {
00046   TAU_TYPE_STRING(taustr, CT(*this) + " void (value_type)"); 
00047   TAU_PROFILE("DomainMap::insert()", taustr, TAU_DOMAINMAP);
00048 
00049   // Tell the tree top to insert.
00050   Root->insert(d, noSplit);
00051   // Increment the total size.
00052   Size += 1;
00053   // Update the pointer to the first element.
00054   update_leftmost();
00055 }
00056 
00058 
00059 // Recalculate the first element in the tree.
00060 
00061 template < class Key , class T , class Touches, class Contains, class Split > 
00062 void
00063 DomainMap<Key,T,Touches,Contains,Split>::update_leftmost()
00064 {
00065   TAU_TYPE_STRING(taustr, CT(*this) + " void ()"); 
00066   TAU_PROFILE("DomainMap::update_leftmost()", taustr, TAU_DOMAINMAP);
00067 
00068   Node *p=Root;
00069   // First dive all the way left.
00070   while ( p->Left )
00071     p = p->Left;
00072   // Look for the first element.
00073   typename Node::cont_type::iterator v;
00074   while ( (v=p->cont.begin()) == p->cont.end() ) {
00075     // First look right.
00076     if ( p->Right ) {
00077       // If it is there, go there and then all the way left.
00078       p = p->Right;
00079       while ( p->Left )
00080         p = p->Left;
00081     }
00082     else {
00083       // If there is no right, go up until you can go right more.
00084       Node *y = p->Parent;
00085       while (y && (p==y->Right)) {
00086         p = y;
00087         y = y->Parent;
00088       }
00089       p = y;
00090     }
00091   }
00092   if ( (Leftmost.p=p) != 0 ) 
00093     Leftmost.v = v;
00094 }
00095 
00097 
00098 // Find the range that touches a given T.
00099 
00100 template < class Key, class T , class Touches, class Contains, class Split > 
00101 pair<typename DomainMap<Key,T,Touches,Contains,Split>::touch_iterator,
00102      typename DomainMap<Key,T,Touches,Contains,Split>::touch_iterator>
00103 DomainMap<Key,T,Touches,Contains,Split>::touch_range(const Key& t) const
00104 { 
00105   TAU_TYPE_STRING(taustr, "pair<" + CT(*this)
00106     + "::touch_iterator, " + CT(*this) + "::touch_iterator > (Key) "); 
00107   TAU_PROFILE("DomainMap::iterator::op_pp()", taustr, TAU_DOMAINMAP);
00108 
00109   typedef pair<touch_iterator,touch_iterator> ret_pair;
00110   Node *p=Root;
00111 
00112   if ( p ) {
00113 
00114     // First dive left, checking touches.
00115     for ( Node* y=p->Left; y && Touches::test(t,y->MyDomain); y=y->Left )
00116       p = y;
00117 
00118     do {
00119       // Look for the first element that actually touches.
00120       for (typename Node::cont_type::iterator v=p->cont.begin();
00121            v!=p->cont.end(); ++v)
00122         if ( Touches::test(t,(*v).first) ) {
00123           // Found it!
00124           touch_iterator f;
00125           f.TouchThis = t;
00126           f.p = p;
00127           f.v = v;
00128           return pair<touch_iterator,touch_iterator>(f,touch_iterator());
00129         }
00130 
00131       // Didn't find one here. Move on.
00132       Node *y = p->Right;
00133       if ( y && Touches::test(t,y->MyDomain) ) {
00134         // If it is there, go there and then all the way left.
00135         p = y;
00136         for ( y=p->Left; y && Touches::test(t,y->MyDomain) ; y=y->Left ) 
00137           p = y;
00138       }
00139       else {
00140         // If there is no right, go up until you can go right more.
00141         for ( y = p->Parent; y && (p==y->Right); y = y->Parent )
00142           p = y;
00143         p = y;
00144       }
00145     } while (p);
00146   }
00147   // Didn't find any.
00148   return pair<touch_iterator,touch_iterator>(touch_iterator(),touch_iterator());
00149 }
00150 
00152 
00153 //
00154 // Copy ctor and assign do deep copies.
00155 //
00156 
00157 template < class Key, class T , class Touches, class Contains, class Split > 
00158 DomainMap<Key,T,Touches,Contains,Split>::
00159 DomainMap(const DomainMap<Key,T,Touches,Contains,Split>& a)
00160 : Root( new Node(a.Root->MyDomain) ), Size(0)
00161 {
00162   TAU_TYPE_STRING(taustr, "void (" + CT(a) + ")"); 
00163   TAU_PROFILE("DomainMap::DomainMap()", taustr, TAU_DOMAINMAP);
00164 
00165   for (iterator p=a.begin(); p!=a.end(); ++p)
00166     insert_noupdate( *p );
00167   update_leftmost();
00168 }
00169 
00170 template < class Key, class T , class Touches, class Contains, class Split > 
00171 void
00172 DomainMap<Key,T,Touches,Contains,Split>::
00173 operator=(const DomainMap<Key,T,Touches,Contains,Split>& a)
00174 {
00175   TAU_TYPE_STRING(taustr, "void (" + CT(a) + ")" ); 
00176   TAU_PROFILE("DomainMap::operator=()", taustr, TAU_DOMAINMAP);
00177 
00178   if ( this != &a ) {
00179     // Clean out the current contents.
00180     delete Root;
00181     Root = new Node( a.Root->MyDomain );
00182     Size = 0;
00183     // Add the new stuff.
00184     for (iterator p=a.begin(); p!=a.end(); ++p)
00185       insert_noupdate( *p );
00186     // Reset the pointer to the first one.
00187     update_leftmost();
00188   }
00189 }
00190 /***************************************************************************
00191  * $RCSfile: DomainMap.cpp,v $   $Author: adelmann $
00192  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:25 $
00193  * IPPL_VERSION_ID: $Id: DomainMap.cpp,v 1.1.1.1 2003/01/23 07:40:25 adelmann Exp $ 
00194  ***************************************************************************/

Generated on Fri Nov 2 01:25:55 2007 for IPPL by doxygen 1.3.5