mirror of https://github.com/CGAL/cgal
trivalize data structure
This commit is contained in:
parent
e5d1739608
commit
a79c6720c7
|
|
@ -783,7 +783,7 @@ void add_faces(const RangeofVertexRange& faces_to_add, PolygonMesh& pm)
|
||||||
typedef boost::container::small_vector<halfedge_descriptor,8> Halfedges;
|
typedef boost::container::small_vector<halfedge_descriptor,8> Halfedges;
|
||||||
#else
|
#else
|
||||||
//typedef boost::unordered_map<vertex_descriptor, halfedge_descriptor, boost::hash<vertex_descriptor> > Halfedges;
|
//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
|
#endif
|
||||||
|
|
||||||
typedef typename CGAL::GetInitializedVertexIndexMap<PolygonMesh>::type Vid_map;
|
typedef typename CGAL::GetInitializedVertexIndexMap<PolygonMesh>::type Vid_map;
|
||||||
|
|
|
||||||
|
|
@ -21,96 +21,47 @@
|
||||||
namespace CGAL {
|
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 {
|
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 };
|
std::array<std::pair<K, T>, M> data;
|
||||||
#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 = {};
|
|
||||||
boost::unordered_map<K, T> * big = nullptr;
|
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:
|
public:
|
||||||
|
|
||||||
Small_unordered_mapV2()
|
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()
|
~Small_unordered_mapV2()
|
||||||
{
|
{
|
||||||
if(big != nullptr){
|
if(big != nullptr){
|
||||||
delete big;
|
delete big;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Set only once for a key
|
/// Set only once for a key
|
||||||
void set(const K& k, const T& t)
|
void set(const K& k, const T& t)
|
||||||
{
|
{
|
||||||
if (N < M) {
|
if (N < M) {
|
||||||
unsigned int h = hash(k) % B;
|
data[N].first = k;
|
||||||
unsigned i = h;
|
data[N].second = t;
|
||||||
#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;
|
++N;
|
||||||
return;
|
}else{
|
||||||
}
|
if (N == M) {
|
||||||
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>();
|
big = new boost::unordered_map<K, T>();
|
||||||
for(int pos = head; pos < B; ++pos){
|
for(int pos = 0; pos < M; ++pos){
|
||||||
if(occupied[pos]){
|
|
||||||
big->insert(data[pos]);
|
big->insert(data[pos]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
(*big)[k] = t;
|
(*big)[k] = t;
|
||||||
}
|
}else{
|
||||||
else {
|
|
||||||
(*big)[k] = t;
|
(*big)[k] = t;
|
||||||
}
|
}
|
||||||
++N;
|
++N;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void insert(const std::pair<K,T>& p)
|
void insert(const std::pair<K,T>& p)
|
||||||
|
|
@ -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;
|
struct const_iterator;
|
||||||
|
|
||||||
const_iterator find(const K& k) const
|
const_iterator find(const K& k) const
|
||||||
{
|
{
|
||||||
if (N <= M) {
|
if (N <= M) {
|
||||||
unsigned int h = hash(k) % B;
|
for(int i =0; i < M; ++i){
|
||||||
unsigned int i = h;
|
|
||||||
do {
|
|
||||||
if(! occupied[i]){
|
|
||||||
// the element is not in the map
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
if (data[i].first == k) {
|
if (data[i].first == k) {
|
||||||
return const_iterator(*this,i);
|
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));
|
return const_iterator(*this, big->find(k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,18 +96,6 @@ public:
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
head = B;
|
|
||||||
// occupied.fill(0);
|
|
||||||
if(big != nullptr){
|
|
||||||
delete big;
|
|
||||||
big = nullptr;
|
|
||||||
}
|
|
||||||
N = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct const_iterator {
|
struct const_iterator {
|
||||||
typedef std::pair<K, T> value_type;
|
typedef std::pair<K, T> value_type;
|
||||||
|
|
@ -198,7 +112,7 @@ public:
|
||||||
bool big = false;
|
bool big = false;
|
||||||
|
|
||||||
const_iterator(const Small_unordered_mapV2& map)
|
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){
|
if(big){
|
||||||
bigit = map.big->end();
|
bigit = map.big->end();
|
||||||
|
|
@ -214,7 +128,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator(const Small_unordered_mapV2& map, const Bigit& bigit)
|
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
|
bool operator==(const const_iterator& other) const
|
||||||
|
|
@ -234,12 +148,11 @@ public:
|
||||||
{
|
{
|
||||||
if (big) {
|
if (big) {
|
||||||
++bigit;
|
++bigit;
|
||||||
} else {
|
} else if(pos < map.N-1){
|
||||||
if(pos != B){
|
|
||||||
do {
|
|
||||||
++pos;
|
++pos;
|
||||||
}while((pos !=B) && (! map.occupied[pos]));
|
}else {
|
||||||
}
|
CGAL_assertion((pos == map.N-1) || (pos = M));
|
||||||
|
pos = M;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +171,10 @@ public:
|
||||||
|
|
||||||
const_iterator begin() const
|
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
|
const_iterator end() const
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue