NGSolve
5.3
|
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