CMS 3D CMS Logo

IgCollection.h

Go to the documentation of this file.
00001 #ifndef IGUANA_IG_FILE_IG_COLLECTION_H
00002 #define IGUANA_IG_FILE_IG_COLLECTION_H
00003 
00004 # ifdef PROJECT_NAME 
00005 #  include <Iguana/Framework/interface/IgLinearAlgebra.h>
00006 # else
00007 #  include <IgLinearAlgebra.h>
00008 # endif
00009 #include <cstring>
00010 #include <string>
00011 #include <cassert>
00012 #include <vector>
00013 #include <map>
00014 #include <iostream>
00015 #include <algorithm>
00016 
00017 enum AssociatedType
00018 {
00019   LEFT_ASSOCIATED = 1,
00020   RIGHT_ASSOCIATED = 2,
00021   BOTH_ASSOCIATED = 3
00022 };
00023 
00024 class IgRef
00025 {
00026 public:
00027   IgRef()
00028   {}
00029   
00030   IgRef(int collectionId, int objectId)
00031   : m_collectionId(collectionId), m_objectId(objectId)
00032   {}
00033   
00034   IgRef(const IgRef &ref)
00035   : m_collectionId(ref.collectionId()),
00036     m_objectId(ref.objectId())
00037   {}
00038   
00039   int collectionId(void) const
00040   {return m_collectionId;}
00041   
00042   int objectId(void) const
00043   {return m_objectId;}
00044   
00045   void set (int collectionId, int objectId)
00046   {
00047     m_collectionId = collectionId;
00048     m_objectId = objectId;
00049   }
00050 private:
00051   int m_collectionId;
00052   int m_objectId;
00053 };
00054 
00055 class IgAssociation
00056 {
00057 public:
00058   IgAssociation(const IgRef &a, const IgRef &b)
00059   :m_refA(a), m_refB(b)
00060   {}
00061   
00062   IgAssociation()
00063   {}
00064   
00065   const IgRef &first(void) const
00066   {return m_refA; };
00067   
00068   const IgRef &second(void) const
00069   {return m_refB; };
00070   
00071   void set (int cA, int oA, int cB, int oB)
00072   {
00073     m_refA.set(cA, oA);
00074     m_refB.set(cB, oB);
00075   }
00076 private:
00077   IgRef m_refA;
00078   IgRef m_refB;
00079 };
00080 
00081 enum ColumnType {
00082   INT_COLUMN = 0,           // int
00083   STRING_COLUMN,            // std::string
00084   DOUBLE_COLUMN,            // double
00085   VECTOR_2D,                // A 2vector of doubles
00086   VECTOR_3D,                // A 3vector of doubles
00087   VECTOR_4D,                // A 4vector of doubles
00088   NUMBER_OF_BASE_TYPES
00089 };
00090 
00091 // Helper class to generate associate a given type with its id. 
00092 template <class T>
00093 struct ColumnTypeHelper
00094 { 
00095   static ColumnType typeId (void)
00096   { 
00097       assert(false);
00098       return -1;
00099   }
00100 };
00101 
00102 template <>
00103 struct ColumnTypeHelper<int>
00104 {
00105   static ColumnType typeId(void)
00106   {
00107       return INT_COLUMN; 
00108   }
00109 };
00110 
00111 template <>
00112 struct ColumnTypeHelper<double>
00113 {
00114   static ColumnType typeId(void)
00115   {
00116       return DOUBLE_COLUMN;
00117   }
00118 };
00119 
00120 template <>
00121 struct ColumnTypeHelper<std::string>
00122 {
00123   static ColumnType typeId(void)
00124   {
00125       return STRING_COLUMN;
00126   }
00127 };
00128 
00129 template <>
00130 struct ColumnTypeHelper<IgV2d>
00131 {
00132   static ColumnType typeId(void)
00133   { return VECTOR_2D; }
00134 };
00135 
00136 template <>
00137 struct ColumnTypeHelper<IgV3d>
00138 {
00139   static ColumnType typeId(void)
00140   { return VECTOR_3D; }
00141 };
00142 
00143 template <>
00144 struct ColumnTypeHelper<IgV4d>
00145 {
00146   static ColumnType typeId(void)
00147   { return VECTOR_4D; }
00148 };
00149 
00150 class IgColumnHandle
00151 {
00152 public:
00153   IgColumnHandle (void *data, ColumnType type)
00154   :m_data(data), m_type(type)
00155   { }
00156   
00157   ColumnType type(void)
00158   { return m_type; }
00159   
00160   void *data(void) const
00161   { return m_data; }
00162 
00163   template <class T>
00164   T &get (int index)
00165   {
00166     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00167     return data[index];
00168   }
00169   
00170   int size(void)
00171   {
00172     switch (type())
00173     {
00174     case INT_COLUMN:
00175       return static_cast<std::vector<int> *>(m_data)->size();
00176       break;
00177     case STRING_COLUMN:
00178       return static_cast<std::vector<std::string> *>(m_data)->size();
00179       break;
00180     case DOUBLE_COLUMN:
00181       return static_cast<std::vector<double> *>(m_data)->size();
00182       break;
00183     case VECTOR_2D:
00184       return static_cast<std::vector<IgV2d> *>(m_data)->size();
00185       break;
00186     case VECTOR_3D:
00187       return static_cast<std::vector<IgV3d> *>(m_data)->size();
00188       break;
00189     case VECTOR_4D:
00190       return static_cast<std::vector<IgV4d> *>(m_data)->size();
00191       break;
00192     default:
00193       assert (false);
00194     }        
00195   }
00196   
00197   void stream(std::ostream &stream, int position)
00198   {
00199     switch (type())
00200     {
00201       case INT_COLUMN:
00202         stream << get<int>(position);
00203         break;
00204       case STRING_COLUMN:
00205         stream << "\""<< get<std::string>(position) << "\"";
00206         break;
00207       case DOUBLE_COLUMN:
00208         stream << get<double>(position);
00209         break;
00210       case VECTOR_2D:
00211         {
00212           IgV2d &v = get<IgV2d>(position);
00213           stream << "("<< v.x() << ", " << v.y() << ")";
00214         }
00215         break;
00216       case VECTOR_3D:
00217         {
00218           IgV3d &v = get<IgV3d>(position);
00219           stream << "("<< v.x() << ", " << v.y() << ", " << v.z() << ")";
00220         }
00221         break;
00222       case VECTOR_4D:
00223         {
00224           IgV4d &v = get<IgV4d>(position);
00225           stream << "("<< v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ")";
00226         }
00227         break;
00228       default:
00229         assert (false);
00230     }
00231   }
00232 
00233   void streamType (std::ostream &stream)
00234   {
00235     switch (type())
00236     {
00237       case INT_COLUMN:
00238         stream << "int";
00239         break;
00240       case STRING_COLUMN:
00241         stream << "string";
00242         break;
00243       case DOUBLE_COLUMN:
00244         stream << "double";
00245         break;
00246       case VECTOR_2D:
00247         stream << "v2d";
00248         break;
00249       case VECTOR_3D:
00250         stream << "v3d";
00251         break;
00252       case VECTOR_4D:
00253         stream << "v4d";
00254         break;
00255       default:
00256         assert (false);
00257     }
00258   }
00259   
00260   void extend ()
00261   {
00262     switch (m_type)
00263     {
00264       case INT_COLUMN:
00265         return doExtend<int>();
00266         break;
00267       case DOUBLE_COLUMN:
00268         return doExtend<double>();
00269         break;
00270       case STRING_COLUMN:
00271         return doExtend<std::string>();
00272         break;
00273       case VECTOR_2D:
00274         return doExtend<IgV2d>();
00275         break;                
00276       case VECTOR_3D:         
00277         return doExtend<IgV3d>();
00278         break;                
00279       case VECTOR_4D:         
00280         return doExtend<IgV4d>();
00281         break;
00282       default:
00283         assert(false);
00284         break;
00285     }
00286   }
00287 
00288   void resize (unsigned int newSize)
00289   {
00290     switch (m_type)
00291     {
00292       case INT_COLUMN:
00293         return doResize<int>(newSize);
00294         break;
00295       case DOUBLE_COLUMN:
00296         return doResize<double>(newSize);
00297         break;
00298       case STRING_COLUMN:
00299         return doResize<std::string>(newSize);
00300         break;
00301       case VECTOR_2D:
00302         return doResize<IgV2d>(newSize);
00303         break;                
00304       case VECTOR_3D:         
00305         return doResize<IgV3d>(newSize);
00306         break;                
00307       case VECTOR_4D:         
00308         return doResize<IgV4d>(newSize);
00309         break;
00310       default:
00311         assert(false);
00312         break;
00313     }
00314   }
00315   
00316   void reserve(unsigned int size)
00317   {
00318     switch (m_type)
00319     {
00320       case INT_COLUMN:
00321         doReserve<int>(size);
00322         break;
00323       case DOUBLE_COLUMN:
00324         doReserve<double>(size);
00325         break;
00326       case STRING_COLUMN:
00327         doReserve<std::string>(size);
00328         break;
00329       case VECTOR_2D:
00330         doReserve<IgV2d>(size);
00331         break;                
00332       case VECTOR_3D:         
00333         doReserve<IgV3d>(size);
00334         break;                
00335       case VECTOR_4D:         
00336         doReserve<IgV4d>(size);
00337         break;
00338       default:
00339         assert(false);
00340         break;
00341     }
00342   }
00343   
00344   void compress()
00345   {
00346     switch (m_type)
00347     {
00348       case INT_COLUMN:
00349         doCompress<int>();
00350         break;
00351       case DOUBLE_COLUMN:
00352         doCompress<double>();
00353         break;
00354       case STRING_COLUMN:
00355         doCompress<std::string>();
00356         break;
00357       case VECTOR_2D:
00358         doCompress<IgV2d>();
00359         break;                
00360       case VECTOR_3D:         
00361         doCompress<IgV3d>();
00362         break;                
00363       case VECTOR_4D:         
00364         doCompress<IgV4d>();
00365         break;
00366       default:
00367         assert(false);
00368         break;
00369     }
00370   }
00371 
00372   void clear()
00373   {
00374     switch (m_type)
00375     {
00376       case INT_COLUMN:
00377         doClear<int>();
00378         break;
00379       case DOUBLE_COLUMN:
00380         doClear<double>();
00381         break;
00382       case STRING_COLUMN:
00383         doClear<std::string>();
00384         break;
00385       case VECTOR_2D:
00386         doClear<IgV2d>();
00387         break;                
00388       case VECTOR_3D:         
00389         doClear<IgV3d>();
00390         break;                
00391       case VECTOR_4D:         
00392         doClear<IgV4d>();
00393         break;
00394       default:
00395         assert(false);
00396         break;
00397     }
00398   }
00399 
00400   template <class T>
00401   void doExtend()
00402   {
00403     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00404     data.resize(data.size()+1);
00405   }
00406   
00407   template <class T>
00408   void doReserve(unsigned int size)
00409   {
00410     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00411     data.reserve(size);
00412   }
00413   
00414   template <class T>
00415   void doCompress(void)
00416   {
00417     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00418     data.reserve(data.size());
00419   }
00420   
00421   template <class T>
00422   void doClear(void)
00423   {
00424     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00425     data.clear();
00426   }
00427 
00428   template <class T>
00429   void doResize(int newSize)
00430   {
00431     std::vector<T> &data = *(static_cast<std::vector<T> *>(m_data));
00432         data.resize(newSize);
00433   }
00434   
00435   void destroy()
00436   {
00437     switch (m_type)
00438     {
00439       case INT_COLUMN:
00440         doDestroy<int>();
00441         break;
00442       case DOUBLE_COLUMN:
00443         doDestroy<double>();
00444         break;
00445       case STRING_COLUMN:
00446         doDestroy<std::string>();
00447         break;
00448       case VECTOR_2D:
00449         doDestroy<IgV2d>();
00450         break;                
00451       case VECTOR_3D:         
00452         doDestroy<IgV3d>();
00453         break;                
00454       case VECTOR_4D:         
00455         doDestroy<IgV4d>();
00456         break;
00457       default:
00458         assert(false);
00459         break;
00460     }
00461   }
00462 
00463   
00464 private:
00465   template <class T>
00466   void doDestroy(void)
00467   {
00468     std::vector<T> *data = static_cast<std::vector<T> *>(m_data);
00469     data->clear();
00470     delete data;
00471   }
00472   
00473 
00474   void *m_data;
00475   ColumnType m_type;
00476 };
00477 
00478 class IgProperty
00479 {
00480 public:
00481   IgProperty(IgColumnHandle &handle)
00482   : m_handle(handle)
00483   { }
00484   
00485   IgColumnHandle &handle(void)
00486   { return m_handle; }
00487   
00488 private:
00489   IgColumnHandle m_handle;
00490 };
00491 
00492 class IgCollectionItem;
00493 class IgCollection;
00494 
00495 class IgCollectionIterator
00496 {
00497 public:
00498   IgCollectionIterator(IgCollection *collection, int rowPosition)
00499   :m_collection(collection), m_rowPosition(rowPosition)
00500   { }
00501   
00502   IgCollectionItem operator*();
00503 
00504   void operator++(int /*dummy*/)
00505   {
00506     m_rowPosition++;
00507   }
00508   
00509   void operator--(int /*dummy*/)
00510   {
00511     m_rowPosition--;
00512   }
00513   
00514   void operator+=(int delta)
00515   {
00516     m_rowPosition += delta;
00517   }
00518   
00519   void operator-=(int delta)
00520   {
00521     m_rowPosition -= delta;
00522   }
00523   
00524   void operator=(int value)
00525   {
00526     m_rowPosition = value;
00527   }
00528 
00529   bool operator==(const IgCollectionIterator& other)
00530   {
00531     return m_rowPosition == other.m_rowPosition;
00532   }
00533 
00534   bool operator!=(const IgCollectionIterator& other)
00535   {
00536     return m_rowPosition != other.m_rowPosition;
00537   }
00538   
00539   IgCollectionIterator operator+(int value)
00540   {
00541     return IgCollectionIterator(m_collection, m_rowPosition + value);
00542   }
00543   
00544 private:
00545   IgCollection *m_collection;
00546   int m_rowPosition;
00547 };
00548 
00552 struct IgSchemaError
00553 {
00554 };
00555 
00556 // TODO: for the time being the collection ID is defined by the creation order.
00557 //       This is actually bad in the case we are merging files and should be 
00558 //       somehow replaced by some hash (maybe using some combination of 
00559 //       column name-column type for all the columns).
00560 class IgCollection
00561 {
00562 public:
00563   typedef std::vector<std::string> Labels;
00564   typedef std::pair<const char *, IgColumnHandle> LabelColumn;
00565   typedef std::pair<ColumnType, IgColumnHandle> TypeColumn;
00566   typedef std::vector<IgProperty> Properties;
00567   
00568   template <class T>
00569   IgProperty &addProperty(const char *label, T defaultValue)
00570   {
00571     Labels::iterator l;
00572     if (doHasProperty(label, &l))
00573     {
00574       return m_properties[std::distance(m_labels.begin(), l)]; 
00575     }
00576     
00577     m_labels.push_back(label);
00578     std::vector<T> *columnData = new std::vector<T>;
00579     IgColumnHandle handle((void *)columnData, ColumnTypeHelper<T>::typeId ());
00580     m_columnLabelsIndex.push_back(LabelColumn(m_labels.back().c_str(), handle));
00581     m_columnTypesIndex[ColumnTypeHelper<T>::typeId()].push_back(handle);
00582     m_properties.push_back (IgProperty(handle));
00583     return m_properties.back();
00584   }
00585   
00586   IgCollectionIterator begin(void);
00587   IgCollectionIterator end(void);
00588 
00589   IgProperty &getProperty (const char *label)
00590   {
00591     Labels::iterator l;
00592     if (!doHasProperty (label, &l))
00593     {
00594       throw IgSchemaError();
00595     } 
00596 
00597     return m_properties[std::distance(m_labels.begin(), l)]; 
00598   }
00599 
00600   bool hasProperty (const char *label)
00601   {
00602     return doHasProperty(label);
00603   }
00604 
00605   int size(void)
00606   {
00607     // We consider the size of the first column as the size of the whole
00608     // collection.
00609     return m_rowCount;
00610   }
00611   
00612   IgColumnHandle &getHandleByLabel(const char *label)
00613   {
00614     for (std::vector<LabelColumn>::iterator i = m_columnLabelsIndex.begin();
00615          i != m_columnLabelsIndex.end();
00616          i++)
00617     {
00618       if (strcmp(i->first, label) == 0)
00619       {
00620         return i->second;
00621       }
00622     }
00623     std::cout << "IgColumnHandle::getHandleByLabel " << label << " from " << m_name << std::endl;
00624     
00625     assert(false && "Column not found. Did you create it?");
00626   }
00627 
00628   IgColumnHandle &getHandleByPosition(const unsigned int position)
00629   {
00630     return m_properties[position].handle();
00631   }
00632 
00633   void reserve(unsigned int size)
00634   {
00635     for (Properties::iterator i = m_properties.begin();
00636          i != m_properties.end();
00637          i++)
00638     {
00639       i->handle().reserve(size);
00640     }
00641   }
00642 
00643   void resize(unsigned int size)
00644   {
00645     for (Properties::iterator i = m_properties.begin();
00646          i != m_properties.end();
00647          i++)
00648     {
00649       i->handle().resize(size);
00650     }
00651     m_rowCount = size;
00652   }
00653   
00654   void compress(void)
00655   {
00656     for (Properties::iterator i = m_properties.begin();
00657          i != m_properties.end();
00658          i++)
00659     {
00660       i->handle().compress();
00661     }    
00662   }
00663   
00664   void clear(void)
00665   {
00666     for (Properties::iterator i = m_properties.begin ();
00667          i != m_properties.end();
00668          i++)
00669     {
00670       i->handle().clear();
00671     }
00672   }
00673 
00674   Properties &properties(void)
00675   {
00676     return m_properties;
00677   }
00678 
00679   IgCollectionItem create();
00680   const char *name(void) const
00681   {
00682     return m_name.c_str();
00683   }
00684   
00685   int id(void) const
00686   {
00687     return m_id;
00688   }
00689   
00690   std::vector<LabelColumn> &columnLabels(void)
00691   { return m_columnLabelsIndex; };
00692   
00693 protected:
00694   IgCollection (const char *name, int id)
00695   : m_name (name), m_id(id), m_rowCount(0)
00696   { }
00697   
00698   ~IgCollection ()
00699   {
00700   }
00701   
00702   friend class IgDataStorage;
00703 
00704 private:
00705   bool doHasProperty (const char *label, Labels::iterator *i = 0)
00706   {
00707     Labels::iterator l = std::find(m_labels.begin(), m_labels.end(), label);
00708     if (i != 0)
00709       *i = l;
00710     return l != m_labels.end();
00711   }
00712 
00713   typedef std::vector<LabelColumn> ColumnLabels;
00714   typedef std::vector<TypeColumn> ColumnTypes;
00715   typedef std::map<ColumnType, std::vector<IgColumnHandle> > ColumnTypeIndex;
00716   std::vector<std::string>  m_labels;
00717   std::vector<int>          m_primaryKeys;
00718   std::vector<LabelColumn>  m_columnLabelsIndex;
00719   Properties   m_properties;
00720   ColumnTypeIndex m_columnTypesIndex;
00721   std::string m_name;
00722   int m_id;
00723   int m_rowCount;
00724 };
00725 
00726 
00727 template <class T>
00728 struct IgStorageGetterTrait
00729 { typedef T storage_type; };
00730 
00731 template <>
00732 struct IgStorageGetterTrait<char *>
00733 { typedef std::string storage_type; };
00734 
00735 template <>
00736 struct IgStorageGetterTrait<const char *>
00737 { typedef std::string storage_type; };
00738 
00739 class IgCollectionItem
00740 {
00741 public:
00742   IgCollectionItem (IgCollection *collection, int position)
00743   :m_collection(collection), m_position(position), m_propertyPosition(0)
00744   {
00745   }
00746 
00747   int currentColumn()
00748   {
00749     return m_propertyPosition;
00750   }
00751 
00752   int currentRow()
00753   {
00754     return m_position;
00755   }
00756 
00757   IgCollectionItem &nextColumn(void)
00758   {
00759         m_propertyPosition++;
00760         return *this;
00761   }
00762   
00763   IgCollectionItem &moveToColumn(const IgColumnHandle &handle)
00764   {
00765     void *data = handle.data();
00766     int j = 0;
00767     for (IgCollection::Properties::iterator i = m_collection->properties().begin();
00768          (i != m_collection->properties().end()) && (i->handle().data() != data);
00769          i++)
00770     { j++; }
00771     m_propertyPosition = j;
00772     return *this;
00773   }
00774 
00775   IgCollectionItem &operator*(void)
00776   {
00777         return *this;
00778   }
00779 
00780   template <class T>
00781   T &current(void)
00782   {
00783         return currentHandle().get<T>(m_position);
00784   }
00785   
00786   IgCollectionItem &operator[](IgProperty &property)
00787   {
00788     return this->moveToColumn(property.handle());
00789   }
00790 
00791   IgCollectionItem &operator[](const char *label)
00792   {
00793     assert(m_collection && "Collection ptr is 0");
00794     return this->moveToColumn(m_collection->getHandleByLabel(label));
00795   }
00796 
00797   template <class T>
00798   IgCollectionItem &operator=(T value)
00799   {
00800     currentHandle().get<typename IgStorageGetterTrait<T>::storage_type>(m_position) = value;
00801     return *this;
00802   }
00803 
00804   IgCollectionItem &operator=(const std::string &value)
00805   {
00806     currentHandle().get<std::string>(m_position) = value;
00807     return *this;
00808   }
00809   
00810   IgCollectionItem &operator=(const char *value)
00811   {
00812     currentHandle().get<std::string>(m_position) = value;
00813     return *this;
00814   }
00815   
00816   template <class T, class A, template <typename, typename> class C>
00817   IgCollectionItem &operator=(C<T,A> container)
00818   {
00819     ContainerTraits<C,T,A>::put(m_collection, 
00820                                 m_propertyPosition, 
00821                                 m_position, 
00822                                 container);
00823     return *this;
00824   }
00825     
00826   template <class T>
00827   IgCollectionItem &operator,(T value)
00828   {
00829     m_propertyPosition++;
00830     currentHandle().get<T>(m_position) = value;
00831     return *this;
00832   }
00833 
00834   IgCollectionItem &operator,(const char *value)
00835   {
00836     m_propertyPosition++;
00837     currentHandle().get<std::string>(m_position) = value;
00838     return *this;
00839   }
00840 
00841   IgCollectionItem &operator,(const std::string &value)
00842   {
00843     m_propertyPosition++;
00844     currentHandle().get<std::string>(m_position) = value;
00845     return *this;
00846   }
00847   
00848   
00849   template <class T, class A, template <typename, typename> class C>
00850   IgCollectionItem &operator,(C<T, A> container)
00851   {
00852     m_propertyPosition=ContainerTraits<C,T,A>::put(m_collection, 
00853                                 m_propertyPosition, 
00854                                 m_position, 
00855                                 container);
00856     return *this;
00857   }
00858   
00859   template <class T>
00860   T &get(const char *label)
00861   {
00862     return m_collection->getHandleByLabel(label).get<T>(m_position);
00863   }
00864 
00865   template <class T>
00866   T &get(IgProperty &property)
00867   {    
00868     return property.handle().get<T>(m_position);
00869   }
00870   
00871   template <class T>
00872   void set(IgProperty &property, T value)
00873   {
00874     property.handle().get<T>(m_position) = value;
00875   }
00876   
00877   template <class T>
00878   void set(const char *label, T value)
00879   {
00880     this->get<T>(label) = value;
00881   }
00882   
00883   void stream(std::ostream &stream)
00884   {
00885     for (IgCollection::Properties::iterator i = m_collection->properties().begin();
00886          i != m_collection->properties().end(); 
00887          i++)
00888     {
00889       IgColumnHandle &handle = i->handle();
00890       handle.stream(stream, m_position);
00891       if (i+1 != m_collection->properties().end())
00892       {
00893         stream << ", ";
00894       }
00895     }
00896   }
00897   
00898   operator IgRef() const
00899   { return IgRef(m_collection->id(), m_position); }
00900   
00901 private:
00902   template <template <typename, typename> class C, class T, class A>
00903   struct ContainerTraits
00904   {
00905     static unsigned int put (IgCollection *collection, 
00906                              unsigned int propertyPosition,
00907                              unsigned int position, C<T,A> container)
00908     {
00909       for (typename C<T,A>::iterator i = container.begin();
00910            i != container.end();
00911            i++)
00912       {
00913         collection->getHandleByPosition(propertyPosition)
00914                     .get<T>(position) = *i;
00915         propertyPosition++;
00916       }
00917       return propertyPosition;
00918     }
00919   };
00920 
00921   IgColumnHandle &currentHandle()
00922   {
00923     return m_collection->getHandleByPosition(m_propertyPosition); 
00924   }
00925 
00926   IgCollection *m_collection;
00927   unsigned int m_position;
00928   unsigned int m_propertyPosition;
00929 };
00930 
00931 class IgAssociationSet
00932 {
00933 public:
00934   typedef std::vector<IgAssociation> Associations;
00935   typedef Associations::iterator Iterator;
00936   
00937   IgAssociationSet(const char *name)
00938   :m_name(name)
00939   { }
00940   
00941   void associate (const IgRef &a, const IgRef &b)
00942   { m_associations.push_back(IgAssociation(a, b)); }
00943   
00944   const char *name(void)
00945   {return m_name.c_str(); }
00946   
00947   Iterator begin(void)
00948   { return m_associations.begin(); }
00949   
00950   Iterator end(void)
00951   { return m_associations.end(); }
00952   
00953   int size(void)
00954   { return m_associations.size(); }
00955   
00956   void clear(void)
00957   { m_associations.clear(); }
00958   
00959   void reserve(unsigned int capacity)
00960   { m_associations.reserve(capacity);}
00961 
00962   void resize(unsigned int newSize)
00963   { m_associations.resize(newSize);}
00964   
00965   void compress(void)
00966   { m_associations.reserve(m_associations.size());}
00967   
00968   IgAssociation &operator[](unsigned int pos)
00969   {
00970     return m_associations[pos];
00971   }
00972 private:
00973   std::string m_name;
00974   Associations m_associations;
00975 };
00976 
00977 class IgAssociatedSet;
00978 
00979 class IgDataStorage
00980 {
00981 public:
00982   // FIXME: quick and dirty...
00983   typedef std::vector<std::string> CollectionNames;
00984   typedef std::vector<std::string> AssociationSetNames;
00985   typedef std::vector<IgCollection *> Collections;
00986   typedef std::vector<IgAssociationSet *> AssociationSets;
00987   
00988   // Data storage is responsible for destroying all its collections
00989   // and their contents.
00990   ~IgDataStorage (void)
00991   {
00992     for (AssociationSets::iterator i = m_associationSets.begin();
00993         i != m_associationSets.end();
00994         i++)
00995     {
00996       delete *i;
00997     }
00998     
00999     for (Collections::iterator i = m_collections.begin();
01000          i != m_collections.end();
01001          i++)
01002     {
01003       for (IgCollection::Properties::iterator j = (*i)->properties().begin();
01004            j != (*i)->properties().end();
01005            j++)
01006       {
01007         j->handle().destroy();
01008       }
01009       delete *i;
01010     }
01011   }
01012   
01013   // FIXME: for the time being a little bit of duplication does not harm.
01014   //        Maybe in future getCollection and getAssociationSet could be
01015   //        put in a templated get<T> function. This needs some template magic
01016   //        which I rather avoid for the time being.
01017   IgCollection &getCollection(const char *label)
01018   {
01019     return *getCollectionPtr(label);
01020   }
01021 
01022   IgAssociatedSet getAssociatedSetPtr(IgAssociationSet *associations, 
01023                                       IgCollectionItem &item, 
01024                                       AssociatedType which = BOTH_ASSOCIATED);
01025 
01026   IgAssociatedSet getAssociatedSet(const char *name, 
01027                                    IgCollectionItem &item, 
01028                                    AssociatedType which = BOTH_ASSOCIATED);
01029   
01030   IgCollection &getCollectionByIndex(unsigned int index)
01031   {
01032     assert(index >= 0);
01033     assert(index < m_collections.size());
01034     return *(m_collections[index]);
01035   }
01036   
01037   IgCollection *getCollectionPtr(const char *label)
01038   {
01039     CollectionNames::iterator n = std::find (m_collectionNames.begin(), 
01040                                              m_collectionNames.end(), 
01041                                              label);
01042     
01043     if (n == m_collectionNames.end())
01044     {
01045       IgCollection *collection = new IgCollection(label, m_collections.size ());
01046       m_collectionNames.push_back(label);
01047       m_collections.push_back(collection);
01048       return collection;
01049     }
01050     return m_collections[std::distance(m_collectionNames.begin(), n)];
01051   }
01052   
01053   IgAssociationSet &getAssociationSet(const char *label)
01054   {
01055     return *getAssociationSetPtr(label);
01056   }
01057   
01058   IgAssociationSet *getAssociationSetPtr(const char * label)
01059   {
01060     AssociationSetNames::iterator n = std::find(m_associationSetNames.begin(),
01061                                                 m_associationSetNames.end(),
01062                                                 label);
01063     if (n == m_associationSetNames.end())
01064     {
01065       IgAssociationSet *associationSet = new IgAssociationSet(label);
01066       m_associationSetNames.push_back(label);
01067       m_associationSets.push_back(associationSet);
01068       return associationSet;
01069     }
01070     return m_associationSets[std::distance(m_associationSetNames.begin(), n)];
01071   }
01072 
01073   IgCollectionItem deref(const IgRef &ref)
01074   {
01075     return IgCollectionItem(m_collections[ref.collectionId()], 
01076                             ref.objectId());
01077   }
01078   
01079   CollectionNames &collectionNames(void)
01080   {
01081     return m_collectionNames; 
01082   }
01083 
01084   AssociationSetNames &associationSetNames(void)
01085   {
01086     return m_associationSetNames; 
01087   }
01088 
01089   bool empty(void)
01090   {
01091     return m_collectionNames.empty();
01092   }
01093 
01094   bool hasCollection(const char *name)
01095   {
01096     return std::find (m_collectionNames.begin(), m_collectionNames.end(), name) != m_collectionNames.end();
01097   }
01098 private:
01099   CollectionNames m_collectionNames;
01100   AssociationSetNames m_associationSetNames;
01101   Collections m_collections;
01102   AssociationSets m_associationSets;
01103 };
01104 
01105 class IgAssociatedSet
01106 {
01107 public:
01108   class Iterator
01109   {
01110   public:
01111     // FIXME: IgCollectionItem should have an objectId method.
01112     Iterator(IgDataStorage *storage, IgAssociationSet::Iterator current,
01113             IgAssociationSet::Iterator end, 
01114             const IgRef &item, 
01115             enum AssociatedType associatedType = BOTH_ASSOCIATED)
01116      :m_storage(storage), 
01117       m_cur(current),
01118       m_end(end),
01119       m_ref(item),
01120       m_associatedType(associatedType)
01121     {
01122       find();
01123     }
01124 
01125     void operator++(int /*dummy*/)
01126     {
01127       m_cur++;
01128       find();
01129     }
01130     
01131     void find(void)
01132     {
01133       while(m_cur != m_end)
01134       {
01135         if ((m_associatedType & RIGHT_ASSOCIATED)
01136             && m_cur->first().objectId() == m_ref.objectId() 
01137             && m_cur->first().collectionId() == m_ref.collectionId())
01138         {
01139           m_pos = 0;
01140           return;
01141         } 
01142         if ((m_associatedType & LEFT_ASSOCIATED)
01143             && m_cur->second().objectId() == m_ref.objectId() 
01144             && m_cur->second().collectionId() == m_ref.collectionId())
01145         {
01146           m_pos = 1;
01147           return;
01148         }
01149         m_cur++;
01150       }      
01151     }
01152     
01153     bool operator==(const Iterator &other)
01154     {
01155       return other.m_cur == this->m_cur;
01156     }
01157 
01158     bool operator!=(const Iterator &other)
01159     {
01160       return other.m_cur != this->m_cur;
01161     }
01162     
01163     IgCollectionItem operator*(void)
01164     {
01165       return m_storage->deref(m_pos ? m_cur->first() : m_cur->second());
01166     }
01167 
01168   private:
01169     IgDataStorage *m_storage;
01170     IgAssociationSet::Iterator m_cur;
01171     IgAssociationSet::Iterator m_end;
01172     const IgRef m_ref;
01173     int   m_pos;
01174     enum AssociatedType m_associatedType;
01175   };
01176   
01177   IgAssociatedSet(IgDataStorage *storage, 
01178                   IgAssociationSet *associations, 
01179                   IgCollectionItem *item,
01180                   enum AssociatedType associatedType = BOTH_ASSOCIATED)
01181   : m_storage(storage),
01182     m_associations(associations),
01183     m_item(item),
01184     m_associatedType(associatedType)
01185   { }
01186   
01187   Iterator begin(void)
01188   {
01189     Iterator result(m_storage, 
01190                     m_associations->begin(),
01191                     m_associations->end(),
01192                     static_cast<IgRef>(*m_item), m_associatedType);
01193     return result;
01194   }
01195   
01196   Iterator end(void)
01197   { return Iterator(m_storage, m_associations->end(),
01198                     m_associations->end(),
01199                     static_cast<const IgRef>(*m_item), m_associatedType); }
01200 private:
01201   IgDataStorage *m_storage;
01202   IgAssociationSet *m_associations;
01203   IgCollectionItem *m_item;
01204   enum AssociatedType m_associatedType;
01205 };
01206 
01207 
01208 std::ostream &operator<<(std::ostream &stream, IgCollection &collection);
01209 std::ostream &operator<<(std::ostream &stream, const IgRef &ref);
01210 std::ostream &operator<<(std::ostream &stream, const IgAssociation &association);
01211 std::ostream &operator<<(std::ostream &stream, IgAssociationSet &associationSet);
01212 std::ostream &operator<<(std::ostream &stream, IgDataStorage &storage);
01213 
01214 #endif /* IGUANA_IG_FILE_IG_COLLECTION_H */

Generated on Tue Jun 9 17:38:14 2009 for CMSSW by  doxygen 1.5.4