snl_fei_RaggedTable.hpp

00001 #ifndef _snl_fei_RaggedTable_hpp_
00002 #define _snl_fei_RaggedTable_hpp_
00003 
00004 /*--------------------------------------------------------------------*/
00005 /*    Copyright 2005 Sandia Corporation.                              */
00006 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00007 /*    non-exclusive license for use of this work by or on behalf      */
00008 /*    of the U.S. Government.  Export of this program may require     */
00009 /*    a license from the United States Government.                    */
00010 /*--------------------------------------------------------------------*/
00011 
00012 #include <fei_macros.hpp>
00013 
00014 #include <snl_fei_SetTraits_specialize.hpp>
00015 #include <snl_fei_MapTraits_specialize.hpp>
00016 
00017 #include <fei_IndexTable.hpp>
00018 #include <fei_Pool_alloc.hpp>
00019 
00020 namespace snl_fei {
00021 
00028 template<typename MAP_TYPE, typename SET_TYPE>
00029 class RaggedTable : public fei::IndexTable {
00030  public:
00032   RaggedTable(int firstKey,
00033         int lastKey);
00034 
00036   RaggedTable(const RaggedTable<MAP_TYPE,SET_TYPE>& src);
00037 
00038   virtual ~RaggedTable();
00039 
00041   typedef MAP_TYPE map_type;
00042 
00044   typedef SET_TYPE row_type;
00045 
00047   void addDiagonals(int numIndices,
00048         const int* indices);
00049 
00051   void addIndices(int row,
00052                   int numIndices,
00053                   const int* indices);
00054 
00056   void addIndices(int numRows,
00057                   const int* rows,
00058                   int numIndices,
00059                   const int* indices);
00060 
00062   MAP_TYPE& getMap();
00063 
00065   const MAP_TYPE& getMap() const;
00066 
00068   SET_TYPE* getRow(int row);
00069 
00072   typedef typename MAP_TYPE::iterator iterator;
00073 
00075   iterator begin();
00076 
00078   iterator end();
00079 
00081   bool equal(const RaggedTable<MAP_TYPE,SET_TYPE>& rhs, bool quiet=true) const;
00082 
00083  private:
00084   MAP_TYPE map_;
00085   fei_Pool_alloc<SET_TYPE> poolAllocatorSet_;
00086   SET_TYPE dummy;
00087 }; //class RaggedTable
00088 
00089 template<typename MAP_TYPE, typename SET_TYPE>
00090 inline RaggedTable<MAP_TYPE,SET_TYPE>::RaggedTable(int firstKey,
00091                                           int lastKey)
00092   : map_(),
00093   poolAllocatorSet_(),
00094   dummy()
00095 {
00096 }
00097 
00098 template<typename MAP_TYPE, typename SET_TYPE>
00099 inline RaggedTable<MAP_TYPE,SET_TYPE>::RaggedTable(const RaggedTable<MAP_TYPE,SET_TYPE>& src)
00100   : map_(src.map_),
00101     poolAllocatorSet_()
00102 {
00103 }
00104 
00105 template<typename MAP_TYPE, typename SET_TYPE>
00106 RaggedTable<MAP_TYPE,SET_TYPE>::~RaggedTable()
00107 {
00108   iterator it = begin();
00109   iterator it_end = end();
00110   for(; it!=it_end; ++it) {
00111     poolAllocatorSet_.destroy( it->second );
00112     poolAllocatorSet_.deallocate( it->second, 1 );
00113   }
00114 }
00115 
00116 template<typename MAP_TYPE, typename SET_TYPE>
00117 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addIndices(int row,
00118                                               int numIndices,
00119                                               const int* indices)
00120 {
00121   iterator m_end = map_.end();
00122   iterator m_iter = MapTraits<MAP_TYPE>::lower_bound(map_, row);
00123 
00124   SET_TYPE* mapped_indices = NULL;
00125 
00126   bool found_row = false;
00127   if (m_iter != m_end) {
00128     if ((*m_iter).first == row) {
00129       mapped_indices = (*m_iter).second;
00130       found_row = true;
00131     }
00132   }
00133 
00134   if (!found_row) {
00135     mapped_indices = poolAllocatorSet_.allocate(1);
00136     poolAllocatorSet_.construct(mapped_indices, dummy);
00137     typename MAP_TYPE::value_type val(row, mapped_indices);
00138     MapTraits<MAP_TYPE>::insert(map_, m_iter, val);
00139   }
00140 
00141   for(int i=0; i<numIndices; ++i) {
00142     SetTraits<SET_TYPE>::insert(mapped_indices, indices[i]);
00143   }
00144 }
00145 
00146 template<typename MAP_TYPE, typename SET_TYPE>
00147 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addIndices(int numRows,
00148                              const int* rows,
00149                              int numIndices,
00150                              const int* indices)
00151 {
00152   iterator m_end = map_.end();
00153   iterator m_iter;
00154   SET_TYPE* mapped_indices = NULL;
00155 
00156   for(int i=0; i<numRows; ++i) {
00157     int row = rows[i];
00158     m_iter = MapTraits<MAP_TYPE>::lower_bound(map_, row);
00159 
00160     bool found_row = false;
00161     if (m_iter != m_end) {
00162       const typename MAP_TYPE::value_type& m_pair = *m_iter;
00163       if (m_pair.first == row) {
00164         mapped_indices = m_pair.second;
00165         found_row = true;
00166       }
00167     }
00168 
00169     if (!found_row) {
00170       mapped_indices = poolAllocatorSet_.allocate(1);
00171       poolAllocatorSet_.construct(mapped_indices, dummy);
00172       typename MAP_TYPE::value_type val(row, mapped_indices);
00173       MapTraits<MAP_TYPE>::insert(map_, m_iter, val);
00174     }
00175 
00176     for(int j=0; j<numIndices; ++j) {
00177       SetTraits<SET_TYPE>::insert(mapped_indices, indices[j]);
00178     }
00179   }
00180 }
00181 
00182 template<typename MAP_TYPE, typename SET_TYPE>
00183 inline MAP_TYPE& RaggedTable<MAP_TYPE,SET_TYPE>::getMap()
00184 {
00185   return(map_);
00186 }
00187 
00188 template<typename MAP_TYPE, typename SET_TYPE>
00189 inline const MAP_TYPE& RaggedTable<MAP_TYPE,SET_TYPE>::getMap() const
00190 {
00191   return(map_);
00192 }
00193 
00194 template<typename MAP_TYPE, typename SET_TYPE>
00195 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::row_type*
00196 RaggedTable<MAP_TYPE,SET_TYPE>::getRow(int row)
00197 {
00198   iterator m_end = map_.end();
00199   iterator m_iter = map_.find(row);
00200   return( m_end == m_iter ? NULL : (*m_iter).second );
00201 }
00202 
00203 template<typename MAP_TYPE, typename SET_TYPE>
00204 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::iterator
00205 RaggedTable<MAP_TYPE,SET_TYPE>::begin()
00206 {
00207   return(map_.begin());
00208 }
00209 
00210 template<typename MAP_TYPE, typename SET_TYPE>
00211 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::iterator
00212 RaggedTable<MAP_TYPE,SET_TYPE>::end()
00213 {
00214   return(map_.end());
00215 }
00216 
00217 template<typename MAP_TYPE, typename SET_TYPE>
00218 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addDiagonals(int numIndices,
00219                                                 const int* indices)
00220 {
00221   for(int i=0; i<numIndices; ++i) {
00222     int ind = indices[i];
00223     addIndices(ind, 1, &ind);
00224   }
00225 }
00226 
00227 template<typename MAP_TYPE, typename SET_TYPE>
00228 bool RaggedTable<MAP_TYPE,SET_TYPE>::equal(const RaggedTable<MAP_TYPE,SET_TYPE>& rhs, bool quiet) const
00229 {
00230   if (map_.size() != rhs.getMap().size()) {
00231     if (!quiet) {
00232       FEI_COUT << "RaggedTable::equal sizes don't match." << FEI_ENDL;
00233     }
00234     return(false);
00235   }
00236 
00237   typename map_type::const_iterator
00238    m_iter = map_.begin(),
00239    m_end  = map_.end();
00240 
00241   typename map_type::const_iterator
00242    rhs_iter = rhs.getMap().begin(),
00243    rhs_end  = rhs.getMap().end();
00244 
00245   for(; m_iter != m_end; ++m_iter, ++rhs_iter) {
00246     if (rhs_iter->first != m_iter->first) {
00247       if (!quiet) {
00248         FEI_COUT << "RaggedTable::equal keys don't match." << FEI_ENDL;
00249       }
00250       return(false);
00251     }
00252 
00253     if (*(rhs_iter->second) != *(m_iter->second)) {
00254       if (!quiet) {
00255         FEI_COUT << "RaggedTable::equal row-values don't match." << FEI_ENDL;
00256       }
00257       return(false);
00258     }
00259   }
00260 
00261   return(true);
00262 }
00263 
00264 }//namespace snl_fei
00265 
00266 #endif
00267 

Generated on Tue Jul 13 09:27:46 2010 for FEI by  doxygen 1.4.7