mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-11 16:49:16 +05:00
Add Table and HashTable from NGSolve
This commit is contained in:
parent
331c0b9486
commit
78693fb196
@ -7,6 +7,7 @@ add_library(ngcore SHARED
|
|||||||
flags.cpp
|
flags.cpp
|
||||||
paje_trace.cpp
|
paje_trace.cpp
|
||||||
profiler.cpp
|
profiler.cpp
|
||||||
|
table.cpp
|
||||||
taskmanager.cpp
|
taskmanager.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
)
|
)
|
||||||
@ -59,7 +60,7 @@ target_link_libraries(ngcore PUBLIC netgen_mpi PRIVATE ${CMAKE_THREAD_LIBS_INIT}
|
|||||||
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
|
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
|
||||||
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp mpi_wrapper.hpp
|
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp mpi_wrapper.hpp
|
||||||
array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp
|
array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp
|
||||||
xbool.hpp signal.hpp bitarray.hpp
|
xbool.hpp signal.hpp bitarray.hpp table.hpp hashtable.hpp
|
||||||
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
||||||
|
|
||||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
|
1109
libsrc/core/hashtable.hpp
Normal file
1109
libsrc/core/hashtable.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,12 +6,14 @@
|
|||||||
#include "bitarray.hpp"
|
#include "bitarray.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "flags.hpp"
|
#include "flags.hpp"
|
||||||
|
#include "hashtable.hpp"
|
||||||
#include "localheap.hpp"
|
#include "localheap.hpp"
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
#include "mpi_wrapper.hpp"
|
#include "mpi_wrapper.hpp"
|
||||||
#include "profiler.hpp"
|
#include "profiler.hpp"
|
||||||
#include "signal.hpp"
|
#include "signal.hpp"
|
||||||
#include "symboltable.hpp"
|
#include "symboltable.hpp"
|
||||||
|
#include "table.hpp"
|
||||||
#include "taskmanager.hpp"
|
#include "taskmanager.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "xbool.hpp"
|
#include "xbool.hpp"
|
||||||
|
177
libsrc/core/table.cpp
Normal file
177
libsrc/core/table.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* File: table.cpp */
|
||||||
|
/* Author: Joachim Schoeberl */
|
||||||
|
/* Date: 25. Mar. 2000 */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Abstract data type Table
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "table.hpp"
|
||||||
|
|
||||||
|
namespace ngcore
|
||||||
|
{
|
||||||
|
template <typename TI>
|
||||||
|
size_t * TablePrefixSum2 (FlatArray<TI> entrysize)
|
||||||
|
{
|
||||||
|
size_t size = entrysize.Size();
|
||||||
|
size_t * index = new size_t[size+1];
|
||||||
|
|
||||||
|
Array<size_t> partial_sums(TaskManager::GetNumThreads()+1);
|
||||||
|
partial_sums[0] = 0;
|
||||||
|
ParallelJob
|
||||||
|
([&] (TaskInfo ti)
|
||||||
|
{
|
||||||
|
IntRange r = IntRange(size).Split(ti.task_nr, ti.ntasks);
|
||||||
|
size_t mysum = 0;
|
||||||
|
for (size_t i : r)
|
||||||
|
mysum += entrysize[i];
|
||||||
|
partial_sums[ti.task_nr+1] = mysum;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (size_t i = 1; i < partial_sums.Size(); i++)
|
||||||
|
partial_sums[i] += partial_sums[i-1];
|
||||||
|
|
||||||
|
ParallelJob
|
||||||
|
([&] (TaskInfo ti)
|
||||||
|
{
|
||||||
|
IntRange r = IntRange(size).Split(ti.task_nr, ti.ntasks);
|
||||||
|
size_t mysum = partial_sums[ti.task_nr];
|
||||||
|
for (size_t i : r)
|
||||||
|
{
|
||||||
|
index[i] = mysum;
|
||||||
|
mysum += entrysize[i];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
index[size] = partial_sums.Last();
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
NGCORE_API size_t * TablePrefixSum32 (FlatArray<unsigned int> entrysize)
|
||||||
|
{ return TablePrefixSum2 (entrysize); }
|
||||||
|
NGCORE_API size_t * TablePrefixSum64 (FlatArray<size_t> entrysize)
|
||||||
|
{ return TablePrefixSum2 (entrysize); }
|
||||||
|
|
||||||
|
|
||||||
|
BaseDynamicTable :: BaseDynamicTable (int size)
|
||||||
|
: data(size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
data[i].maxsize = 0;
|
||||||
|
data[i].size = 0;
|
||||||
|
data[i].col = NULL;
|
||||||
|
}
|
||||||
|
oneblock = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseDynamicTable :: BaseDynamicTable (const Array<int> & entrysizes, int elemsize)
|
||||||
|
: data(entrysizes.Size())
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
int n = entrysizes.Size();
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
cnt += entrysizes[i];
|
||||||
|
oneblock = new char[elemsize * cnt];
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
data[i].maxsize = entrysizes[i];
|
||||||
|
data[i].size = 0;
|
||||||
|
|
||||||
|
data[i].col = &oneblock[elemsize * cnt];
|
||||||
|
cnt += entrysizes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BaseDynamicTable :: ~BaseDynamicTable ()
|
||||||
|
{
|
||||||
|
if (oneblock)
|
||||||
|
delete [] oneblock;
|
||||||
|
else
|
||||||
|
for (int i = 0; i < data.Size(); i++)
|
||||||
|
delete [] static_cast<char*> (data[i].col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseDynamicTable :: SetSize (int size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < data.Size(); i++)
|
||||||
|
delete [] static_cast<char*> (data[i].col);
|
||||||
|
|
||||||
|
data.SetSize(size);
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
data[i].maxsize = 0;
|
||||||
|
data[i].size = 0;
|
||||||
|
data[i].col = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseDynamicTable :: IncSize (int i, int elsize)
|
||||||
|
{
|
||||||
|
if (i < 0 || i >= data.Size())
|
||||||
|
{
|
||||||
|
std::cerr << "BaseDynamicTable::Inc: Out of range, i = " << i << ", size = " << data.Size() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
linestruct & line = data[i];
|
||||||
|
|
||||||
|
if (line.size == line.maxsize)
|
||||||
|
{
|
||||||
|
void * p = new char [(2*line.maxsize+5) * elsize];
|
||||||
|
|
||||||
|
memcpy (p, line.col, line.maxsize * elsize);
|
||||||
|
delete [] static_cast<char*> (line.col);
|
||||||
|
line.col = p;
|
||||||
|
line.maxsize = 2*line.maxsize+5;
|
||||||
|
}
|
||||||
|
|
||||||
|
line.size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseDynamicTable :: DecSize (int i)
|
||||||
|
{
|
||||||
|
if (i < 0 || i >= data.Size())
|
||||||
|
{
|
||||||
|
std::cerr << "BaseDynamicTable::Dec: Out of range" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
linestruct & line = data[i];
|
||||||
|
|
||||||
|
if (line.size == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "BaseDynamicTable::Dec: EntrySize < 0" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
line.size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredTableCreator::Add (size_t blocknr, int data)
|
||||||
|
{
|
||||||
|
if (!takedofs||takedofs->Test(data))
|
||||||
|
TableCreator<int>::Add(blocknr,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredTableCreator::Add (size_t blocknr, IntRange range)
|
||||||
|
{
|
||||||
|
for (size_t i=range.First(); i<range.Next();i++)
|
||||||
|
if (!takedofs||takedofs->Test(i))
|
||||||
|
TableCreator<int>::Add(blocknr,i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredTableCreator::Add (size_t blocknr, FlatArray<int> dofs)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < dofs.Size(); i++)
|
||||||
|
if (!takedofs||takedofs->Test(dofs[i]))
|
||||||
|
TableCreator<int>::Add(blocknr,dofs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ngcore
|
496
libsrc/core/table.hpp
Normal file
496
libsrc/core/table.hpp
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
#ifndef NETGEN_CORE_TABLE_HPP
|
||||||
|
#define NETGEN_CORE_TABLE_HPP
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* File: table.hpp */
|
||||||
|
/* Author: Joachim Schoeberl */
|
||||||
|
/* Date: 25. Mar. 2000 */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "array.hpp"
|
||||||
|
#include "bitarray.hpp"
|
||||||
|
#include "taskmanager.hpp"
|
||||||
|
#include "ngcore_api.hpp"
|
||||||
|
|
||||||
|
namespace ngcore
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class FlatTable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/// number of rows
|
||||||
|
size_t size;
|
||||||
|
/// pointer to first in row
|
||||||
|
size_t * index;
|
||||||
|
/// array of data
|
||||||
|
T * data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlatTable() = delete;
|
||||||
|
|
||||||
|
NETGEN_INLINE FlatTable(size_t as, size_t * aindex, T * adata)
|
||||||
|
: size(as), index(aindex), data(adata) { ; }
|
||||||
|
|
||||||
|
/// Size of table
|
||||||
|
NETGEN_INLINE size_t Size() const { return size; }
|
||||||
|
|
||||||
|
/// Access entry
|
||||||
|
NETGEN_INLINE const FlatArray<T> operator[] (size_t i) const
|
||||||
|
{
|
||||||
|
return FlatArray<T> (index[i+1]-index[i], data+index[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETGEN_INLINE T * Data() const { return data; }
|
||||||
|
|
||||||
|
NETGEN_INLINE FlatArray<T> AsArray() const
|
||||||
|
{
|
||||||
|
return FlatArray<T> (index[size]-index[0], data+index[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETGEN_INLINE FlatArray<size_t> IndexArray() const
|
||||||
|
{
|
||||||
|
return FlatArray<size_t> (size+1, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// takes range starting from position start of end-start elements
|
||||||
|
NETGEN_INLINE FlatTable<T> Range (size_t start, size_t end) const
|
||||||
|
{
|
||||||
|
return FlatTable<T> (end-start, index+start, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// takes range starting from position start of end-start elements
|
||||||
|
NETGEN_INLINE FlatTable<T> Range (T_Range<size_t> range) const
|
||||||
|
{
|
||||||
|
return FlatTable<T> (range.Size(), index+range.First(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Iterator
|
||||||
|
{
|
||||||
|
const FlatTable & tab;
|
||||||
|
size_t row;
|
||||||
|
public:
|
||||||
|
Iterator (const FlatTable & _tab, size_t _row) : tab(_tab), row(_row) { ; }
|
||||||
|
Iterator & operator++ () { ++row; return *this; }
|
||||||
|
FlatArray<T> operator* () const { return tab[row]; }
|
||||||
|
bool operator!= (const Iterator & it2) { return row != it2.row; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Iterator begin() const { return Iterator(*this, 0); }
|
||||||
|
Iterator end() const { return Iterator(*this, size); }
|
||||||
|
};
|
||||||
|
|
||||||
|
NGCORE_API extern size_t * TablePrefixSum32 (FlatArray<unsigned int> entrysize);
|
||||||
|
NGCORE_API extern size_t * TablePrefixSum64 (FlatArray<size_t> entrysize);
|
||||||
|
|
||||||
|
|
||||||
|
NETGEN_INLINE size_t * TablePrefixSum (FlatArray<unsigned int> entrysize)
|
||||||
|
{ return TablePrefixSum32 (entrysize); }
|
||||||
|
NETGEN_INLINE size_t * TablePrefixSum (FlatArray<int> entrysize)
|
||||||
|
{ return TablePrefixSum32 (FlatArray<unsigned> (entrysize.Size(), (unsigned int*)(int*)(entrysize.Addr(0)))); }
|
||||||
|
NETGEN_INLINE size_t * TablePrefixSum (FlatArray<std::atomic<int>> entrysize)
|
||||||
|
{ return TablePrefixSum32 (FlatArray<unsigned> (entrysize.Size(), (unsigned int*)(std::atomic<int>*)entrysize.Addr(0))); }
|
||||||
|
NETGEN_INLINE size_t * TablePrefixSum (FlatArray<size_t> entrysize)
|
||||||
|
{ return TablePrefixSum64 (entrysize); }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A compact Table container.
|
||||||
|
A table contains size entries of variable size.
|
||||||
|
The entry sizes must be known at construction.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class Table : public FlatTable<T>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
using FlatTable<T>::size;
|
||||||
|
using FlatTable<T>::index;
|
||||||
|
using FlatTable<T>::data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
NETGEN_INLINE Table () : FlatTable<T> (0,nullptr,nullptr) { ; }
|
||||||
|
/// Construct table of uniform entrysize
|
||||||
|
NETGEN_INLINE Table (size_t asize, size_t entrysize)
|
||||||
|
: FlatTable<T>( asize, new size_t[asize+1], new T[asize*entrysize] )
|
||||||
|
{
|
||||||
|
for (size_t i : Range(size))
|
||||||
|
index[i] = i*entrysize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct table of variable entrysize
|
||||||
|
template <typename TI>
|
||||||
|
NETGEN_INLINE Table (FlatArray<TI> entrysize)
|
||||||
|
: FlatTable<T> (0, nullptr, nullptr)
|
||||||
|
{
|
||||||
|
size = entrysize.Size();
|
||||||
|
index = TablePrefixSum (entrysize);
|
||||||
|
size_t cnt = index[size];
|
||||||
|
data = new T[cnt];
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit NETGEN_INLINE Table (const Table<T> & tab2)
|
||||||
|
: FlatTable<T>(0, nullptr, nullptr)
|
||||||
|
{
|
||||||
|
size = tab2.Size();
|
||||||
|
|
||||||
|
index = new size_t[size+1];
|
||||||
|
for (size_t i = 0; i <= size; i++)
|
||||||
|
index[i] = tab2.index[i];
|
||||||
|
|
||||||
|
size_t cnt = index[size];
|
||||||
|
data = new T[cnt];
|
||||||
|
for (size_t i = 0; i < cnt; i++)
|
||||||
|
data[i] = tab2.data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
NETGEN_INLINE Table (Table<T> && tab2)
|
||||||
|
: FlatTable<T>(0, nullptr, nullptr)
|
||||||
|
{
|
||||||
|
Swap (size, tab2.size);
|
||||||
|
Swap (index, tab2.index);
|
||||||
|
Swap (data, tab2.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETGEN_INLINE Table & operator= (Table<T> && tab2)
|
||||||
|
{
|
||||||
|
Swap (size, tab2.size);
|
||||||
|
Swap (index, tab2.index);
|
||||||
|
Swap (data, tab2.data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Delete data
|
||||||
|
NETGEN_INLINE ~Table ()
|
||||||
|
{
|
||||||
|
delete [] data;
|
||||||
|
delete [] index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Size of table
|
||||||
|
using FlatTable<T>::Size;
|
||||||
|
|
||||||
|
/// number of elements in all rows
|
||||||
|
NETGEN_INLINE size_t NElements() const { return index[size]; }
|
||||||
|
|
||||||
|
using FlatTable<T>::operator[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Print table
|
||||||
|
template <class T>
|
||||||
|
inline ostream & operator<< (ostream & s, const Table<T> & table)
|
||||||
|
{
|
||||||
|
for (auto i : Range(table))
|
||||||
|
{
|
||||||
|
s << i << ":";
|
||||||
|
for (auto el : table[i])
|
||||||
|
s << " " << el;
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
s << std::flush;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class TableCreator
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int mode; // 1 .. cnt, 2 .. cnt entries, 3 .. fill table
|
||||||
|
std::atomic<size_t> nd;
|
||||||
|
Array<std::atomic<int>> cnt;
|
||||||
|
Table<T> table;
|
||||||
|
public:
|
||||||
|
TableCreator()
|
||||||
|
{ nd = 0; mode = 1; }
|
||||||
|
TableCreator (size_t acnt)
|
||||||
|
{ nd = acnt; SetMode(2); }
|
||||||
|
|
||||||
|
Table<T> MoveTable()
|
||||||
|
{
|
||||||
|
return std::move(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Done () { return mode > 3; }
|
||||||
|
void operator++(int) { SetMode (mode+1); }
|
||||||
|
|
||||||
|
int GetMode () const { return mode; }
|
||||||
|
void SetMode (int amode)
|
||||||
|
{
|
||||||
|
mode = amode;
|
||||||
|
if (mode == 2)
|
||||||
|
{
|
||||||
|
// cnt.SetSize(nd); // atomic has no copy
|
||||||
|
cnt = Array<std::atomic<int>> (nd);
|
||||||
|
for (auto & ci : cnt) ci.store (0, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
if (mode == 3)
|
||||||
|
{
|
||||||
|
table = Table<T> (cnt);
|
||||||
|
// for (auto & ci : cnt) ci = 0;
|
||||||
|
for (auto & ci : cnt) ci.store (0, std::memory_order_relaxed);
|
||||||
|
// cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSize (size_t _nd)
|
||||||
|
{
|
||||||
|
if (mode == 1)
|
||||||
|
nd = _nd;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nd != _nd)
|
||||||
|
throw Exception ("cannot change size of table-creator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add (size_t blocknr, const T & data)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
size_t oldval = nd;
|
||||||
|
while (blocknr+1>nd) {
|
||||||
|
nd.compare_exchange_weak (oldval, blocknr+1);
|
||||||
|
oldval = nd;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
cnt[blocknr]++;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
int ci = cnt[blocknr]++;
|
||||||
|
table[blocknr][ci] = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Add (size_t blocknr, IntRange range)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
size_t oldval = nd;
|
||||||
|
while (blocknr+1>nd) {
|
||||||
|
nd.compare_exchange_weak (oldval, blocknr+1);
|
||||||
|
oldval = nd;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
cnt[blocknr] += range.Size();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
size_t ci = ( cnt[blocknr] += range.Size() ) - range.Size();
|
||||||
|
for (size_t j = 0; j < range.Size(); j++)
|
||||||
|
table[blocknr][ci+j] = range.First()+j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add (size_t blocknr, const FlatArray<int> & dofs)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
size_t oldval = nd;
|
||||||
|
while (blocknr+1>nd) {
|
||||||
|
nd.compare_exchange_weak (oldval, blocknr+1);
|
||||||
|
oldval = nd;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
cnt[blocknr] += dofs.Size();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
size_t ci = ( cnt[blocknr] += dofs.Size() ) - dofs.Size();
|
||||||
|
for (size_t j = 0; j < dofs.Size(); j++)
|
||||||
|
table[blocknr][ci+j] = dofs[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NGCORE_API FilteredTableCreator : public TableCreator<int>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const BitArray* takedofs;
|
||||||
|
public:
|
||||||
|
FilteredTableCreator(const BitArray* atakedofs)
|
||||||
|
: TableCreator<int>(), takedofs(atakedofs) { };
|
||||||
|
FilteredTableCreator(int acnt, const BitArray* atakedofs)
|
||||||
|
: TableCreator<int>(acnt),takedofs(atakedofs) { };
|
||||||
|
void Add (size_t blocknr, int data);
|
||||||
|
void Add (size_t blocknr, IntRange range);
|
||||||
|
void Add (size_t blocknr, FlatArray<int> dofs);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Base class to generic DynamicTable.
|
||||||
|
class BaseDynamicTable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
///
|
||||||
|
struct linestruct
|
||||||
|
{
|
||||||
|
///
|
||||||
|
int size;
|
||||||
|
///
|
||||||
|
int maxsize;
|
||||||
|
///
|
||||||
|
void * col;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
Array<linestruct> data;
|
||||||
|
///
|
||||||
|
char * oneblock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
NGCORE_API BaseDynamicTable (int size);
|
||||||
|
///
|
||||||
|
NGCORE_API BaseDynamicTable (const Array<int> & entrysizes, int elemsize);
|
||||||
|
///
|
||||||
|
NGCORE_API ~BaseDynamicTable ();
|
||||||
|
|
||||||
|
/// Changes Size of table to size, deletes data
|
||||||
|
NGCORE_API void SetSize (int size);
|
||||||
|
///
|
||||||
|
NGCORE_API void IncSize (int i, int elsize);
|
||||||
|
|
||||||
|
NGCORE_API void DecSize (int i);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A dynamic table class.
|
||||||
|
|
||||||
|
A DynamicTable contains entries of variable size. Entry sizes can
|
||||||
|
be increased dynamically.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class DynamicTable : public BaseDynamicTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Creates table of size size
|
||||||
|
DynamicTable (int size = 0)
|
||||||
|
: BaseDynamicTable (size) { ; }
|
||||||
|
|
||||||
|
/// Creates table with a priori fixed entry sizes.
|
||||||
|
DynamicTable (const Array<int> & entrysizes)
|
||||||
|
: BaseDynamicTable (entrysizes, sizeof(T)) { ; }
|
||||||
|
|
||||||
|
/// Inserts element acont into row i. Does not test if already used.
|
||||||
|
void Add (int i, const T & acont)
|
||||||
|
{
|
||||||
|
if (data[i].size == data[i].maxsize)
|
||||||
|
IncSize (i, sizeof (T));
|
||||||
|
else
|
||||||
|
data[i].size++;
|
||||||
|
static_cast<T*> (data[i].col) [data[i].size-1] = acont;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inserts element acont into row i, iff not yet exists.
|
||||||
|
void AddUnique (int i, const T & cont)
|
||||||
|
{
|
||||||
|
int es = EntrySize (i);
|
||||||
|
int * line = const_cast<int*> (GetLine (i));
|
||||||
|
for (int j = 0; j < es; j++)
|
||||||
|
if (line[j] == cont)
|
||||||
|
return;
|
||||||
|
Add (i, cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Inserts element acont into row i. Does not test if already used.
|
||||||
|
void AddEmpty (int i)
|
||||||
|
{
|
||||||
|
IncSize (i, sizeof (T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the nr-th element in the i-th row to acont.
|
||||||
|
Does not check for overflow. */
|
||||||
|
void Set (int i, int nr, const T & acont)
|
||||||
|
{ static_cast<T*> (data[i].col)[nr] = acont; }
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the nr-th element in the i-th row.
|
||||||
|
Does not check for overflow. */
|
||||||
|
const T & Get (int i, int nr) const
|
||||||
|
{ return static_cast<T*> (data[i].col)[nr]; }
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns pointer to the first element in row i. */
|
||||||
|
const T * GetLine (int i) const
|
||||||
|
{ return static_cast<T*> (data[i].col); }
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns size of the table.
|
||||||
|
int Size () const
|
||||||
|
{ return data.Size(); }
|
||||||
|
|
||||||
|
/// Returns size of the i-th row.
|
||||||
|
int EntrySize (int i) const
|
||||||
|
{ return data[i].size; }
|
||||||
|
|
||||||
|
///
|
||||||
|
void DecEntrySize (int i)
|
||||||
|
{ DecSize(i); }
|
||||||
|
|
||||||
|
/// Access entry i
|
||||||
|
FlatArray<T> operator[] (int i)
|
||||||
|
{ return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef const FlatArray<T> ConstFlatArray;
|
||||||
|
/// Access entry i
|
||||||
|
ConstFlatArray operator[] (int i) const
|
||||||
|
{ return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
|
||||||
|
*/
|
||||||
|
FlatArray<T> operator[] (int i) const
|
||||||
|
{ return FlatArray<T> (data[i].size, static_cast<T*> (data[i].col)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Print table
|
||||||
|
template <class T>
|
||||||
|
inline ostream & operator<< (ostream & s, const DynamicTable<T> & table)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < table.Size(); i++)
|
||||||
|
{
|
||||||
|
s << i << ":";
|
||||||
|
for (int j = 0; j < table[i].Size(); j++)
|
||||||
|
s << " " << table[i][j];
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
s << std::flush;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef DynamicTable<int> IntTable;
|
||||||
|
|
||||||
|
} // namespace ngcore
|
||||||
|
|
||||||
|
#endif // NETGEN_CORE_TABLE_HPP
|
@ -146,6 +146,35 @@ namespace ngcore
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
using index_type = typename detail::IndexTypeHelper<T>::type;
|
using index_type = typename detail::IndexTypeHelper<T>::type;
|
||||||
|
|
||||||
|
class MyMutex
|
||||||
|
{
|
||||||
|
std::atomic<bool> m;
|
||||||
|
public:
|
||||||
|
MyMutex() { m.store(false, std::memory_order_relaxed); }
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
bool should = false;
|
||||||
|
while (!m.compare_exchange_weak(should, true))
|
||||||
|
{
|
||||||
|
should = false;
|
||||||
|
_mm_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
m = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MyLock
|
||||||
|
{
|
||||||
|
MyMutex & mutex;
|
||||||
|
public:
|
||||||
|
MyLock (MyMutex & amutex) : mutex(amutex) { mutex.lock(); }
|
||||||
|
~MyLock () { mutex.unlock(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace ngcore
|
} // namespace ngcore
|
||||||
|
|
||||||
#endif // NETGEN_CORE_UTILS_HPP
|
#endif // NETGEN_CORE_UTILS_HPP
|
||||||
|
Loading…
Reference in New Issue
Block a user