Compare commits

...

4 Commits

Author SHA1 Message Date
e5c6ccc3d3 CONFIG: bump patch level 2025-08-14 11:04:56 +02:00
af3c9ebb5e BUG: missed removal of pointMesh/boundaryProcAddressing (fixes #3412) 2025-08-14 11:04:25 +02:00
de413eaf9c ENH: pointConstraint: work in binary mode 2025-08-14 11:04:25 +02:00
07945a519f COMP: resolve label 64 compilation ambiguity for Mingw (fixes #3390)
COMP: restrict HashTable maxTableSize to int32 range

- avoids compiler warning about possible overflow (left-shift
  operation) for label 64 compilations and we don't need anything
  larger than int32 HashTable capacity anyhow.

ENH: make nearest power-of-two non-branching (previously brute-force)
2025-08-14 11:04:25 +02:00
8 changed files with 82 additions and 41 deletions

View File

@ -1,2 +1,2 @@
api=2412
patch=0
patch=250814

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,11 +37,30 @@ License
using namespace Foam;
void checkCanonicalSize(label size)
{
const auto n = HashTableCore::canonicalSize(size);
std::ostringstream buf;
buf.setf(std::ios_base::hex, std::ios_base::basefield);
buf << n;
Info<< "hash-table size of " << size
<< " = " << n << " (0x" << buf.str().c_str() << ')' << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
for (label size : { -1, 0, 1, 7, 500, 1024, 1025, 10000, (labelMax-1)} )
{
checkCanonicalSize(size);
}
Info<< nl;
HashTable<scalar> table1
{
{"aaa", 1.0},

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,7 +27,6 @@ License
\*---------------------------------------------------------------------------*/
#include "HashTableCore.H"
#include "uLabel.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -36,51 +35,66 @@ namespace Foam
defineTypeNameAndDebug(HashTableCore, 0);
}
// Approximately labelMax/4
const Foam::label Foam::HashTableCore::maxTableSize(1L << (sizeof(label)*8-3));
// file-scope:
// Minimum internal table size (must be a power of two!)
constexpr int32_t minTableSize = 8;
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::label Foam::HashTableCore::canonicalSize(const label requested_size)
Foam::label Foam::HashTableCore::canonicalSize(const label size) noexcept
{
if (requested_size < 1)
{
return 0;
}
else if (requested_size >= maxTableSize)
{
return maxTableSize;
}
// Enforce power of two for fast modulus in hash index calculations.
// Use unsigned for these calculations.
//
// - The lower limit (8) is somewhat arbitrary, but if the hash table
// is too small, there will be many direct table collisions.
// - The upper limit (approx. labelMax/4) must be a power of two,
// - The upper limit (approx. INT32_MAX/4) must be a power of two,
// need not be extremely large for hashing.
uLabel powerOfTwo = 8u; // lower-limit
const uLabel size = requested_size;
if (size <= powerOfTwo)
if (size <= minTableSize)
{
return powerOfTwo;
return (size < 1 ? 0 : minTableSize);
}
else if (size > maxTableSize/2)
{
return maxTableSize;
}
if (size & (size-1)) // <- Modulus of i^2
{
// Determine power-of-two. Brute-force is fast enough.
while (powerOfTwo < size)
{
powerOfTwo <<= 1;
}
// Determine power-of-two with glibc (may or may not be faster):
//
// return (1 << (32-__builtin_clz(int32_t(size-1))));
return powerOfTwo;
if (!(size & (size-1)))
{
// Already a power-of-two...
return size;
}
return size;
// Non-branching for 32-bit
// [https://graphics.stanford.edu/~seander/bithacks.html]
{
uint32_t n(size);
--n;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
++n;
return n;
}
// OLD:
// Brute-force method
//
// uint32_t n(minTableSize);
// while (n < uint32_t(size))
// {
// n <<= 1;
// }
// return n;
}

View File

@ -40,7 +40,6 @@ SourceFiles
#define Foam_HashTableCore_H
#include "label.H"
#include "uLabel.H"
#include "className.H"
#include "nullObject.H"
@ -56,11 +55,13 @@ namespace Foam
//- Bits that are independent of HashTable template parameters.
struct HashTableCore
{
//- Maximum allowable internal table size. Approximately labelMax/4
static const label maxTableSize;
//- Maximum allowable internal table size (must be a power of two!).
// - approximately (INT32_MAX/4) => 0x20000000
// - don't need an int64 version
static constexpr int32_t maxTableSize = (1 << (32-3));
//- Return a canonical (power-of-two) of the requested size.
static label canonicalSize(const label requested_size);
static label canonicalSize(const label size) noexcept;
//- Declare type-name (with debug switch)
ClassName("HashTable");

View File

@ -26,12 +26,19 @@ License
\*---------------------------------------------------------------------------*/
#include "pointConstraint.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
const char* const pTraits<pointConstraint>::typeName = "pointConstraint";
defineCompoundTypeName(List<pointConstraint>, pointConstraintList);
addCompoundToRunTimeSelectionTable
(
List<pointConstraint>,
pointConstraintList
);
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -64,7 +64,7 @@ MAXMINPOW(float, float, int)
MAXMINPOW(float, int, float)
MAXMINPOW(float, float, long)
MAXMINPOW(float, long, float)
#if defined(__APPLE__) && WM_LABEL_SIZE == 64
#if (WM_LABEL_SIZE == 64) && (defined(__APPLE__) || defined(_WIN32))
MAXMINPOW(double, double, int64_t)
MAXMINPOW(double, int64_t, double)
MAXMINPOW(float, float, int64_t)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -433,7 +433,7 @@ inline complex pow(const complex& x, const complex& y)
powFuncs(int)
powFuncs(long)
#if defined(__APPLE__) && WM_LABEL_SIZE == 64
#if (WM_LABEL_SIZE == 64) && (defined(__APPLE__) || defined(_WIN32))
powFuncs(int64_t)
#endif
powFuncs(float)

View File

@ -306,8 +306,8 @@ void Foam::processorMeshes::removeFiles(const polyMesh& mesh)
// pointMesh/boundary
fileHandler().rm(fileHandler().filePath(pointIO.objectPath()));
// boundaryProcAddressing
io.rename("boundaryProcAddressing");
// pointMesh/boundaryProcAddressing
pointIO.rename("boundaryProcAddressing");
fileHandler().rm(fileHandler().filePath(pointIO.objectPath()));
}