From a79c6720c73721ab92cb931e5d2cee392b0a345f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 10 Apr 2020 12:20:08 +0100 Subject: [PATCH] trivalize data structure --- .../CGAL/boost/graph/Euler_operations.h | 2 +- .../include/CGAL/Small_unordered_mapV2.h | 154 ++++-------------- 2 files changed, 36 insertions(+), 120 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 7ac0cb9732a..4dc515df562 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -783,7 +783,7 @@ void add_faces(const RangeofVertexRange& faces_to_add, PolygonMesh& pm) typedef boost::container::small_vector Halfedges; #else //typedef boost::unordered_map > Halfedges; - typedef Small_unordered_mapV2,8,1> Halfedges; + typedef Small_unordered_mapV2 Halfedges; #endif typedef typename CGAL::GetInitializedVertexIndexMap::type Vid_map; diff --git a/STL_Extension/include/CGAL/Small_unordered_mapV2.h b/STL_Extension/include/CGAL/Small_unordered_mapV2.h index f4d9865378f..db14648696a 100644 --- a/STL_Extension/include/CGAL/Small_unordered_mapV2.h +++ b/STL_Extension/include/CGAL/Small_unordered_mapV2.h @@ -21,95 +21,46 @@ namespace CGAL { -template +template class Small_unordered_mapV2 { -#ifdef CGAL_SMALL_UNORDERED_MAP_STATS - std::array 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 occupied {}; // all 0 - mutable std::bitset occupied; - std::array, B> data; - const H hash = {}; + + std::array, M> data; + boost::unordered_map * 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(); - 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(); + 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 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