diff --git a/Hash_map/include/CGAL/Tools/chained_map.h b/Hash_map/include/CGAL/Tools/chained_map.h index 8bb0475a3d6..076f6f2c38c 100644 --- a/Hash_map/include/CGAL/Tools/chained_map.h +++ b/Hash_map/include/CGAL/Tools/chained_map.h @@ -59,7 +59,7 @@ class chained_map typedef typename Allocator_traits::template rebind_alloc > allocator_type; allocator_type alloc; - + std::size_t reserved_size; public: T& xdef() { return STOP.i; } const T& cxdef() const { return STOP.i; } @@ -70,7 +70,7 @@ private: chained_map_elem* HASH(std::size_t x) const { return table + (x & table_size_1); } - void init_table(std::size_t t); + void init_table(std::size_t n); void rehash(); void del_old_table(); @@ -83,17 +83,19 @@ private: } public: + static constexpr std::size_t min_size = 32; + static constexpr std::size_t default_size = 512; typedef chained_map_elem* chained_map_item; typedef chained_map_item item; std::size_t index(chained_map_item it) const { return it->k; } T& inf(chained_map_item it) const { return it->i; } - chained_map(std::size_t n = 1); + chained_map(std::size_t n = default_size); chained_map(const chained_map& D); chained_map& operator=(const chained_map& D); - + void reserve(std::size_t n); void clear_entries(); void clear(); ~chained_map() @@ -104,6 +106,8 @@ public: destroy(item); alloc.deallocate(old_table, old_table_end - old_table); } + if(!table) + return; for (chained_map_item item = table ; item != table_end ; ++item) destroy(item); alloc.deallocate(table, table_end - table); @@ -119,7 +123,11 @@ public: template inline T& chained_map::access(std::size_t x) -{ chained_map_item p = HASH(x); +{ + if(!table) + init_table(reserved_size); + + chained_map_item p = HASH(x); if (old_table) del_old_table(); if ( p->k == x ) { @@ -138,8 +146,11 @@ inline T& chained_map::access(std::size_t x) } template -void chained_map::init_table(std::size_t t) +void chained_map::init_table(std::size_t n) { + std::size_t t = min_size; + while (t < n) t <<= 1; + table_size = t; table_size_1 = t-1; table = alloc.allocate(t + t/2); @@ -270,16 +281,9 @@ T& chained_map::access(chained_map_item p, std::size_t x) template -chained_map::chained_map(std::size_t n) : - nullptrKEY(0), NONnullptrKEY(1), old_table(0) +chained_map::chained_map(std::size_t n) + : nullptrKEY(0), NONnullptrKEY(1), table(nullptr), old_table(0), reserved_size(n) { - if (n < 512) - init_table(512); - else { - std::size_t ts = 1; - while (ts < n) ts <<= 1; - init_table(ts); - } } @@ -320,9 +324,20 @@ chained_map& chained_map::operator=(const chained_ma return *this; } +template +void chained_map::reserve(std::size_t n) +{ + CGAL_assertion(!table); + reserved_size = n; +} + template void chained_map::clear_entries() -{ for(chained_map_item p = table + 1; p < free; p++) +{ + if(!table) + return; + + for(chained_map_item p = table + 1; p < free; p++) if (p->k != nullptrKEY || p >= table + table_size) p->i = T(); } @@ -330,23 +345,30 @@ void chained_map::clear_entries() template void chained_map::clear() { + if(!table) + return; + clear_entries(); for (chained_map_item item = table ; item != table_end ; ++item) destroy(item); alloc.deallocate(table, table_end - table); - init_table(512); + table = nullptr; } template typename chained_map::chained_map_item chained_map::lookup(std::size_t x) const -{ chained_map_item p = HASH(x); +{ + if(!table) + return nullptr; + + chained_map_item p = HASH(x); ((std::size_t &)STOP.k) = x; // cast away const while (p->k != x) { p = p->succ; } - return (p == &STOP) ? 0 : p; + return (p == &STOP) ? nullptr : p; } diff --git a/Hash_map/include/CGAL/Unique_hash_map.h b/Hash_map/include/CGAL/Unique_hash_map.h index 1f7d5be6fc0..a9892ca9774 100644 --- a/Hash_map/include/CGAL/Unique_hash_map.h +++ b/Hash_map/include/CGAL/Unique_hash_map.h @@ -57,7 +57,7 @@ public: Unique_hash_map() { m_map.xdef() = Data(); } - Unique_hash_map( const Data& deflt, std::size_t table_size = 1) + Unique_hash_map( const Data& deflt, std::size_t table_size = Map::default_size) : m_map( table_size) { m_map.xdef() = deflt; } Unique_hash_map( const Data& deflt, @@ -78,6 +78,9 @@ public: insert( first1, beyond1, first2); } + void reserve(std::size_t n) + { m_map.reserve(n); } + Data default_value() const { return m_map.cxdef(); } Hash_function hash_function() const { return m_hash_function; } diff --git a/Miscellany/doc/Miscellany/CGAL/Unique_hash_map.h b/Miscellany/doc/Miscellany/CGAL/Unique_hash_map.h index 4d4477dda05..5d980a1aafa 100644 --- a/Miscellany/doc/Miscellany/CGAL/Unique_hash_map.h +++ b/Miscellany/doc/Miscellany/CGAL/Unique_hash_map.h @@ -120,6 +120,12 @@ been inserted explicitly. Their variables are initialized to */ bool is_defined( const Key& key) const; + +/*! +sets the table size. + */ +void reserve(std::size_t table_size); + /*! resets `*this` to the injective function from `Key` to the diff --git a/Nef_3/include/CGAL/Nef_3/Binary_operation.h b/Nef_3/include/CGAL/Nef_3/Binary_operation.h index 61c86bca0d7..bcfe27e3591 100644 --- a/Nef_3/include/CGAL/Nef_3/Binary_operation.h +++ b/Nef_3/include/CGAL/Nef_3/Binary_operation.h @@ -306,7 +306,7 @@ class Binary_operation : public CGAL::SNC_decorator { number_of_intersection_candidates=0; #endif - Unique_hash_map ignore(false); + Unique_hash_map ignore(false, snc1.number_of_vertices()); Vertex_const_iterator v0; // CGAL_NEF_SETDTHREAD(19*43*131); diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index b17768d8353..e2bf66a33be 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -606,6 +606,7 @@ Node_handle build_kdtree(Vertex_list& V, Halfedge_list& E, Halffacet_list& F, #else Side_of_plane sop(point_on_plane, coord); #endif + sop.reserve(V.size()); Vertex_list V1,V2; classify_objects(V, sop, V1, V2); diff --git a/Nef_3/include/CGAL/Nef_3/SNC_FM_decorator.h b/Nef_3/include/CGAL/Nef_3/SNC_FM_decorator.h index fd9bbb62c24..6f60c188570 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_FM_decorator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_FM_decorator.h @@ -110,14 +110,14 @@ struct Sort_sedges2 { template struct Halffacet_output { -Halffacet_output(CGAL::Unique_hash_map& F, std::vector& S) +Halffacet_output(const CGAL::Unique_hash_map& F, std::vector& S) : From(F), Support(S) { edge_number=0; Support[0]=E(); } typedef P Point; typedef V Vertex_handle; typedef unsigned Halfedge_handle; -CGAL::Unique_hash_map& From; +const CGAL::Unique_hash_map& From; std::vector& Support; unsigned edge_number; @@ -467,12 +467,11 @@ create_facet_objects(const Plane_3& plane_supporting_facet, Object_list_iterator start, Object_list_iterator end) const { CGAL_NEF_TRACEN(">>>>>create_facet_objects " << normalized(plane_supporting_facet)); - CGAL::Unique_hash_map FacetCycle(-1); + std::vector MinimalEdge; std::list SHalfedges; std::list SHalfloops; - CGAL::Unique_hash_map From; Segment_list Segments; SHalfedge_handle e; SHalfloop_handle l; @@ -503,6 +502,7 @@ create_facet_objects(const Plane_3& plane_supporting_facet, CGAL_error_msg("Damn wrong handle."); } + CGAL::Unique_hash_map FacetCycle(-1, SHalfedges.size()); /* We iterate all shalfedges and assign a number for each facet cycle. After that iteration for an edge |e| the number of its facet cycle is |FacetCycle[e]| and for a facet cycle |c| we know @@ -606,6 +606,7 @@ create_facet_objects(const Plane_3& plane_supporting_facet, // Insertion of SHalfedges into Segments is shifted below in order // to guarantee that there are no gaps in the overlay. + CGAL::Unique_hash_map From(SHalfedge_handle(), SHalfedges.size()); // SHalfedges.sort(Sort_sedges2()); SHalfedges.sort(Sort_sedges()); diff --git a/Nef_3/include/CGAL/Nef_3/SNC_decorator.h b/Nef_3/include/CGAL/Nef_3/SNC_decorator.h index f03780a1fa6..61dcbb983ef 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_decorator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_decorator.h @@ -280,6 +280,7 @@ class SNC_decorator : public SNC_const_decorator { SFace_map linked; Shell_volume_setter(const SNCD_& Di) : D(Di), linked(false) {} + void reserve(Size_type n) { linked.reserve(n); } void visit(SFace_handle h) { CGAL_NEF_TRACEN(h->center_vertex()->point()); D.set_volume(h, c); diff --git a/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h index c03e212fdfd..1f6d85e1139 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h @@ -796,9 +796,11 @@ public: // CGAL_NEF_SETDTHREAD(37*43*503*509); CGAL_NEF_TRACEN(">>>>>create_volumes"); - Sface_shell_hash ShellSf(0); - Face_shell_hash ShellF(0); - SFace_visited_hash Done(false); + auto face_count = this->sncp()->number_of_halffacets(); + auto sface_count = this->sncp()->number_of_sfaces(); + Sface_shell_hash ShellSf(0, sface_count); + Face_shell_hash ShellF(0, face_count); + SFace_visited_hash Done(false, sface_count); Shell_explorer V(*this,ShellSf,ShellF,Done); std::vector MinimalSFace; std::vector EntrySFace; @@ -828,11 +830,14 @@ public: Closed.push_back(false); Halffacet_iterator hf; - CGAL_forall_facets(hf,*this) - if(ShellF[hf] != ShellF[hf->twin()]) { - Closed[ShellF[hf]] = true; - Closed[ShellF[hf->twin()]] = true; + CGAL_forall_facets(hf,*this) { + unsigned int shf = ShellF[hf]; + unsigned int shf_twin = ShellF[hf->twin()]; + if(shf != shf_twin) { + Closed[shf] = true; + Closed[shf_twin] = true; } + } CGAL_assertion( pl != nullptr); @@ -1304,7 +1309,7 @@ public: link_shalfedges_to_facet_cycles(); std::map hash; - CGAL::Unique_hash_map done(false); + CGAL::Unique_hash_map done(false, this->sncp()->number_of_shalfedges()); SHalfedge_iterator sei; CGAL_forall_shalfedges(sei, *this->sncp()) { @@ -1381,17 +1386,7 @@ public: SNC_simplify simp(*this->sncp()); simp.vertex_simplificationI(); - // std::map hash; - CGAL::Unique_hash_map - done(false); - /* - SHalfedge_iterator sei; - CGAL_forall_shalfedges(sei, *this->sncp()) { - hash[sei->get_forward_index()] = sei->get_forward_index(); - hash[sei->get_backward_index()] = sei->get_backward_index(); - } - */ categorize_facet_cycles_and_create_facets(); create_volumes(); diff --git a/Nef_3/include/CGAL/Nef_3/SNC_k3_tree_traits.h b/Nef_3/include/CGAL/Nef_3/SNC_k3_tree_traits.h index e993d9dd81a..d32f5be6d89 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_k3_tree_traits.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_k3_tree_traits.h @@ -85,7 +85,7 @@ public: #else Side_of_plane(const Point_3& p, int c) : OnSideMap(unknown_side), coord(c), pop(p) {} #endif - + void reserve(std::size_t n) { OnSideMap.reserve(n); } Oriented_side operator()(Vertex_handle v); Oriented_side operator()(Halfedge_handle e); Oriented_side operator()(Halffacet_handle f); diff --git a/Nef_3/include/CGAL/Nef_3/SNC_simplify.h b/Nef_3/include/CGAL/Nef_3/SNC_simplify.h index 9e258323e5a..6ee8676523d 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_simplify.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_simplify.h @@ -316,9 +316,9 @@ class SNC_simplify_base : public SNC_decorator { CGAL_NEF_TRACEN(">>> simplifying"); SNC_decorator D(*this->sncp()); - Unique_hash_map< Volume_handle, UFH_volume> hash_volume; - Unique_hash_map< Halffacet_handle, UFH_facet> hash_facet; - Unique_hash_map< SFace_handle, UFH_sface> hash_sface; + Unique_hash_map< Volume_handle, UFH_volume> hash_volume(UFH_volume(), this->sncp()->number_of_volumes()); + Unique_hash_map< Halffacet_handle, UFH_facet> hash_facet(UFH_facet(), this->sncp()->number_of_halffacets()); + Unique_hash_map< SFace_handle, UFH_sface> hash_sface(UFH_sface(), this->sncp()->number_of_sfaces()); Union_find< Volume_handle> uf_volume; Union_find< Halffacet_handle> uf_facet; Union_find< SFace_handle> uf_sface; @@ -544,7 +544,8 @@ class SNC_simplify_base : public SNC_decorator { void create_boundary_links_forall_sfaces( Unique_hash_map< SFace_handle, UFH_sface>& hash, Union_find< SFace_handle>& uf ) { - Unique_hash_map< SHalfedge_handle, bool> linked(false); + Unique_hash_map< SHalfedge_handle, bool> linked(false, this->sncp()->number_of_shalfedges()); + SNC_decorator D(*this->sncp()); SHalfedge_iterator e; CGAL_forall_shalfedges(e, *this->sncp()) { @@ -597,7 +598,7 @@ class SNC_simplify_base : public SNC_decorator { void create_boundary_links_forall_facets( Unique_hash_map< Halffacet_handle, UFH_facet>& hash, Union_find< Halffacet_handle>& uf) { - Unique_hash_map< SHalfedge_handle, bool> linked(false); + Unique_hash_map< SHalfedge_handle, bool> linked(false, this->sncp()->number_of_shalfedges()); SNC_decorator D(*this->sncp()); SHalfedge_iterator u; CGAL_forall_shalfedges(u, *this->sncp()) { @@ -651,6 +652,7 @@ class SNC_simplify_base : public SNC_decorator { SNC_decorator D(*this->sncp()); Volume_setter setter(D); + setter.reserve(this->sncp()->number_of_sfaces()); SFace_iterator sf; Volume_handle c; diff --git a/Nef_3/include/CGAL/Nef_3/SNC_structure.h b/Nef_3/include/CGAL/Nef_3/SNC_structure.h index 4a36c02e5b6..1a5442e53ad 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_structure.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_structure.h @@ -462,6 +462,10 @@ public: return *this; } + void reserve_sm_boundary_items(Size_type n) { + sm_boundary_item_.reserve(n); + } + void clear_boundary() { boundary_item_.clear(boost::none); sm_boundary_item_.clear(boost::none); @@ -484,10 +488,10 @@ public: } template - bool is_boundary_object(H h) + bool is_boundary_object(H h) const { return boundary_item_[h]!=boost::none; } template - bool is_sm_boundary_object(H h) + bool is_sm_boundary_object(H h) const { return sm_boundary_item_[h]!=boost::none; } template @@ -1099,13 +1103,13 @@ template void SNC_structure:: pointer_update(const SNC_structure& D) { - CGAL::Unique_hash_map VM; - CGAL::Unique_hash_map EM; - CGAL::Unique_hash_map FM; - CGAL::Unique_hash_map CM; - CGAL::Unique_hash_map SEM; - CGAL::Unique_hash_map SLM; - CGAL::Unique_hash_map SFM; + CGAL::Unique_hash_map VM(Vertex_handle(), D.number_of_vertices()); + CGAL::Unique_hash_map EM(Halfedge_handle(), D.number_of_halfedges()); + CGAL::Unique_hash_map FM(Halffacet_handle(), D.number_of_halffacets()); + CGAL::Unique_hash_map CM(Volume_handle(), D.number_of_volumes()); + CGAL::Unique_hash_map SEM(SHalfedge_handle(), D.number_of_shalfedges()); + CGAL::Unique_hash_map SLM(SHalfloop_handle(), D.number_of_shalfloops()); + CGAL::Unique_hash_map SFM(SFace_handle(), D.number_of_sfaces()); Vertex_const_iterator vc = D.vertices_begin(); Vertex_iterator v = vertices_begin(); for ( ; vc != D.vertices_end(); ++vc,++v) VM[vc] = v; diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index dea41f6eb00..2d2a5922113 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -205,7 +205,6 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, Face_graph_index_adder index_adder(P,himap); - for(vertex_descriptor pv : vertices(P) ) { typename boost::property_traits::reference npv = get(pmap,pv); diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index c4d0e48fa30..8b8acdd7b17 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -355,6 +355,10 @@ protected: delegate(mbv, /*compute_external*/ false, /*simplify*/ false); } + void reserve_for_vertices(Size_type n) { + snc().reserve_sm_boundary_items(n); + } + struct Private_tag {}; Nef_polyhedron_3(Private_tag) { pl() = new SNC_point_locator_default; @@ -615,6 +619,7 @@ protected: : Nef_polyhedron_3(Private_tag{}) { CGAL_NEF_TRACEN("construction from Polyhedron_3"); + reserve_for_vertices(P.size_of_vertices()); initialize_infibox_vertices(EMPTY); polyhedron_3_to_nef_3 , SNC_structure>( P, snc()); @@ -628,6 +633,7 @@ protected: : Nef_polyhedron_3(Private_tag{}) { CGAL_NEF_TRACEN("construction from PolygonMesh with internal index maps"); + reserve_for_vertices(num_vertices(pm)); initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc()); build_external_structure(); @@ -645,6 +651,7 @@ protected: ) : Nef_polyhedron_3(Private_tag{}) { CGAL_NEF_TRACEN("construction from PolygonMesh"); + reserve_for_vertices(num_vertices(pm)); initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc(), fim, him); build_external_structure(); diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_map.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_map.h index 9e2982fd347..4c89dbf4ecd 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_map.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_map.h @@ -495,10 +495,10 @@ template void Sphere_map:: pointer_update(const Sphere_map& D) { - CGAL::Unique_hash_map VM; - CGAL::Unique_hash_map EM; - CGAL::Unique_hash_map LM; - CGAL::Unique_hash_map FM; + CGAL::Unique_hash_map VM(SVertex_handle(), D.number_of_svertices()); + CGAL::Unique_hash_map EM(SHalfedge_handle(), D.number_of_shalfedges()); + CGAL::Unique_hash_map LM(SHalfloop_handle(), D.number_of_shalfloops()); + CGAL::Unique_hash_map FM(SFace_handle(), D.number_of_sfaces()); SVertex_const_iterator vc = D.svertices_begin(); SVertex_iterator v = svertices_begin();