NGSolve  5.3
ngstd/table.hpp
00001 #ifndef FILE_NGS_TABLE
00002 #define FILE_NGS_TABLE
00003 
00004 /**************************************************************************/
00005 /* File:   table.hpp                                                      */
00006 /* Author: Joachim Schoeberl                                              */
00007 /* Date:   25. Mar. 2000                                                  */
00008 /**************************************************************************/
00009 
00010 #include <atomic>
00011 
00012 namespace ngstd
00013 {
00014 
00015 
00016 template <class T>
00017 class FlatTable 
00018 {
00019 protected:
00021   int size;
00023   size_t * index;
00025   T * data;
00026 
00027 public:
00028   INLINE FlatTable() { ; }
00029 
00030   INLINE FlatTable(int as, size_t * aindex, T * adata)
00031     : size(as), index(aindex), data(adata) { ; }
00032 
00034   INLINE int Size() const { return size; }
00035 
00037   INLINE const FlatArray<T> operator[] (int i) const 
00038   { 
00039     return FlatArray<T> (index[i+1]-index[i], data+index[i]); 
00040   }
00041 
00042   INLINE T * Data() const { return data; }
00043 
00044   INLINE FlatArray<T,size_t> AsArray() const
00045   {
00046     return FlatArray<T,size_t> (index[size], data);
00047   }
00048 
00049   INLINE FlatArray<size_t> IndexArray() const
00050   {
00051     return FlatArray<size_t> (size+1, index);
00052   }
00053 
00054   
00055   class Iterator
00056   {
00057     const FlatTable & tab;
00058     int row;
00059   public:
00060     Iterator (const FlatTable & _tab, int _row) : tab(_tab), row(_row) { ; }
00061     Iterator & operator++ () { ++row; return *this; }
00062     FlatArray<T> operator* () const { return tab[row]; }
00063     bool operator!= (const Iterator & it2) { return row != it2.row; }
00064   };
00065   
00066   Iterator begin() const { return Iterator(*this, 0); }
00067   Iterator end() const { return Iterator(*this, size); }
00068   // IntRange Range () const { return IntRange(0, size); }
00069 };
00070 
00071 
00072 
00078 template <class T>
00079 class Table : public FlatTable<T>
00080 {
00081 protected:
00082 
00083   using FlatTable<T>::size;
00084   using FlatTable<T>::index;
00085   using FlatTable<T>::data;
00086 
00087   /*
00088   INLINE Table ()
00089     : data(NULL) { ; }
00090   */
00091 
00092 public:
00094   INLINE Table () : FlatTable<T> (0,NULL,NULL) { ; }
00096   INLINE Table (int asize, int entrysize)
00097   { 
00098     size = asize;
00099     index = new size_t[size+1];
00100     for (int i = 0; i <= size; i++)
00101       index[i] = i*entrysize;
00102     data = new T [size*entrysize]; 
00103   }
00104 
00106   template <typename TI>
00107   INLINE Table (FlatArray<TI> entrysize)
00108   {
00109     size_t cnt = 0;
00110     size  = entrysize.Size();
00111     
00112     index = new size_t[size+1];
00113     for (int i = 0; i < size; i++)
00114       {
00115         index[i] = cnt;
00116         cnt += entrysize[i];
00117       }
00118     index[size] = cnt;
00119     data = new T[cnt];
00120   }
00121 
00122   explicit INLINE Table (const Table<T> & tab2)
00123   {
00124     size = tab2.Size();
00125     
00126     index = new size_t[size+1];
00127     for (int i = 0; i <= size; i++)
00128       index[i] = tab2.index[i];
00129 
00130     size_t cnt = index[size];
00131     data = new T[cnt];
00132     for (size_t i = 0; i < cnt; i++)
00133       data[i] = tab2.data[i];
00134   }
00135 
00136   INLINE Table (Table<T> && tab2)
00137   {
00138     size = 0;
00139     index = NULL;
00140     data = NULL;
00141 
00142     Swap (size, tab2.size);
00143     Swap (index, tab2.index);
00144     Swap (data, tab2.data);
00145   }
00146 
00147   INLINE Table & operator= (Table<T> && tab2)
00148   {
00149     Swap (size, tab2.size);
00150     Swap (index, tab2.index);
00151     Swap (data, tab2.data);
00152     return *this;
00153   }
00154 
00155 
00156 
00158   INLINE ~Table ()
00159   {
00160     delete [] data; 
00161     delete [] index;
00162   }
00163 
00165   // INLINE int Size() const { return size; }
00166   using FlatTable<T>::Size;
00167   
00169   INLINE size_t NElements() const { return index[size]; }
00170 
00171   using FlatTable<T>::operator[];
00172 };
00173 
00174 
00176 template <class T>
00177 inline ostream & operator<< (ostream & s, const Table<T> & table)
00178 {
00179   for (auto i : Range(table))
00180     {
00181       s << i << ":";
00182       for (auto el : table[i])
00183         s << " " << el;
00184       s << "\n";
00185     }
00186   s << flush;
00187   return s;
00188 }
00189 
00190 
00191 
00192 
00193 template <class T>
00194   class TableCreator
00195   {
00196   protected:  
00197     int mode;    // 1 .. cnt, 2 .. cnt entries, 3 .. fill table
00198     atomic<int> nd;
00199     Array<atomic<int>> cnt;
00200     Table<T> * table;
00201   public:
00202     TableCreator()
00203     { nd = 0; mode = 1; table = NULL; }
00204     TableCreator(int acnt)
00205     { nd = acnt; table = NULL; SetMode(2); }
00206     
00207     Table<T> * GetTable() { return table; }
00208 
00209     /*
00210     operator Table<T> () 
00211     {
00212       Table<int> tmp (std::move(*table));
00213       delete table;
00214       table = NULL;
00215       return std::move(tmp);
00216     }
00217     */
00218     Table<T> MoveTable() 
00219     {
00220       Table<int> tmp (std::move(*table));
00221       delete table;
00222       table = NULL;
00223       return std::move(tmp);
00224     }
00225 
00226 
00227     bool Done () { return mode > 3; }
00228     void operator++(int) { SetMode (mode+1); }
00229 
00230     int GetMode () const { return mode; }
00231     void SetMode (int amode) 
00232     {
00233       mode = amode; 
00234       if (mode == 2) 
00235         {
00236           // cnt.SetSize(nd);  // atomic has no copy
00237           cnt = Array<atomic<int>> (nd);
00238           for (auto & ci : cnt) ci = 0;
00239         }
00240       if (mode == 3)
00241         {
00242           table = new Table<T> (cnt);
00243           for (auto & ci : cnt) ci = 0;
00244           // cnt = 0;
00245         }
00246     }
00247 
00248     void SetSize (int _nd)
00249     {
00250       if (mode == 1)
00251         nd = _nd;
00252       else
00253         {
00254           if (nd != _nd)
00255             throw Exception ("cannot change size of table-creator");
00256         }
00257     }
00258 
00259     void Add (int blocknr, const T & data)
00260     {
00261       int oldval;
00262       switch (mode)
00263         {
00264         case 1:
00265       oldval = nd;
00266       while (blocknr+1>nd) {
00267           nd.compare_exchange_weak (oldval, blocknr+1);
00268           oldval = nd;
00269       }
00270           break;
00271         case 2:
00272           cnt[blocknr]++;
00273           break;
00274         case 3:
00275           int ci = cnt[blocknr]++;
00276           (*table)[blocknr][ci] = data;
00277           break;
00278         }
00279     }
00280 
00281 
00282     void Add (int blocknr, IntRange range)
00283     {
00284       int oldval;
00285       switch (mode)
00286         {
00287         case 1:
00288       oldval = nd;
00289       while (blocknr+1>nd) {
00290           nd.compare_exchange_weak (oldval, blocknr+1);
00291           oldval = nd;
00292       }
00293           break;
00294         case 2:
00295           cnt[blocknr] += range.Size();
00296           break;
00297         case 3:
00298           int ci = ( cnt[blocknr] += range.Size() ) - range.Size();
00299           for (int j = 0; j < range.Size(); j++)
00300             (*table)[blocknr][ci+j] = range.First()+j;
00301           break;
00302         }
00303     }
00304 
00305     void Add (int blocknr, const FlatArray<int> & dofs)
00306     {
00307       int oldval;
00308       switch (mode)
00309         {
00310         case 1:
00311       oldval = nd;
00312       while (blocknr+1>nd) {
00313           nd.compare_exchange_weak (oldval, blocknr+1);
00314           oldval = nd;
00315       }
00316           break;
00317         case 2:
00318           cnt[blocknr] += dofs.Size();
00319           break;
00320         case 3:
00321           int ci = ( cnt[blocknr] += dofs.Size() ) - dofs.Size();
00322           for (int j = 0; j < dofs.Size(); j++)
00323             (*table)[blocknr][ci+j] = dofs[j];
00324           break;
00325         }
00326     }
00327   };
00328 
00329   class BitArray;
00330   
00331   class NGS_DLL_HEADER FilteredTableCreator : public TableCreator<int>
00332   {
00333   protected:
00334     const BitArray* takedofs;  
00335   public:
00336     FilteredTableCreator(const BitArray* atakedofs) 
00337       : TableCreator<int>(), takedofs(atakedofs) { };
00338     FilteredTableCreator(int acnt, const BitArray* atakedofs)
00339       : TableCreator<int>(acnt),takedofs(atakedofs) { };
00340     void Add (int blocknr, int data);
00341     void Add (int blocknr, IntRange range);
00342     void Add (int blocknr, FlatArray<int> dofs);
00343   };
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00353 class BaseDynamicTable
00354 {
00355 protected:
00356   
00358   struct linestruct
00359   {
00361     int size;
00363     int maxsize;
00365     void * col;
00366   };
00367   
00369   Array<linestruct> data;
00371   char * oneblock;
00372 
00373 public:
00375   NGS_DLL_HEADER BaseDynamicTable (int size);
00377   NGS_DLL_HEADER BaseDynamicTable (const Array<int> & entrysizes, int elemsize);
00379   NGS_DLL_HEADER ~BaseDynamicTable ();
00380 
00382   NGS_DLL_HEADER void SetSize (int size);
00384   NGS_DLL_HEADER void IncSize (int i, int elsize);
00385 
00386   NGS_DLL_HEADER void DecSize (int i);
00387 };
00388 
00389 
00390 
00397 template <class T>
00398 class DynamicTable : public BaseDynamicTable
00399 {
00400 public:
00402   DynamicTable (int size = 0)
00403     : BaseDynamicTable (size) { ; }
00404 
00406   DynamicTable (const Array<int> & entrysizes)
00407     : BaseDynamicTable (entrysizes, sizeof(T)) { ; }
00408 
00410   void Add (int i, const T & acont)
00411   {
00412     if (data[i].size == data[i].maxsize)
00413       IncSize (i, sizeof (T));
00414     else
00415       data[i].size++;
00416     static_cast<T*> (data[i].col) [data[i].size-1] = acont;
00417   }
00418 
00420   void AddUnique (int i, const T & cont)
00421   {
00422     int es = EntrySize (i);
00423     int * line = const_cast<int*> (GetLine (i));
00424     for (int j = 0; j < es; j++)
00425       if (line[j] == cont)
00426         return;
00427     Add (i, cont);
00428   }
00429 
00430 
00432   void AddEmpty (int i)
00433   {
00434     IncSize (i, sizeof (T));
00435   }
00436 
00439   void Set (int i, int nr, const T & acont)
00440   { static_cast<T*> (data[i].col)[nr] = acont; }
00441   
00442 
00445   const T & Get (int i, int nr) const
00446   { return static_cast<T*> (data[i].col)[nr]; }
00447 
00448 
00450   const T * GetLine (int i) const
00451   { return static_cast<T*> (data[i].col); }
00452   
00453   
00455   int Size () const
00456   { return data.Size(); }
00457 
00459   int EntrySize (int i) const
00460   { return data[i].size; }
00461   
00463   void DecEntrySize (int i)
00464   { DecSize(i); }
00465 
00467   FlatArray<T> operator[] (int i) 
00468   { return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
00469 
00470   /*
00471   typedef const FlatArray<T> ConstFlatArray;
00473   ConstFlatArray operator[] (int i) const
00474   { return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
00475   */
00476   FlatArray<T> operator[] (int i) const
00477   { return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
00478 };
00479 
00480 
00481 
00482 
00484 template <class T>
00485 inline ostream & operator<< (ostream & s, const DynamicTable<T> & table)
00486 {
00487   for (int i = 0; i < table.Size(); i++)
00488     {
00489       s << i << ":";
00490       for (int j = 0; j < table[i].Size(); j++)
00491         s << " " << table[i][j];
00492       s << "\n";
00493     }
00494   s << flush;
00495   return s;
00496 }
00497 
00498 typedef DynamicTable<int> IntTable;
00499 
00500 }
00501 
00502 #endif
00503