netgen-mesher 6.2.2506.post35.dev0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netgen/NgOCC.py +7 -0
- netgen/__init__.py +114 -0
- netgen/__init__.pyi +22 -0
- netgen/__main__.py +53 -0
- netgen/cmake/NetgenConfig.cmake +79 -0
- netgen/cmake/netgen-targets-release.cmake +69 -0
- netgen/cmake/netgen-targets.cmake +146 -0
- netgen/config/__init__.py +1 -0
- netgen/config/__init__.pyi +52 -0
- netgen/config/__main__.py +4 -0
- netgen/config/config.py +68 -0
- netgen/config/config.pyi +54 -0
- netgen/csg.py +25 -0
- netgen/geom2d.py +178 -0
- netgen/gui.py +82 -0
- netgen/include/core/archive.hpp +1256 -0
- netgen/include/core/array.hpp +1760 -0
- netgen/include/core/autodiff.hpp +1131 -0
- netgen/include/core/autodiffdiff.hpp +733 -0
- netgen/include/core/bitarray.hpp +240 -0
- netgen/include/core/concurrentqueue.h +3619 -0
- netgen/include/core/exception.hpp +145 -0
- netgen/include/core/flags.hpp +199 -0
- netgen/include/core/hashtable.hpp +1281 -0
- netgen/include/core/localheap.hpp +318 -0
- netgen/include/core/logging.hpp +117 -0
- netgen/include/core/memtracer.hpp +221 -0
- netgen/include/core/mpi4py_pycapi.h +245 -0
- netgen/include/core/mpi_wrapper.hpp +643 -0
- netgen/include/core/ng_mpi.hpp +94 -0
- netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
- netgen/include/core/ng_mpi_native.hpp +25 -0
- netgen/include/core/ngcore.hpp +32 -0
- netgen/include/core/ngcore_api.hpp +152 -0
- netgen/include/core/ngstream.hpp +115 -0
- netgen/include/core/paje_trace.hpp +279 -0
- netgen/include/core/profiler.hpp +382 -0
- netgen/include/core/python_ngcore.hpp +457 -0
- netgen/include/core/ranges.hpp +109 -0
- netgen/include/core/register_archive.hpp +100 -0
- netgen/include/core/signal.hpp +82 -0
- netgen/include/core/simd.hpp +160 -0
- netgen/include/core/simd_arm64.hpp +407 -0
- netgen/include/core/simd_avx.hpp +394 -0
- netgen/include/core/simd_avx512.hpp +285 -0
- netgen/include/core/simd_generic.hpp +1053 -0
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +289 -0
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/symboltable.hpp +153 -0
- netgen/include/core/table.hpp +810 -0
- netgen/include/core/taskmanager.hpp +1161 -0
- netgen/include/core/type_traits.hpp +65 -0
- netgen/include/core/utils.hpp +385 -0
- netgen/include/core/version.hpp +102 -0
- netgen/include/core/xbool.hpp +47 -0
- netgen/include/csg/algprim.hpp +563 -0
- netgen/include/csg/brick.hpp +150 -0
- netgen/include/csg/csg.hpp +43 -0
- netgen/include/csg/csgeom.hpp +389 -0
- netgen/include/csg/csgparser.hpp +101 -0
- netgen/include/csg/curve2d.hpp +67 -0
- netgen/include/csg/edgeflw.hpp +112 -0
- netgen/include/csg/explicitcurve2d.hpp +113 -0
- netgen/include/csg/extrusion.hpp +185 -0
- netgen/include/csg/gencyl.hpp +70 -0
- netgen/include/csg/geoml.hpp +16 -0
- netgen/include/csg/identify.hpp +213 -0
- netgen/include/csg/manifold.hpp +29 -0
- netgen/include/csg/meshsurf.hpp +46 -0
- netgen/include/csg/polyhedra.hpp +121 -0
- netgen/include/csg/revolution.hpp +180 -0
- netgen/include/csg/singularref.hpp +84 -0
- netgen/include/csg/solid.hpp +295 -0
- netgen/include/csg/specpoin.hpp +194 -0
- netgen/include/csg/spline3d.hpp +99 -0
- netgen/include/csg/splinesurface.hpp +85 -0
- netgen/include/csg/surface.hpp +394 -0
- netgen/include/csg/triapprox.hpp +63 -0
- netgen/include/csg/vscsg.hpp +34 -0
- netgen/include/general/autodiff.hpp +356 -0
- netgen/include/general/autoptr.hpp +39 -0
- netgen/include/general/gzstream.h +121 -0
- netgen/include/general/hashtabl.hpp +1692 -0
- netgen/include/general/myadt.hpp +48 -0
- netgen/include/general/mystring.hpp +226 -0
- netgen/include/general/netgenout.hpp +205 -0
- netgen/include/general/ngarray.hpp +797 -0
- netgen/include/general/ngbitarray.hpp +149 -0
- netgen/include/general/ngpython.hpp +74 -0
- netgen/include/general/optmem.hpp +44 -0
- netgen/include/general/parthreads.hpp +138 -0
- netgen/include/general/seti.hpp +50 -0
- netgen/include/general/sort.hpp +47 -0
- netgen/include/general/spbita2d.hpp +59 -0
- netgen/include/general/stack.hpp +114 -0
- netgen/include/general/table.hpp +280 -0
- netgen/include/general/template.hpp +509 -0
- netgen/include/geom2d/csg2d.hpp +750 -0
- netgen/include/geom2d/geometry2d.hpp +280 -0
- netgen/include/geom2d/spline2d.hpp +234 -0
- netgen/include/geom2d/vsgeom2d.hpp +28 -0
- netgen/include/gprim/adtree.hpp +1392 -0
- netgen/include/gprim/geom2d.hpp +858 -0
- netgen/include/gprim/geom3d.hpp +749 -0
- netgen/include/gprim/geomfuncs.hpp +212 -0
- netgen/include/gprim/geomobjects.hpp +544 -0
- netgen/include/gprim/geomops.hpp +404 -0
- netgen/include/gprim/geomtest3d.hpp +101 -0
- netgen/include/gprim/gprim.hpp +33 -0
- netgen/include/gprim/spline.hpp +778 -0
- netgen/include/gprim/splinegeometry.hpp +73 -0
- netgen/include/gprim/transform3d.hpp +216 -0
- netgen/include/include/acisgeom.hpp +3 -0
- netgen/include/include/csg.hpp +1 -0
- netgen/include/include/geometry2d.hpp +1 -0
- netgen/include/include/gprim.hpp +1 -0
- netgen/include/include/incopengl.hpp +62 -0
- netgen/include/include/inctcl.hpp +13 -0
- netgen/include/include/incvis.hpp +6 -0
- netgen/include/include/linalg.hpp +1 -0
- netgen/include/include/meshing.hpp +1 -0
- netgen/include/include/myadt.hpp +1 -0
- netgen/include/include/mydefs.hpp +70 -0
- netgen/include/include/mystdlib.h +59 -0
- netgen/include/include/netgen_config.hpp +27 -0
- netgen/include/include/netgen_version.hpp +9 -0
- netgen/include/include/nginterface_v2_impl.hpp +395 -0
- netgen/include/include/ngsimd.hpp +1 -0
- netgen/include/include/occgeom.hpp +1 -0
- netgen/include/include/opti.hpp +1 -0
- netgen/include/include/parallel.hpp +1 -0
- netgen/include/include/stlgeom.hpp +1 -0
- netgen/include/include/visual.hpp +1 -0
- netgen/include/interface/rw_medit.hpp +11 -0
- netgen/include/interface/writeuser.hpp +80 -0
- netgen/include/linalg/densemat.hpp +414 -0
- netgen/include/linalg/linalg.hpp +29 -0
- netgen/include/linalg/opti.hpp +142 -0
- netgen/include/linalg/polynomial.hpp +47 -0
- netgen/include/linalg/vector.hpp +217 -0
- netgen/include/meshing/adfront2.hpp +274 -0
- netgen/include/meshing/adfront3.hpp +332 -0
- netgen/include/meshing/basegeom.hpp +370 -0
- netgen/include/meshing/bcfunctions.hpp +53 -0
- netgen/include/meshing/bisect.hpp +72 -0
- netgen/include/meshing/boundarylayer.hpp +113 -0
- netgen/include/meshing/classifyhpel.hpp +1984 -0
- netgen/include/meshing/clusters.hpp +46 -0
- netgen/include/meshing/curvedelems.hpp +274 -0
- netgen/include/meshing/delaunay2d.hpp +73 -0
- netgen/include/meshing/fieldlines.hpp +103 -0
- netgen/include/meshing/findip.hpp +198 -0
- netgen/include/meshing/findip2.hpp +103 -0
- netgen/include/meshing/geomsearch.hpp +69 -0
- netgen/include/meshing/global.hpp +54 -0
- netgen/include/meshing/hpref_hex.hpp +330 -0
- netgen/include/meshing/hpref_prism.hpp +3405 -0
- netgen/include/meshing/hpref_pyramid.hpp +154 -0
- netgen/include/meshing/hpref_quad.hpp +2082 -0
- netgen/include/meshing/hpref_segm.hpp +122 -0
- netgen/include/meshing/hpref_tet.hpp +4230 -0
- netgen/include/meshing/hpref_trig.hpp +848 -0
- netgen/include/meshing/hprefinement.hpp +366 -0
- netgen/include/meshing/improve2.hpp +178 -0
- netgen/include/meshing/improve3.hpp +151 -0
- netgen/include/meshing/localh.hpp +223 -0
- netgen/include/meshing/meshclass.hpp +1076 -0
- netgen/include/meshing/meshfunc.hpp +47 -0
- netgen/include/meshing/meshing.hpp +63 -0
- netgen/include/meshing/meshing2.hpp +163 -0
- netgen/include/meshing/meshing3.hpp +123 -0
- netgen/include/meshing/meshtool.hpp +90 -0
- netgen/include/meshing/meshtype.hpp +1930 -0
- netgen/include/meshing/msghandler.hpp +62 -0
- netgen/include/meshing/paralleltop.hpp +172 -0
- netgen/include/meshing/python_mesh.hpp +206 -0
- netgen/include/meshing/ruler2.hpp +172 -0
- netgen/include/meshing/ruler3.hpp +211 -0
- netgen/include/meshing/soldata.hpp +141 -0
- netgen/include/meshing/specials.hpp +17 -0
- netgen/include/meshing/surfacegeom.hpp +73 -0
- netgen/include/meshing/topology.hpp +1003 -0
- netgen/include/meshing/validate.hpp +21 -0
- netgen/include/meshing/visual_interface.hpp +71 -0
- netgen/include/mydefs.hpp +70 -0
- netgen/include/nginterface.h +474 -0
- netgen/include/nginterface_v2.hpp +406 -0
- netgen/include/nglib.h +697 -0
- netgen/include/nglib_occ.h +50 -0
- netgen/include/occ/occ_edge.hpp +47 -0
- netgen/include/occ/occ_face.hpp +52 -0
- netgen/include/occ/occ_solid.hpp +23 -0
- netgen/include/occ/occ_utils.hpp +376 -0
- netgen/include/occ/occ_vertex.hpp +30 -0
- netgen/include/occ/occgeom.hpp +659 -0
- netgen/include/occ/occmeshsurf.hpp +168 -0
- netgen/include/occ/vsocc.hpp +33 -0
- netgen/include/pybind11/LICENSE +29 -0
- netgen/include/pybind11/attr.h +722 -0
- netgen/include/pybind11/buffer_info.h +208 -0
- netgen/include/pybind11/cast.h +2361 -0
- netgen/include/pybind11/chrono.h +228 -0
- netgen/include/pybind11/common.h +2 -0
- netgen/include/pybind11/complex.h +74 -0
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +823 -0
- netgen/include/pybind11/detail/common.h +1348 -0
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +226 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +538 -0
- netgen/include/pybind11/detail/internals.h +799 -0
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +1591 -0
- netgen/include/pybind11/detail/typeid.h +65 -0
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/common.h +9 -0
- netgen/include/pybind11/eigen/matrix.h +723 -0
- netgen/include/pybind11/eigen/tensor.h +521 -0
- netgen/include/pybind11/eigen.h +12 -0
- netgen/include/pybind11/embed.h +320 -0
- netgen/include/pybind11/eval.h +161 -0
- netgen/include/pybind11/functional.h +147 -0
- netgen/include/pybind11/gil.h +199 -0
- netgen/include/pybind11/gil_safe_call_once.h +102 -0
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/iostream.h +265 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +2312 -0
- netgen/include/pybind11/operators.h +202 -0
- netgen/include/pybind11/options.h +92 -0
- netgen/include/pybind11/pybind11.h +3645 -0
- netgen/include/pybind11/pytypes.h +2680 -0
- netgen/include/pybind11/stl/filesystem.h +114 -0
- netgen/include/pybind11/stl.h +666 -0
- netgen/include/pybind11/stl_bind.h +858 -0
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
- netgen/include/pybind11/typing.h +298 -0
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/stlgeom/meshstlsurface.hpp +67 -0
- netgen/include/stlgeom/stlgeom.hpp +491 -0
- netgen/include/stlgeom/stlline.hpp +193 -0
- netgen/include/stlgeom/stltool.hpp +331 -0
- netgen/include/stlgeom/stltopology.hpp +419 -0
- netgen/include/stlgeom/vsstl.hpp +58 -0
- netgen/include/visualization/meshdoc.hpp +42 -0
- netgen/include/visualization/mvdraw.hpp +325 -0
- netgen/include/visualization/vispar.hpp +128 -0
- netgen/include/visualization/visual.hpp +28 -0
- netgen/include/visualization/visual_api.hpp +10 -0
- netgen/include/visualization/vssolution.hpp +399 -0
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/lib/togl.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.lib +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +1545 -0
- netgen/libngpy/__init__.pyi +7 -0
- netgen/libngpy/_csg.pyi +259 -0
- netgen/libngpy/_geom2d.pyi +323 -0
- netgen/libngpy/_meshing.pyi +1111 -0
- netgen/libngpy/_stl.pyi +131 -0
- netgen/libngpy.lib +0 -0
- netgen/libngpy.pyd +0 -0
- netgen/meshing.py +65 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/occ.py +52 -0
- netgen/read_gmsh.py +259 -0
- netgen/read_meshio.py +22 -0
- netgen/stl.py +2 -0
- netgen/togl.dll +0 -0
- netgen/version.py +2 -0
- netgen/webgui.py +529 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
- pyngcore/__init__.py +1 -0
- pyngcore/pyngcore.cp314-win_amd64.pyd +0 -0
|
@@ -0,0 +1,1281 @@
|
|
|
1
|
+
#ifndef FILE_NGSTD_HASHTABLE
|
|
2
|
+
#define FILE_NGSTD_HASHTABLE
|
|
3
|
+
|
|
4
|
+
/**************************************************************************/
|
|
5
|
+
/* File: hashtable.hpp */
|
|
6
|
+
/* Author: Joachim Schoeberl */
|
|
7
|
+
/* Date: 01. Jun. 95 */
|
|
8
|
+
/**************************************************************************/
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <tuple>
|
|
12
|
+
#include <optional>
|
|
13
|
+
|
|
14
|
+
// #include "mpi_wrapper.hpp"
|
|
15
|
+
#include "ngcore_api.hpp"
|
|
16
|
+
#include "table.hpp"
|
|
17
|
+
#include "utils.hpp"
|
|
18
|
+
|
|
19
|
+
namespace ngcore
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
template <int K>
|
|
24
|
+
class MakeTupleFromInt
|
|
25
|
+
{
|
|
26
|
+
public:
|
|
27
|
+
template <typename I>
|
|
28
|
+
auto operator()(I & i)
|
|
29
|
+
{ return tuple_cat(MakeTupleFromInt<K-1> ()(i), std::tie(i[K-1])); }
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
template <>
|
|
33
|
+
class MakeTupleFromInt<1>
|
|
34
|
+
{
|
|
35
|
+
public:
|
|
36
|
+
template <typename I>
|
|
37
|
+
auto operator()(I & i) { return std::tie(i[0]); }
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
// feature check macro for transition from INT to IVec
|
|
43
|
+
#define NGCORE_HAS_IVEC
|
|
44
|
+
|
|
45
|
+
/// N integers
|
|
46
|
+
template <int N, typename T = int>
|
|
47
|
+
class IVec
|
|
48
|
+
{
|
|
49
|
+
/// data
|
|
50
|
+
// T i[(N>0)?N:1];
|
|
51
|
+
|
|
52
|
+
HTArray<N,T> i;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
///
|
|
56
|
+
constexpr NETGEN_INLINE IVec () = default;
|
|
57
|
+
constexpr NETGEN_INLINE IVec (const IVec & i1) : i(i1.i) { }
|
|
58
|
+
|
|
59
|
+
constexpr NETGEN_INLINE IVec (T ai1) : i(ai1) { }
|
|
60
|
+
|
|
61
|
+
template <class... T2,
|
|
62
|
+
std::enable_if_t<N==1+sizeof...(T2),bool> = true>
|
|
63
|
+
constexpr IVec (const T &v, T2... rest)
|
|
64
|
+
: i{v,rest...} { }
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
/// init all
|
|
68
|
+
NETGEN_INLINE IVec (T ai1)
|
|
69
|
+
{
|
|
70
|
+
for (int j = 0; j < N; j++) { i[j] = ai1; }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// init i[0], i[1]
|
|
74
|
+
constexpr NETGEN_INLINE IVec (T ai1, T ai2)
|
|
75
|
+
: i{ai1, ai2} { ; }
|
|
76
|
+
|
|
77
|
+
/// init i[0], i[1], i[2]
|
|
78
|
+
constexpr NETGEN_INLINE IVec (T ai1, T ai2, T ai3)
|
|
79
|
+
: i{ai1, ai2, ai3} { ; }
|
|
80
|
+
|
|
81
|
+
/// init i[0], i[1], i[2]
|
|
82
|
+
constexpr NETGEN_INLINE IVec (T ai1, T ai2, T ai3, T ai4)
|
|
83
|
+
: i{ai1, ai2, ai3, ai4} { ; }
|
|
84
|
+
|
|
85
|
+
/// init i[0], i[1], i[2]
|
|
86
|
+
constexpr NETGEN_INLINE IVec (T ai1, T ai2, T ai3, T ai4, T ai5)
|
|
87
|
+
: i{ai1, ai2, ai3, ai4, ai5} { ; }
|
|
88
|
+
|
|
89
|
+
/// init i[0], i[1], i[2]
|
|
90
|
+
NETGEN_INLINE IVec (T ai1, T ai2, T ai3, T ai4, T ai5, T ai6, T ai7, T ai8, T ai9)
|
|
91
|
+
: i{ai1, ai2, ai3, ai4, ai5, ai6, ai7, ai8, ai9 } { ; }
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
template <typename ARCHIVE>
|
|
95
|
+
void DoArchive(ARCHIVE& ar)
|
|
96
|
+
{
|
|
97
|
+
// ar.Do(i.begin(), N);
|
|
98
|
+
ar.Do(i.Ptr(), N);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
template <int N2, typename T2>
|
|
102
|
+
NETGEN_INLINE IVec (const IVec<N2,T2> & in2)
|
|
103
|
+
{
|
|
104
|
+
if (N2 <= N)
|
|
105
|
+
{
|
|
106
|
+
for (int j = 0; j < N2; j++)
|
|
107
|
+
i[j] = in2[j];
|
|
108
|
+
for (int j = N2; j < N; j++)
|
|
109
|
+
i[j] = 0;
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
{
|
|
113
|
+
for (int j = 0; j < N; j++)
|
|
114
|
+
i[j] = in2[j];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
template <typename T2>
|
|
119
|
+
NETGEN_INLINE IVec (const BaseArrayObject<T2> & ao)
|
|
120
|
+
{
|
|
121
|
+
for (int j = 0; j < N; j++)
|
|
122
|
+
i[j] = ao.Spec()[j];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
NETGEN_INLINE size_t Size() const { return N; }
|
|
126
|
+
/// all ints equal ?
|
|
127
|
+
NETGEN_INLINE bool operator== (const IVec & in2) const
|
|
128
|
+
{
|
|
129
|
+
for (int j = 0; j < N; j++)
|
|
130
|
+
if (i[j] != in2.i[j]) return 0;
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// any ints unequal ?
|
|
135
|
+
NETGEN_INLINE bool operator!= (const IVec & in2) const
|
|
136
|
+
{
|
|
137
|
+
for (int j = 0; j < N; j++)
|
|
138
|
+
if (i[j] != in2.i[j]) return 1;
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/// sort integers
|
|
143
|
+
NETGEN_INLINE IVec & Sort () &
|
|
144
|
+
{
|
|
145
|
+
for (int k = 0; k < N; k++)
|
|
146
|
+
for (int l = k+1; l < N; l++)
|
|
147
|
+
if (i[k] > i[l])
|
|
148
|
+
Swap (i[k], i[l]);
|
|
149
|
+
return *this;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
NETGEN_INLINE IVec Sort () &&
|
|
153
|
+
{
|
|
154
|
+
for (int k = 0; k < N; k++)
|
|
155
|
+
for (int l = k+1; l < N; l++)
|
|
156
|
+
if (i[k] > i[l])
|
|
157
|
+
Swap (i[k], i[l]);
|
|
158
|
+
return *this;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// access
|
|
162
|
+
NETGEN_INLINE T & operator[] (int j)
|
|
163
|
+
{ return i[j]; }
|
|
164
|
+
|
|
165
|
+
/// access
|
|
166
|
+
NETGEN_INLINE constexpr const T & operator[] (int j) const
|
|
167
|
+
{ return i[j]; }
|
|
168
|
+
|
|
169
|
+
template <size_t J>
|
|
170
|
+
constexpr T get() const { return i[J]; }
|
|
171
|
+
|
|
172
|
+
operator FlatArray<T> () { return FlatArray<T> (N, &i[0]); }
|
|
173
|
+
|
|
174
|
+
NETGEN_INLINE IVec<N,T> & operator= (T value)
|
|
175
|
+
{
|
|
176
|
+
for (int j = 0; j < N; j++)
|
|
177
|
+
i[j] = value;
|
|
178
|
+
return *this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
template <typename T2>
|
|
182
|
+
NETGEN_INLINE IVec<N,T> & operator= (IVec<N,T2> v2)
|
|
183
|
+
{
|
|
184
|
+
for (int j = 0; j < N; j++)
|
|
185
|
+
i[j] = v2[j];
|
|
186
|
+
return *this;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
template <typename... Ts>
|
|
190
|
+
operator std::tuple<Ts...> ()
|
|
191
|
+
{
|
|
192
|
+
return MakeTupleFromInt<N>()(*this);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
bool Contains (T val)
|
|
196
|
+
{
|
|
197
|
+
for (int j = 0; j < N; j++)
|
|
198
|
+
if (i[j] == val) return true;
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/// sort 2 integers
|
|
204
|
+
template <>
|
|
205
|
+
NETGEN_INLINE IVec<2> & IVec<2>::Sort () &
|
|
206
|
+
{
|
|
207
|
+
if (i[0] > i[1]) Swap (i[0], i[1]);
|
|
208
|
+
return *this;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
template <>
|
|
212
|
+
NETGEN_INLINE IVec<2> IVec<2>::Sort () &&
|
|
213
|
+
{
|
|
214
|
+
if (i[0] > i[1]) Swap (i[0], i[1]);
|
|
215
|
+
return *this;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/// sort 3 integers
|
|
219
|
+
template <>
|
|
220
|
+
NETGEN_INLINE IVec<3> IVec<3>::Sort () &&
|
|
221
|
+
{
|
|
222
|
+
if (i[0] > i[1]) Swap (i[0], i[1]);
|
|
223
|
+
if (i[1] > i[2]) Swap (i[1], i[2]);
|
|
224
|
+
if (i[0] > i[1]) Swap (i[0], i[1]);
|
|
225
|
+
return *this;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/// Print integers
|
|
229
|
+
template <int N, typename T>
|
|
230
|
+
inline ostream & operator<<(ostream & s, const IVec<N,T> & i2)
|
|
231
|
+
{
|
|
232
|
+
for (int j = 0; j < N; j++)
|
|
233
|
+
s << (int) i2[j] << " ";
|
|
234
|
+
return s;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
template <int N, typename T>
|
|
238
|
+
auto begin(const IVec<N,T> & ind)
|
|
239
|
+
{
|
|
240
|
+
return AOWrapperIterator<IVec<N,T>> (ind, 0);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
template <int N, typename T>
|
|
244
|
+
auto end(const IVec<N,T> & ind)
|
|
245
|
+
{
|
|
246
|
+
return AOWrapperIterator<IVec<N,T>> (ind, N);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
template <int N, typename TI>
|
|
255
|
+
NETGEN_INLINE size_t HashValue (const IVec<N,TI> & ind, size_t size)
|
|
256
|
+
{
|
|
257
|
+
IVec<N,size_t> lind = ind;
|
|
258
|
+
size_t sum = 0;
|
|
259
|
+
for (int i = 0; i < N; i++)
|
|
260
|
+
sum += lind[i];
|
|
261
|
+
return sum % size;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/// hash value of 1 int
|
|
265
|
+
template <typename TI>
|
|
266
|
+
NETGEN_INLINE size_t HashValue (const IVec<1,TI> & ind, size_t size)
|
|
267
|
+
{
|
|
268
|
+
return ind[0] % size;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/// hash value of 2 int
|
|
272
|
+
template <typename TI>
|
|
273
|
+
NETGEN_INLINE size_t HashValue (const IVec<2,TI> & ind, size_t size)
|
|
274
|
+
{
|
|
275
|
+
IVec<2,size_t> lind = ind;
|
|
276
|
+
return (113*lind[0]+lind[1]) % size;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/// hash value of 3 int
|
|
280
|
+
template <typename TI>
|
|
281
|
+
NETGEN_INLINE size_t HashValue (const IVec<3,TI> & ind, size_t size)
|
|
282
|
+
{
|
|
283
|
+
IVec<3,size_t> lind = ind;
|
|
284
|
+
return (113*lind[0]+59*lind[1]+lind[2]) % size;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
NETGEN_INLINE size_t HashValue (size_t ind, size_t size)
|
|
288
|
+
{
|
|
289
|
+
return ind%size;
|
|
290
|
+
}
|
|
291
|
+
NETGEN_INLINE size_t HashValue (int ind, size_t size)
|
|
292
|
+
{
|
|
293
|
+
return size_t(ind)%size;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
template <int N, typename TI>
|
|
303
|
+
NETGEN_INLINE constexpr size_t HashValue2 (const IVec<N,TI> & ind, size_t mask)
|
|
304
|
+
{
|
|
305
|
+
IVec<N,size_t> lind = ind;
|
|
306
|
+
size_t sum = 0;
|
|
307
|
+
for (int i = 0; i < N; i++)
|
|
308
|
+
sum += lind[i];
|
|
309
|
+
return sum & mask;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/// hash value of 1 int
|
|
313
|
+
template <typename TI>
|
|
314
|
+
NETGEN_INLINE constexpr size_t HashValue2 (const IVec<1,TI> & ind, size_t mask)
|
|
315
|
+
{
|
|
316
|
+
return ind[0] & mask;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/// hash value of 2 int
|
|
320
|
+
template <typename TI>
|
|
321
|
+
NETGEN_INLINE constexpr size_t HashValue2 (const IVec<2,TI> & ind, size_t mask)
|
|
322
|
+
{
|
|
323
|
+
IVec<2,size_t> lind = ind;
|
|
324
|
+
return (113*lind[0]+lind[1]) & mask;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/// hash value of 3 int
|
|
328
|
+
template <typename TI>
|
|
329
|
+
NETGEN_INLINE constexpr size_t HashValue2 (const IVec<3,TI> & ind, size_t mask)
|
|
330
|
+
{
|
|
331
|
+
IVec<3,size_t> lind = ind;
|
|
332
|
+
return (113*lind[0]+59*lind[1]+lind[2]) & mask;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
NETGEN_INLINE constexpr size_t HashValue2 (size_t ind, size_t mask)
|
|
336
|
+
{
|
|
337
|
+
return ind & mask;
|
|
338
|
+
}
|
|
339
|
+
NETGEN_INLINE constexpr size_t HashValue2 (int ind, size_t mask)
|
|
340
|
+
{
|
|
341
|
+
return size_t(ind) & mask;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
// using ngstd::max;
|
|
349
|
+
|
|
350
|
+
template <int D, typename T>
|
|
351
|
+
NETGEN_INLINE T Max (const IVec<D,T> & i)
|
|
352
|
+
{
|
|
353
|
+
if (D == 0) return 0;
|
|
354
|
+
T m = i[0];
|
|
355
|
+
for (int j = 1; j < D; j++)
|
|
356
|
+
if (i[j] > m) m = i[j];
|
|
357
|
+
return m;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
template <int D, typename T>
|
|
361
|
+
NETGEN_INLINE T Min (const IVec<D,T> & i)
|
|
362
|
+
{
|
|
363
|
+
if (D == 0) return 0;
|
|
364
|
+
T m = i[0];
|
|
365
|
+
for (int j = 1; j < D; j++)
|
|
366
|
+
if (i[j] < m) m = i[j];
|
|
367
|
+
return m;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
template <int D, typename T>
|
|
371
|
+
NETGEN_INLINE IVec<D,T> Max (IVec<D,T> i1, IVec<D,T> i2)
|
|
372
|
+
{
|
|
373
|
+
IVec<D,T> tmp;
|
|
374
|
+
for (int i = 0; i < D; i++)
|
|
375
|
+
tmp[i] = std::max(i1[i], i2[i]);
|
|
376
|
+
return tmp;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
template <int D, typename T>
|
|
380
|
+
NETGEN_INLINE IVec<D,T> operator+ (IVec<D,T> i1, IVec<D,T> i2)
|
|
381
|
+
{
|
|
382
|
+
IVec<D,T> tmp;
|
|
383
|
+
for (int i = 0; i < D; i++)
|
|
384
|
+
tmp[i] = i1[i]+i2[i];
|
|
385
|
+
return tmp;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
A hash-table.
|
|
400
|
+
Generic identifiers are mapped to the generic type T.
|
|
401
|
+
An open hashtable. The table is implemented by a DynamicTable.
|
|
402
|
+
Identifiers must provide a HashValue method.
|
|
403
|
+
*/
|
|
404
|
+
template <class T_HASH, class T>
|
|
405
|
+
class HashTable
|
|
406
|
+
{
|
|
407
|
+
/*
|
|
408
|
+
DynamicTable<T_HASH> hash;
|
|
409
|
+
DynamicTable<T> cont;
|
|
410
|
+
*/
|
|
411
|
+
DynamicTable<std::pair<T_HASH,T>> table;
|
|
412
|
+
public:
|
|
413
|
+
/// Constructs a hashtable of size bags.
|
|
414
|
+
NETGEN_INLINE HashTable (int size)
|
|
415
|
+
// : hash(size), cont(size)
|
|
416
|
+
: table(size)
|
|
417
|
+
{ ; }
|
|
418
|
+
NETGEN_INLINE ~HashTable () { ; }
|
|
419
|
+
|
|
420
|
+
/// Sets identifier ahash to value acont
|
|
421
|
+
void Set (const T_HASH & ahash, const T & acont)
|
|
422
|
+
{
|
|
423
|
+
int bnr = HashValue (ahash, Size());
|
|
424
|
+
int pos = CheckPosition (bnr, ahash);
|
|
425
|
+
if (pos != -1)
|
|
426
|
+
// cont.Set (bnr, pos, acont);
|
|
427
|
+
table[bnr][pos].second = acont;
|
|
428
|
+
else
|
|
429
|
+
{
|
|
430
|
+
// hash.Add (bnr, ahash);
|
|
431
|
+
// cont.Add (bnr, acont);
|
|
432
|
+
table.Add (bnr, std::make_pair(ahash, acont));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/// get value of identifier ahash, exception if unused
|
|
437
|
+
const T & Get (const T_HASH & ahash) const
|
|
438
|
+
{
|
|
439
|
+
int bnr = HashValue (ahash, Size());
|
|
440
|
+
int pos = Position (bnr, ahash);
|
|
441
|
+
// return cont.Get (bnr, pos);
|
|
442
|
+
return table.Get (bnr, pos).second;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/// get value of identifier ahash, exception if unused
|
|
446
|
+
const T & Get (int bnr, int pos) const
|
|
447
|
+
{
|
|
448
|
+
// return cont.Get (bnr, pos);
|
|
449
|
+
return table.Get (bnr, pos).second;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/// is identifier used ?
|
|
453
|
+
bool Used (const T_HASH & ahash) const
|
|
454
|
+
{
|
|
455
|
+
// return (CheckPosition (HashValue (ahash, hash.Size()), ahash) != -1);
|
|
456
|
+
return (CheckPosition (HashValue (ahash, table.Size()), ahash) != -1);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/// is identifier used ?
|
|
460
|
+
bool Used (const T_HASH & ahash, int & bnr, int & pos) const
|
|
461
|
+
{
|
|
462
|
+
// bnr = HashValue (ahash, hash.Size());
|
|
463
|
+
bnr = HashValue (ahash, Size());
|
|
464
|
+
pos = CheckPosition (bnr, ahash);
|
|
465
|
+
return (pos != -1);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
/// number of hash entries
|
|
470
|
+
size_t Size () const
|
|
471
|
+
{
|
|
472
|
+
// return hash.Size();
|
|
473
|
+
return table.Size();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/// size of hash entry
|
|
477
|
+
size_t EntrySize (int bnr) const
|
|
478
|
+
{
|
|
479
|
+
// return hash[bnr].Size();
|
|
480
|
+
return table[bnr].Size();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/// get identifier and value of entry bnr, position colnr
|
|
484
|
+
void GetData (int bnr, int colnr, T_HASH & ahash, T & acont) const
|
|
485
|
+
{
|
|
486
|
+
// ahash = hash[bnr][colnr];
|
|
487
|
+
// acont = cont[bnr][colnr];
|
|
488
|
+
ahash = table[bnr][colnr].first;
|
|
489
|
+
acont = table[bnr][colnr].second;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/// set identifier and value of entry bnr, position colnr
|
|
493
|
+
void SetData (int bnr, int colnr, const T_HASH & ahash, const T & acont)
|
|
494
|
+
{
|
|
495
|
+
// hash[bnr][colnr] = ahash;
|
|
496
|
+
// cont[bnr][colnr] = acont;
|
|
497
|
+
table[bnr][colnr] = std::make_pair(ahash, acont);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/// returns position of index. returns -1 on unused
|
|
501
|
+
int CheckPosition (int bnr, const T_HASH & ind) const
|
|
502
|
+
{
|
|
503
|
+
/*
|
|
504
|
+
for (int i = 0; i < hash[bnr].Size(); i++)
|
|
505
|
+
if (hash[bnr][i] == ind)
|
|
506
|
+
return i;
|
|
507
|
+
*/
|
|
508
|
+
for (int i = 0; i < table[bnr].Size(); i++)
|
|
509
|
+
if (table[bnr][i].first == ind)
|
|
510
|
+
return i;
|
|
511
|
+
return -1;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/// returns position of index. exception on unused
|
|
515
|
+
int Position (int bnr, const T_HASH & ind) const
|
|
516
|
+
{
|
|
517
|
+
for (int i = 0; i < table[bnr].Size(); i++)
|
|
518
|
+
if (table[bnr][i].first == ind)
|
|
519
|
+
return i;
|
|
520
|
+
throw Exception ("Ask for unused hash-value");
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
T & operator[] (T_HASH ahash)
|
|
524
|
+
{
|
|
525
|
+
int bnr, pos;
|
|
526
|
+
if (Used (ahash, bnr, pos))
|
|
527
|
+
return table[bnr][pos].second;
|
|
528
|
+
else
|
|
529
|
+
{
|
|
530
|
+
// hash.Add (bnr, ahash);
|
|
531
|
+
// cont.Add (bnr, T(0));
|
|
532
|
+
table.Add (bnr, std::make_pair(ahash, T(0)));
|
|
533
|
+
// return cont[bnr][cont[bnr].Size()-1];
|
|
534
|
+
return table[bnr][table[bnr].Size()-1].second;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const T & operator[] (T_HASH ahash) const
|
|
539
|
+
{
|
|
540
|
+
return Get(ahash);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
class Iterator
|
|
544
|
+
{
|
|
545
|
+
const HashTable & ht;
|
|
546
|
+
int bnr;
|
|
547
|
+
int pos;
|
|
548
|
+
public:
|
|
549
|
+
Iterator (const HashTable & aht, int abnr, int apos)
|
|
550
|
+
: ht(aht), bnr(abnr), pos(apos) { ; }
|
|
551
|
+
std::pair<T_HASH,T> operator* () const
|
|
552
|
+
{
|
|
553
|
+
T_HASH hash;
|
|
554
|
+
T data;
|
|
555
|
+
ht.GetData (bnr, pos, hash, data);
|
|
556
|
+
return std::pair<T_HASH,T> (hash, data);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
Iterator & operator++()
|
|
560
|
+
{
|
|
561
|
+
pos++;
|
|
562
|
+
if (pos == ht.EntrySize(bnr))
|
|
563
|
+
{
|
|
564
|
+
pos = 0;
|
|
565
|
+
bnr++;
|
|
566
|
+
for ( ; bnr < ht.Size(); bnr++)
|
|
567
|
+
if (ht.EntrySize(bnr) != 0) break;
|
|
568
|
+
}
|
|
569
|
+
return *this;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
bool operator!= (const Iterator & it2) { return bnr != it2.bnr || pos != it2.pos; }
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
Iterator begin () const
|
|
576
|
+
{
|
|
577
|
+
int i = 0;
|
|
578
|
+
for ( ; i < Size(); i++)
|
|
579
|
+
if (EntrySize(i) != 0) break;
|
|
580
|
+
return Iterator(*this, i,0);
|
|
581
|
+
}
|
|
582
|
+
Iterator end () const { return Iterator(*this, Size(),0); }
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
inline size_t RoundUp2 (size_t i)
|
|
588
|
+
{
|
|
589
|
+
size_t res = 1;
|
|
590
|
+
while (res < i) res *= 2; // hope it will never be too large
|
|
591
|
+
return res;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
template <typename T>
|
|
595
|
+
constexpr inline T InvalidHash() { return T(-1); }
|
|
596
|
+
|
|
597
|
+
template <typename T_HASH>
|
|
598
|
+
struct CHT_trait
|
|
599
|
+
{
|
|
600
|
+
constexpr static inline T_HASH Invalid() { return InvalidHash<T_HASH>(); }
|
|
601
|
+
constexpr static inline size_t HashValue (const T_HASH & hash, size_t mask) { return HashValue2(hash, mask); }
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
template <typename T1, typename T2>
|
|
605
|
+
struct CHT_trait<std::tuple<T1,T2>>
|
|
606
|
+
{
|
|
607
|
+
constexpr static inline std::tuple<T1,T2> Invalid() { return { CHT_trait<T1>::Invalid(), CHT_trait<T2>::Invalid() } ; }
|
|
608
|
+
constexpr static inline size_t HashValue (const std::tuple<T1,T2> & hash, size_t mask)
|
|
609
|
+
{
|
|
610
|
+
return (CHT_trait<T1>::HashValue(std::get<0>(hash), mask) + CHT_trait<T2>::HashValue(std::get<1>(hash),mask)) & mask;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
A closed hash-table.
|
|
618
|
+
All information is stored in one fixed array.
|
|
619
|
+
The array should be allocated with the double size of the expected number of entries.
|
|
620
|
+
*/
|
|
621
|
+
template <class T_HASH, class T>
|
|
622
|
+
class ClosedHashTable
|
|
623
|
+
{
|
|
624
|
+
protected:
|
|
625
|
+
///
|
|
626
|
+
size_t size;
|
|
627
|
+
size_t mask;
|
|
628
|
+
///
|
|
629
|
+
size_t used = 0;
|
|
630
|
+
///
|
|
631
|
+
Array<T_HASH> hash;
|
|
632
|
+
///
|
|
633
|
+
Array<T> cont;
|
|
634
|
+
///
|
|
635
|
+
// T_HASH invalid = -1;
|
|
636
|
+
// static constexpr T_HASH invalid = InvalidHash<T_HASH>();
|
|
637
|
+
static constexpr T_HASH invalid = CHT_trait<T_HASH>::Invalid();
|
|
638
|
+
public:
|
|
639
|
+
///
|
|
640
|
+
ClosedHashTable (size_t asize = 128)
|
|
641
|
+
: size(RoundUp2(asize)), hash(size), cont(size)
|
|
642
|
+
{
|
|
643
|
+
mask = size-1;
|
|
644
|
+
// hash = T_HASH(invalid);
|
|
645
|
+
// hash = InvalidHash<T_HASH>();
|
|
646
|
+
hash = CHT_trait<T_HASH>::Invalid();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
ClosedHashTable (ClosedHashTable && ht2) = default;
|
|
650
|
+
|
|
651
|
+
/// allocate on local heap
|
|
652
|
+
ClosedHashTable (size_t asize, LocalHeap & lh)
|
|
653
|
+
: size(RoundUp2(asize)), mask(size-1), hash(size, lh), cont(size, lh)
|
|
654
|
+
{
|
|
655
|
+
// hash = T_HASH(invalid);
|
|
656
|
+
hash = InvalidHash<T_HASH>();
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
ClosedHashTable & operator= (ClosedHashTable && ht2) = default;
|
|
660
|
+
|
|
661
|
+
///
|
|
662
|
+
size_t Size() const
|
|
663
|
+
{
|
|
664
|
+
return size;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/// is position used
|
|
668
|
+
bool UsedPos (size_t pos) const
|
|
669
|
+
{
|
|
670
|
+
return ! (hash[pos] == invalid);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/// number of used elements
|
|
674
|
+
size_t UsedElements () const
|
|
675
|
+
{
|
|
676
|
+
return used;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
size_t Position (const T_HASH ind) const
|
|
680
|
+
{
|
|
681
|
+
// size_t i = HashValue2(ind, mask);
|
|
682
|
+
size_t i = CHT_trait<T_HASH>::HashValue(ind, mask);
|
|
683
|
+
while (true)
|
|
684
|
+
{
|
|
685
|
+
if (hash[i] == ind) return i;
|
|
686
|
+
if (hash[i] == invalid) return size_t(-1);
|
|
687
|
+
i = (i+1) & mask;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
void DoubleSize()
|
|
692
|
+
{
|
|
693
|
+
ClosedHashTable tmp(2*Size());
|
|
694
|
+
for (auto both : *this)
|
|
695
|
+
tmp[both.first] = both.second;
|
|
696
|
+
*this = std::move(tmp);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// returns true if new position is created
|
|
700
|
+
bool PositionCreate (const T_HASH ind, size_t & apos)
|
|
701
|
+
{
|
|
702
|
+
if (UsedElements()*2 > Size()) DoubleSize();
|
|
703
|
+
|
|
704
|
+
// size_t i = HashValue2 (ind, mask);
|
|
705
|
+
size_t i = CHT_trait<T_HASH>::HashValue (ind, mask);
|
|
706
|
+
|
|
707
|
+
while (true)
|
|
708
|
+
{
|
|
709
|
+
if (hash[i] == invalid)
|
|
710
|
+
{
|
|
711
|
+
hash[i] = ind;
|
|
712
|
+
apos = i;
|
|
713
|
+
used++;
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
if (hash[i] == ind)
|
|
717
|
+
{
|
|
718
|
+
apos = i;
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
i = (i+1) & mask;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
///
|
|
727
|
+
void Set (const T_HASH & ahash, const T & acont)
|
|
728
|
+
{
|
|
729
|
+
size_t pos;
|
|
730
|
+
PositionCreate (ahash, pos);
|
|
731
|
+
hash[pos] = ahash;
|
|
732
|
+
cont[pos] = acont;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
///
|
|
736
|
+
const T & Get (const T_HASH & ahash) const
|
|
737
|
+
{
|
|
738
|
+
size_t pos = Position (ahash);
|
|
739
|
+
if (pos == size_t(-1))
|
|
740
|
+
throw Exception (std::string("illegal key: ") + ToString(ahash) );
|
|
741
|
+
return cont[pos];
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
///
|
|
745
|
+
bool Used (const T_HASH & ahash) const
|
|
746
|
+
{
|
|
747
|
+
return (Position (ahash) != size_t(-1));
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
inline std::optional<T> GetIfUsed (const T_HASH & ahash) const
|
|
751
|
+
{
|
|
752
|
+
size_t pos = Position (ahash);
|
|
753
|
+
if (pos != size_t(-1))
|
|
754
|
+
return cont[pos];
|
|
755
|
+
else
|
|
756
|
+
return std::nullopt;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
void SetData (size_t pos, const T_HASH & ahash, const T & acont)
|
|
761
|
+
{
|
|
762
|
+
hash[pos] = ahash;
|
|
763
|
+
cont[pos] = acont;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
void GetData (size_t pos, T_HASH & ahash, T & acont) const
|
|
767
|
+
{
|
|
768
|
+
ahash = hash[pos];
|
|
769
|
+
acont = cont[pos];
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
void SetData (size_t pos, const T & acont)
|
|
773
|
+
{
|
|
774
|
+
cont[pos] = acont;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
void GetData (size_t pos, T & acont) const
|
|
778
|
+
{
|
|
779
|
+
acont = cont[pos];
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
T GetData (size_t pos) const
|
|
783
|
+
{
|
|
784
|
+
return cont[pos];
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
std::pair<T_HASH,T> GetBoth (size_t pos) const
|
|
788
|
+
{
|
|
789
|
+
return std::pair<T_HASH,T> (hash[pos], cont[pos]);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
const T & operator[] (T_HASH key) const { return Get(key); }
|
|
793
|
+
T & operator[] (T_HASH key)
|
|
794
|
+
{
|
|
795
|
+
size_t pos;
|
|
796
|
+
PositionCreate(key, pos);
|
|
797
|
+
return cont[pos];
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
void SetSize (size_t asize)
|
|
801
|
+
{
|
|
802
|
+
size = asize;
|
|
803
|
+
hash.Alloc(size);
|
|
804
|
+
cont.Alloc(size);
|
|
805
|
+
|
|
806
|
+
// for (size_t i = 0; i < size; i++)
|
|
807
|
+
// hash[i] = invalid;
|
|
808
|
+
hash = T_HASH(invalid);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
void Delete (T_HASH key)
|
|
812
|
+
{
|
|
813
|
+
size_t pos = Position(key);
|
|
814
|
+
if (pos == size_t(-1)) return;
|
|
815
|
+
hash[pos] = invalid; used--;
|
|
816
|
+
|
|
817
|
+
while (1)
|
|
818
|
+
{
|
|
819
|
+
size_t nextpos = pos+1;
|
|
820
|
+
if (nextpos == size) nextpos = 0;
|
|
821
|
+
if (hash[nextpos] == invalid) break;
|
|
822
|
+
|
|
823
|
+
auto key = hash[nextpos];
|
|
824
|
+
auto val = cont[nextpos];
|
|
825
|
+
hash[pos] = invalid; used--;
|
|
826
|
+
|
|
827
|
+
Set (key, val);
|
|
828
|
+
pos = nextpos;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
void DeleteData()
|
|
833
|
+
{
|
|
834
|
+
hash = T_HASH(invalid);
|
|
835
|
+
used = 0;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
template <typename ARCHIVE>
|
|
839
|
+
void DoArchive (ARCHIVE& ar)
|
|
840
|
+
{
|
|
841
|
+
ar & hash & cont;
|
|
842
|
+
ar & size & mask & used;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
struct EndIterator { };
|
|
846
|
+
|
|
847
|
+
class Iterator
|
|
848
|
+
{
|
|
849
|
+
const ClosedHashTable & tab;
|
|
850
|
+
size_t nr;
|
|
851
|
+
public:
|
|
852
|
+
Iterator (const ClosedHashTable & _tab, size_t _nr)
|
|
853
|
+
: tab(_tab), nr(_nr)
|
|
854
|
+
{
|
|
855
|
+
while (nr < tab.Size() && !tab.UsedPos(nr)) nr++;
|
|
856
|
+
}
|
|
857
|
+
Iterator & operator++()
|
|
858
|
+
{
|
|
859
|
+
nr++;
|
|
860
|
+
while (nr < tab.Size() && !tab.UsedPos(nr)) nr++;
|
|
861
|
+
return *this;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
bool operator!= (EndIterator it2) { return nr != tab.Size(); }
|
|
865
|
+
|
|
866
|
+
auto operator* () const { return tab.GetBoth(nr); }
|
|
867
|
+
};
|
|
868
|
+
|
|
869
|
+
Iterator begin() const { return Iterator(*this, 0); }
|
|
870
|
+
EndIterator end() const { return EndIterator(); }
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
template <class T_HASH, class T>
|
|
874
|
+
ostream & operator<< (ostream & ost,
|
|
875
|
+
const ClosedHashTable<T_HASH,T> & tab)
|
|
876
|
+
{
|
|
877
|
+
/*
|
|
878
|
+
for (size_t i = 0; i < tab.Size(); i++)
|
|
879
|
+
if (tab.UsedPos(i))
|
|
880
|
+
{
|
|
881
|
+
T_HASH key;
|
|
882
|
+
T val;
|
|
883
|
+
tab.GetData (i, key, val);
|
|
884
|
+
ost << key << ": " << val << ", ";
|
|
885
|
+
}
|
|
886
|
+
*/
|
|
887
|
+
for (auto [key,val] : tab)
|
|
888
|
+
ost << key << ": " << val << ", ";
|
|
889
|
+
return ost;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
template <typename TI>
|
|
893
|
+
NETGEN_INLINE size_t HashValue (const IVec<3,TI> ind)
|
|
894
|
+
{
|
|
895
|
+
IVec<3,size_t> lind = ind;
|
|
896
|
+
return 113*lind[0]+59*lind[1]+lind[2];
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
template <typename TI>
|
|
900
|
+
NETGEN_INLINE size_t HashValue (const IVec<2,TI> ind)
|
|
901
|
+
{
|
|
902
|
+
IVec<2,size_t> lind = ind;
|
|
903
|
+
return 113*lind[0]+lind[1];
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
template <typename TI>
|
|
907
|
+
NETGEN_INLINE size_t HashValue (const IVec<1,TI> ind)
|
|
908
|
+
{
|
|
909
|
+
return ind[0];
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
template <typename TKEY, typename T>
|
|
914
|
+
class ParallelHashTable
|
|
915
|
+
{
|
|
916
|
+
class ClosedHT
|
|
917
|
+
{
|
|
918
|
+
Array<TKEY> keys;
|
|
919
|
+
Array<T> values;
|
|
920
|
+
size_t used;
|
|
921
|
+
|
|
922
|
+
public:
|
|
923
|
+
ClosedHT(size_t asize = 256) : keys(asize), values(asize), used(0)
|
|
924
|
+
{
|
|
925
|
+
keys = TKEY(-1);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
size_t Size () const { return keys.Size(); }
|
|
929
|
+
size_t Used () const { return used; }
|
|
930
|
+
|
|
931
|
+
ClosedHT & operator= (ClosedHT&&) = default;
|
|
932
|
+
|
|
933
|
+
void Resize()
|
|
934
|
+
{
|
|
935
|
+
ClosedHT tmp(keys.Size()*2);
|
|
936
|
+
for (size_t i = 0; i < keys.Size(); i++)
|
|
937
|
+
if (keys[i] != TKEY(-1))
|
|
938
|
+
{
|
|
939
|
+
TKEY hkey = keys[i];
|
|
940
|
+
T hval = values[i];
|
|
941
|
+
size_t hhash = HashValue(hkey);
|
|
942
|
+
size_t hhash2 = hhash / 256;
|
|
943
|
+
tmp.DoSave(hkey, [hval] (T & v) { v = hval; }, hhash2);
|
|
944
|
+
}
|
|
945
|
+
(*this) = std::move(tmp);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
template <typename TFUNC>
|
|
949
|
+
auto Do (TKEY key, TFUNC func, size_t hash)
|
|
950
|
+
{
|
|
951
|
+
if (used > keys.Size()/2)
|
|
952
|
+
Resize();
|
|
953
|
+
return DoSave (key, func, hash);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
template <typename TFUNC>
|
|
957
|
+
auto DoSave (TKEY key, TFUNC func, size_t hash)
|
|
958
|
+
{
|
|
959
|
+
size_t pos = hash & (keys.Size()-1);
|
|
960
|
+
while (1)
|
|
961
|
+
{
|
|
962
|
+
if (keys[pos] == key)
|
|
963
|
+
break;
|
|
964
|
+
if (keys[pos] == TKEY(-1))
|
|
965
|
+
{
|
|
966
|
+
keys[pos] = key;
|
|
967
|
+
values[pos] = T(0);
|
|
968
|
+
used++;
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
pos++;
|
|
972
|
+
if (pos == keys.Size()) pos = 0;
|
|
973
|
+
}
|
|
974
|
+
return func(values[pos]);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
T Get (TKEY key, size_t hash)
|
|
978
|
+
{
|
|
979
|
+
size_t pos = hash & (keys.Size()-1);
|
|
980
|
+
while (1)
|
|
981
|
+
{
|
|
982
|
+
if (keys[pos] == key)
|
|
983
|
+
return values[pos];
|
|
984
|
+
if (keys[pos] == TKEY(-1))
|
|
985
|
+
throw Exception ("ParallelHashTable::Get of unused key");
|
|
986
|
+
pos++;
|
|
987
|
+
if (pos == keys.Size()) pos = 0;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
size_t GetCosts (TKEY key, size_t hash)
|
|
992
|
+
{
|
|
993
|
+
size_t pos = hash & (keys.Size()-1);
|
|
994
|
+
size_t costs = 1;
|
|
995
|
+
while (1)
|
|
996
|
+
{
|
|
997
|
+
if (keys[pos] == key)
|
|
998
|
+
return costs;
|
|
999
|
+
if (keys[pos] == TKEY(-1))
|
|
1000
|
+
throw Exception ("ParallelHashTable::Get of unused key");
|
|
1001
|
+
costs++;
|
|
1002
|
+
pos++;
|
|
1003
|
+
if (pos == keys.Size()) pos = 0;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
template <typename TFUNC>
|
|
1009
|
+
void Iterate (TFUNC func) const
|
|
1010
|
+
{
|
|
1011
|
+
for (size_t i = 0; i < keys.Size(); i++)
|
|
1012
|
+
if (keys[i] != TKEY(-1))
|
|
1013
|
+
func(keys[i], values[i]);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
void Print (ostream & ost) const
|
|
1017
|
+
{
|
|
1018
|
+
for (size_t i = 0; i < keys.Size(); i++)
|
|
1019
|
+
if (keys[i] != TKEY(-1))
|
|
1020
|
+
ost << keys[i] << ": " << values[i] << ", ";
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
Array<ClosedHT> hts;
|
|
1025
|
+
class alignas(64) MyMutex64 : public MyMutex { };
|
|
1026
|
+
|
|
1027
|
+
Array<MyMutex64> locks;
|
|
1028
|
+
|
|
1029
|
+
public:
|
|
1030
|
+
ParallelHashTable() : hts(256), locks(256) { ; }
|
|
1031
|
+
size_t NumBuckets() const { return hts.Size(); }
|
|
1032
|
+
auto & Bucket(size_t nr) { return hts[nr]; }
|
|
1033
|
+
size_t BucketSize(size_t nr) const { return hts[nr].Size(); }
|
|
1034
|
+
size_t Used (size_t nr) const { return hts[nr].Used(); }
|
|
1035
|
+
size_t Used() const
|
|
1036
|
+
{
|
|
1037
|
+
size_t used = 0;
|
|
1038
|
+
for (auto & ht : hts)
|
|
1039
|
+
used += ht.Used();
|
|
1040
|
+
return used;
|
|
1041
|
+
}
|
|
1042
|
+
template <typename TFUNC>
|
|
1043
|
+
auto Do (TKEY key, TFUNC func)
|
|
1044
|
+
{
|
|
1045
|
+
size_t hash = HashValue(key);
|
|
1046
|
+
size_t hash1 = hash % 256;
|
|
1047
|
+
size_t hash2 = hash / 256;
|
|
1048
|
+
|
|
1049
|
+
// locks[hash1].lock();
|
|
1050
|
+
// hts[hash1].Do (key, func, hash2);
|
|
1051
|
+
// locks[hash1].unlock();
|
|
1052
|
+
MyLock lock(locks[hash1]);
|
|
1053
|
+
return hts[hash1].Do (key, func, hash2);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
T Get (TKEY key)
|
|
1057
|
+
{
|
|
1058
|
+
size_t hash = HashValue(key);
|
|
1059
|
+
size_t hash1 = hash % 256;
|
|
1060
|
+
size_t hash2 = hash / 256;
|
|
1061
|
+
|
|
1062
|
+
return hts[hash1].Get (key, hash2);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
auto GetCosts (TKEY key)
|
|
1066
|
+
{
|
|
1067
|
+
size_t hash = HashValue(key);
|
|
1068
|
+
size_t hash1 = hash % 256;
|
|
1069
|
+
size_t hash2 = hash / 256;
|
|
1070
|
+
|
|
1071
|
+
return hts[hash1].GetCosts (key, hash2);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
template <typename TFUNC>
|
|
1076
|
+
void Iterate(TFUNC func) const
|
|
1077
|
+
{
|
|
1078
|
+
for (auto & bucket : hts)
|
|
1079
|
+
bucket.Iterate(func);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
template <typename TFUNC>
|
|
1083
|
+
void Iterate(size_t nr, TFUNC func) const
|
|
1084
|
+
{
|
|
1085
|
+
hts[nr].Iterate(func);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
template <typename FUNC>
|
|
1090
|
+
void IterateParallel (FUNC func)
|
|
1091
|
+
{
|
|
1092
|
+
Array<size_t> base(NumBuckets());
|
|
1093
|
+
size_t sum = 0;
|
|
1094
|
+
for (size_t i = 0; i < NumBuckets(); i++)
|
|
1095
|
+
{
|
|
1096
|
+
base[i] = sum;
|
|
1097
|
+
sum += Used(i);
|
|
1098
|
+
}
|
|
1099
|
+
ParallelFor(NumBuckets(),
|
|
1100
|
+
[&] (size_t nr)
|
|
1101
|
+
{
|
|
1102
|
+
size_t cnt = base[nr];
|
|
1103
|
+
Iterate(nr,
|
|
1104
|
+
[&cnt, func] (TKEY key, T val)
|
|
1105
|
+
{
|
|
1106
|
+
func(cnt, key, val);
|
|
1107
|
+
cnt++;
|
|
1108
|
+
});
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
void Print (ostream & ost) const
|
|
1116
|
+
{
|
|
1117
|
+
for (size_t i : Range(hts))
|
|
1118
|
+
if (hts[i].Used() > 0)
|
|
1119
|
+
{
|
|
1120
|
+
ost << i << ": ";
|
|
1121
|
+
hts[i].Print(ost);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
template <typename TKEY, typename T>
|
|
1127
|
+
inline ostream & operator<< (ostream & ost, const ParallelHashTable<TKEY,T> & ht)
|
|
1128
|
+
{
|
|
1129
|
+
ht.Print(ost);
|
|
1130
|
+
return ost;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
template <class T, class IndexType>
|
|
1142
|
+
class CompressedTable
|
|
1143
|
+
{
|
|
1144
|
+
Table<T, size_t> table;
|
|
1145
|
+
ClosedHashTable<IndexType, size_t> idmap;
|
|
1146
|
+
|
|
1147
|
+
public:
|
|
1148
|
+
CompressedTable (Table<T, size_t> && atable, ClosedHashTable<IndexType, size_t> && aidmap)
|
|
1149
|
+
: table(std::move(atable)), idmap(std::move(aidmap)) { }
|
|
1150
|
+
|
|
1151
|
+
FlatArray<T> operator[](IndexType id) const
|
|
1152
|
+
{
|
|
1153
|
+
if (auto nr = idmap.GetIfUsed(id))
|
|
1154
|
+
return table[*nr];
|
|
1155
|
+
else
|
|
1156
|
+
return { 0, nullptr };
|
|
1157
|
+
}
|
|
1158
|
+
auto & GetTable() { return table; }
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
template <class T, typename IndexType>
|
|
1163
|
+
class CompressedTableCreator
|
|
1164
|
+
{
|
|
1165
|
+
protected:
|
|
1166
|
+
int mode; // 1 .. cnt, 2 .. cnt entries, 3 .. fill table
|
|
1167
|
+
size_t nd; // number of entries;
|
|
1168
|
+
ClosedHashTable<IndexType, size_t> idmap;
|
|
1169
|
+
Array<int,size_t> cnt;
|
|
1170
|
+
Table<T,size_t> table;
|
|
1171
|
+
public:
|
|
1172
|
+
CompressedTableCreator()
|
|
1173
|
+
{ nd = 0; mode = 1; }
|
|
1174
|
+
|
|
1175
|
+
CompressedTable<T,IndexType> MoveTable()
|
|
1176
|
+
{
|
|
1177
|
+
return { std::move(table), std::move(idmap) };
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
bool Done () { return mode > 3; }
|
|
1181
|
+
void operator++(int) { SetMode (mode+1); }
|
|
1182
|
+
|
|
1183
|
+
int GetMode () const { return mode; }
|
|
1184
|
+
void SetMode (int amode)
|
|
1185
|
+
{
|
|
1186
|
+
mode = amode;
|
|
1187
|
+
if (mode == 2)
|
|
1188
|
+
{
|
|
1189
|
+
cnt.SetSize(nd);
|
|
1190
|
+
cnt = 0;
|
|
1191
|
+
}
|
|
1192
|
+
if (mode == 3)
|
|
1193
|
+
{
|
|
1194
|
+
table = Table<T,size_t> (cnt);
|
|
1195
|
+
cnt = 0;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
void Add (IndexType blocknr, const T & data)
|
|
1200
|
+
{
|
|
1201
|
+
switch (mode)
|
|
1202
|
+
{
|
|
1203
|
+
case 1:
|
|
1204
|
+
{
|
|
1205
|
+
if (!idmap.Used (blocknr))
|
|
1206
|
+
idmap[blocknr] = nd++;
|
|
1207
|
+
break;
|
|
1208
|
+
}
|
|
1209
|
+
case 2:
|
|
1210
|
+
cnt[idmap.Get(blocknr)]++;
|
|
1211
|
+
break;
|
|
1212
|
+
case 3:
|
|
1213
|
+
size_t cblock = idmap.Get(blocknr);
|
|
1214
|
+
int ci = cnt[cblock]++;
|
|
1215
|
+
table[cblock][ci] = data;
|
|
1216
|
+
break;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
} // namespace ngcore
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
/*
|
|
1237
|
+
#ifdef PARALLEL
|
|
1238
|
+
namespace ngcore {
|
|
1239
|
+
template<int S, typename T>
|
|
1240
|
+
class MPI_typetrait<ngcore::IVec<S, T> >
|
|
1241
|
+
{
|
|
1242
|
+
public:
|
|
1243
|
+
/// gets the MPI datatype
|
|
1244
|
+
static MPI_Datatype MPIType ()
|
|
1245
|
+
{
|
|
1246
|
+
static MPI_Datatype MPI_T = 0;
|
|
1247
|
+
if (!MPI_T)
|
|
1248
|
+
{
|
|
1249
|
+
MPI_Type_contiguous ( S, MPI_typetrait<T>::MPIType(), &MPI_T);
|
|
1250
|
+
MPI_Type_commit ( &MPI_T );
|
|
1251
|
+
}
|
|
1252
|
+
return MPI_T;
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
#endif
|
|
1257
|
+
*/
|
|
1258
|
+
|
|
1259
|
+
namespace ngcore
|
|
1260
|
+
{
|
|
1261
|
+
template<typename T> struct MPI_typetrait;
|
|
1262
|
+
|
|
1263
|
+
template<int S, typename T>
|
|
1264
|
+
struct MPI_typetrait<IVec<S, T> > {
|
|
1265
|
+
static auto MPIType () {
|
|
1266
|
+
return MPI_typetrait<std::array<T,S>>::MPIType();
|
|
1267
|
+
}
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
namespace std
|
|
1274
|
+
{
|
|
1275
|
+
// structured binding support
|
|
1276
|
+
template <auto N, typename T>
|
|
1277
|
+
struct tuple_size<ngcore::IVec<N,T>> : std::integral_constant<std::size_t, N> {};
|
|
1278
|
+
template<size_t N, auto M, typename T> struct tuple_element<N,ngcore::IVec<M,T>> { using type = T; };
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
#endif
|