trivalize data structure

This commit is contained in:
Andreas Fabri 2020-04-10 12:20:08 +01:00
parent e5d1739608
commit a79c6720c7
2 changed files with 36 additions and 120 deletions

View File

@ -783,7 +783,7 @@ void add_faces(const RangeofVertexRange& faces_to_add, PolygonMesh& pm)
typedef boost::container::small_vector<halfedge_descriptor,8> Halfedges;
#else
//typedef boost::unordered_map<vertex_descriptor, halfedge_descriptor, boost::hash<vertex_descriptor> > Halfedges;
typedef Small_unordered_mapV2<vertex_descriptor, halfedge_descriptor, boost::hash<vertex_descriptor>,8,1> Halfedges;
typedef Small_unordered_mapV2<vertex_descriptor, halfedge_descriptor, 8> Halfedges;
#endif
typedef typename CGAL::GetInitializedVertexIndexMap<PolygonMesh>::type Vid_map;

View File

@ -21,95 +21,46 @@
namespace CGAL {
template <typename K, typename T, typename H, unsigned int M, unsigned int Factor>
template <typename K, typename T, int M>
class Small_unordered_mapV2 {
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
std::array<int, 20> collisions = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#endif
static constexpr int B = M * Factor ; // the number of bins
int head = B;
// mutable std::array<boost::int8_t, B> occupied {}; // all 0
mutable std::bitset<B> occupied;
std::array<std::pair<K, T>, B> data;
const H hash = {};
std::array<std::pair<K, T>, M> data;
boost::unordered_map<K, T> * big = nullptr;
std::size_t N = 0; // the number of stored elements
int N = 0; // the number of stored elements
public:
Small_unordered_mapV2()
{}
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
~Small_unordered_mapV2()
{
std::cout << "N = "<< N << std::endl;
int total = 0;
std::cout << "0 " << collisions[0] << std::endl;
for (int i = 1; i < 20; i++) {
total += collisions[i];
if (collisions[i] != 0) {
std::cout << i << " " << collisions[i] << std::endl;
}
}
std::cout << "Total: " << total << " " << 100 * (double(total) / double(total + collisions[0])) << "%" << std::endl;
}
#else
~Small_unordered_mapV2()
{
if(big != nullptr){
delete big;
}
}
#endif
/// Set only once for a key
void set(const K& k, const T& t)
{
if (N < M) {
unsigned int h = hash(k) % B;
unsigned i = h;
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
int collision = 0;
#endif
do {
if (occupied[i] == false) {
occupied[i] = true;
data[i].first = k;
data[i].second = t;
if(i < head){
head = i;
}
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
if (collision > 19) {
std::cerr << collision << " collisions" << std::endl;
}
else {
++collisions[collision];
}
#endif
++N;
return;
}
i = (i + 1) % B;
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
++collision;
#endif
} while (i != h);
CGAL_error();
}
else if (N == M) {
big = new boost::unordered_map<K, T>();
for(int pos = head; pos < B; ++pos){
if(occupied[pos]){
data[N].first = k;
data[N].second = t;
++N;
}else{
if (N == M) {
big = new boost::unordered_map<K, T>();
for(int pos = 0; pos < M; ++pos){
big->insert(data[pos]);
}
(*big)[k] = t;
}else{
(*big)[k] = t;
}
(*big)[k] = t;
++N;
}
else {
(*big)[k] = t;
}
++N;
}
@ -119,44 +70,19 @@ public:
}
const T& at(const K& k) const
{
if (N <= M) {
unsigned int h = hash(k) % B;
unsigned int i = h;
do {
if ((occupied[i]) && (data[i].first == k)) {
return data[i].second;
}
i = (i + 1) % B;
} while (i != h);
CGAL_error();
}
else {
return big.at(k);
}
}
struct const_iterator;
const_iterator find(const K& k) const
{
if (N <= M) {
unsigned int h = hash(k) % B;
unsigned int i = h;
do {
if(! occupied[i]){
// the element is not in the map
return end();
}
if (N <= M) {
for(int i =0; i < M; ++i){
if (data[i].first == k) {
return const_iterator(*this,i);
}
i = (i + 1) % B;
} while (i != h);
CGAL_error();
}
else {
}
return end();
}else{
return const_iterator(*this, big->find(k));
}
}
@ -170,18 +96,6 @@ public:
return N;
}
/*
void clear()
{
head = B;
// occupied.fill(0);
if(big != nullptr){
delete big;
big = nullptr;
}
N = 0;
}
*/
struct const_iterator {
typedef std::pair<K, T> value_type;
@ -198,7 +112,7 @@ public:
bool big = false;
const_iterator(const Small_unordered_mapV2& map)
: map(map), pos(B), big(map.N > M)
: map(map), pos(M), big(map.N > M)
{
if(big){
bigit = map.big->end();
@ -214,7 +128,7 @@ public:
}
const_iterator(const Small_unordered_mapV2& map, const Bigit& bigit)
: map(map), pos(B), bigit(bigit), big(true)
: map(map), pos(M), bigit(bigit), big(true)
{}
bool operator==(const const_iterator& other) const
@ -234,12 +148,11 @@ public:
{
if (big) {
++bigit;
} else {
if(pos != B){
do {
++pos;
}while((pos !=B) && (! map.occupied[pos]));
}
} else if(pos < map.N-1){
++pos;
}else {
CGAL_assertion((pos == map.N-1) || (pos = M));
pos = M;
}
return *this;
}
@ -258,7 +171,10 @@ public:
const_iterator begin() const
{
return const_iterator(*this, head);
if(N==0){
return const_iterator(*this);
}
return const_iterator(*this, 0);
}
const_iterator end() const