ENH: dedicated HashSetOps, HashTableOps namespaces

- relocated HashSetPlusEqOp and HashTablePlusEqOp to
  HashSetOps::plusEqOp and HashTableOps::plusEqOp, respectively

- additional functions for converting between a labelHashSet
  and a PackedBoolList or List<bool>:

  From lists selections to labelHashSet indices:

      HashSetOps::used(const PackedBoolList&);
      HashSetOps::used(const UList<bool>&);

  From labelHashSet to list forms:

      PackedBoolList bitset(const labelHashSet&);
      List<bool> bools(const labelHashSet&);
This commit is contained in:
Mark Olesen
2018-03-06 11:41:34 +01:00
parent 15f7260884
commit bcabe827f6
10 changed files with 340 additions and 112 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,13 +27,50 @@ Description
#include "hashedWordList.H" #include "hashedWordList.H"
#include "nil.H" #include "nil.H"
#include "HashOps.H"
#include "HashSet.H" #include "HashSet.H"
#include "Map.H" #include "Map.H"
#include "labelPairHashes.H" #include "labelPairHashes.H"
#include "FlatOutput.H" #include "FlatOutput.H"
#include <algorithm>
using namespace Foam; using namespace Foam;
template<class Iter>
void printIf(const Iter& iter)
{
if (iter.found())
{
Info<< *iter;
}
else
{
Info<<"(null)";
}
}
template<class Key, class Hash>
void printMinMax(const HashSet<Key, Hash>& set)
{
const auto first = set.cbegin();
const auto last = set.cend();
const auto min = std::min_element(first, last);
const auto max = std::max_element(first, last);
Info<< "set: " << flatOutput(set) << nl;
Info<< " min=";
printIf(min);
Info<< nl;
Info<< " max=";
printIf(max);
Info<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -131,9 +168,14 @@ int main(int argc, char *argv[])
Info<< "create from Map<label>: "; Info<< "create from Map<label>: ";
Info<< labelHashSet(mapA) << endl; Info<< labelHashSet(mapA) << endl;
Info<<"combined toc: " {
<< (wordHashSet(setA) | wordHashSet(tableA) | wordHashSet(tableB)) auto allToc =
<< nl; (wordHashSet(setA) | wordHashSet(tableA) | wordHashSet(tableB));
Info<<"combined toc: " << flatOutput(allToc) << nl;
printMinMax(allToc);
}
labelHashSet setB labelHashSet setB
{ {
@ -226,6 +268,12 @@ int main(int argc, char *argv[])
Info << i << endl; Info << i << endl;
} }
printMinMax(setD);
Info<< nl;
printMinMax(labelHashSet());
Info<< nl;
Info<< nl << "Test swapping, moving etc." << nl; Info<< nl << "Test swapping, moving etc." << nl;
setA.insert({ "some", "more", "entries" }); setA.insert({ "some", "more", "entries" });

View File

@ -43,6 +43,7 @@ See also
#include "labelRange.H" #include "labelRange.H"
#include "scalarList.H" #include "scalarList.H"
#include "HashOps.H"
#include "ListOps.H" #include "ListOps.H"
#include "SubList.H" #include "SubList.H"
@ -473,7 +474,7 @@ int main(int argc, char *argv[])
} }
{ {
PackedBoolList select(locations.toc()); PackedBoolList select = HashSetOps::bitset(locations);
auto output = ListOps::createWithValue<label> auto output = ListOps::createWithValue<label>
( (
30, 30,
@ -486,16 +487,7 @@ int main(int argc, char *argv[])
} }
{ {
// Fairly really inconvenient way to set true/false List<bool> select = HashSetOps::bools(locations);
labelList toc(locations.sortedToc());
List<bool> select = ListOps::createWithValue<bool>
(
toc.last() + 1,
toc,
true,
false // default value
);
auto output = ListOps::createWithValue<label> auto output = ListOps::createWithValue<label>
( (
@ -524,7 +516,7 @@ int main(int argc, char *argv[])
} }
{ {
PackedBoolList select(locations.toc()); PackedBoolList select = HashSetOps::bitset(locations);
auto output = ListOps::createWithValue<label> auto output = ListOps::createWithValue<label>
( (
30, 30,
@ -533,20 +525,12 @@ int main(int argc, char *argv[])
-1 // default value -1 // default value
); );
Info<< "with PackedBoolList: " << flatOutput(output) Info<< "with PackedBoolList: " << flatOutput(output)
<< " selector: " << flatOutput(select.used()) << nl; << " selector: " << flatOutput(HashSetOps::used(select))
<< nl;
} }
{ {
// Fairly really inconvenient way to set true/false List<bool> select = HashSetOps::bools(locations);
labelList toc(locations.sortedToc());
List<bool> select = ListOps::createWithValue<bool>
(
toc.last() + 1,
toc,
true,
false // default value
);
auto output = ListOps::createWithValue<label> auto output = ListOps::createWithValue<label>
( (
@ -556,7 +540,8 @@ int main(int argc, char *argv[])
-1 // default value -1 // default value
); );
Info<< "with boolList: " << flatOutput(output) Info<< "with boolList: " << flatOutput(output)
<< " selector: " << flatOutput(select) << nl; << " selector: " << flatOutput(HashSetOps::used(select))
<< nl;
} }
} }

View File

@ -62,7 +62,7 @@ if (timeDirs.size() && !noLagrangian)
if (Pstream::parRun()) if (Pstream::parRun())
{ {
Pstream::mapCombineGather(cloudFields, HashTablePlusEqOp<word>()); Pstream::mapCombineGather(cloudFields, HashTableOps::plusEqOp<word>());
Pstream::mapCombineScatter(cloudFields); Pstream::mapCombineScatter(cloudFields);
} }

View File

@ -73,7 +73,7 @@ Note
#include "IOmanip.H" #include "IOmanip.H"
#include "OFstream.H" #include "OFstream.H"
#include "PstreamCombineReduceOps.H" #include "PstreamCombineReduceOps.H"
#include "HashTableOps.H" #include "HashOps.H"
#include "fvc.H" #include "fvc.H"
#include "volFields.H" #include "volFields.H"

View File

@ -53,7 +53,7 @@ if (timeDirs.size() && !noLagrangian)
if (Pstream::parRun()) if (Pstream::parRun())
{ {
Pstream::combineGather(allCloudDirs, HashSetPlusEqOp<word>()); Pstream::combineGather(allCloudDirs, HashSetOps::plusEqOp<word>());
Pstream::combineScatter(allCloudDirs); Pstream::combineScatter(allCloudDirs);
} }
} }

View File

@ -147,7 +147,7 @@ Note
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "PstreamCombineReduceOps.H" #include "PstreamCombineReduceOps.H"
#include "HashTableOps.H" #include "HashOps.H"
#include "labelIOField.H" #include "labelIOField.H"
#include "scalarIOField.H" #include "scalarIOField.H"
#include "sphericalTensorIOField.H" #include "sphericalTensorIOField.H"
@ -1482,7 +1482,7 @@ int main(int argc, char *argv[])
Pstream::mapCombineGather Pstream::mapCombineGather
( (
cloudFields, cloudFields,
HashSetPlusEqOp<word>() HashSetOps::plusEqOp<word>()
); );
Pstream::mapCombineScatter(cloudFields); Pstream::mapCombineScatter(cloudFields);
} }

View File

@ -145,6 +145,7 @@ primitives/polynomialEqns/quadraticEqn/quadraticEqn.C
primitives/Barycentric/barycentric/barycentric.C primitives/Barycentric/barycentric/barycentric.C
primitives/Barycentric2D/barycentric2D/barycentric2D.C primitives/Barycentric2D/barycentric2D/barycentric2D.C
containers/HashTables/HashOps/HashOps.C
containers/HashTables/HashTable/HashTableCore.C containers/HashTables/HashTable/HashTableCore.C
containers/Lists/SortableList/ParSortableListName.C containers/Lists/SortableList/ParSortableListName.C
containers/Lists/PackedList/PackedListCore.C containers/Lists/PackedList/PackedListCore.C

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "HashOps.H"
#include "PackedBoolList.H"
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::labelHashSet Foam::HashSetOps::used(const PackedBoolList& select)
{
const label count = select.count();
const label len = select.size();
labelHashSet output(2*count);
label used = 0;
for (label i = 0; i < len && used < count; ++i)
{
if (select[i])
{
output.insert(i);
++used;
}
}
return output;
}
Foam::labelHashSet Foam::HashSetOps::used(const UList<bool>& select)
{
// We have no estimate of the size/sparsity, just assume 1/10
const label len = select.size();
labelHashSet output(len/10);
for (label i = 0; i < len; ++i)
{
if (select[i])
{
output.insert(i);
}
}
return output;
}
Foam::PackedBoolList Foam::HashSetOps::bitset(const labelHashSet& labels)
{
auto const max = std::max_element(labels.cbegin(), labels.cend());
const label len = (max.found() ? (1 + *max) : 0);
if (len <= 0)
{
return PackedBoolList();
}
PackedBoolList output(len);
for (const label i : labels)
{
if (i >= 0)
{
output.set(i);
}
}
return output;
}
Foam::List<bool> Foam::HashSetOps::bools(const labelHashSet& labels)
{
auto const max = std::max_element(labels.cbegin(), labels.cend());
const label len = (max.found() ? (1 + *max) : 0);
if (len <= 0)
{
return List<bool>();
}
List<bool> output(len, false);
for (const label i : labels)
{
if (i >= 0)
{
output[i] = true;
}
}
return output;
}
// ************************************************************************* //

View File

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namspace
Foam::HashSetOps
Description
Various operations for HashSet.
Namspace
Foam::HashTableOps
Description
Various operations for HashTable.
SourceFiles
HashOps.H
\*---------------------------------------------------------------------------*/
#ifndef HashOps_H
#define HashOps_H
#include "HashSet.H"
#include "List.H"
namespace Foam
{
// Forward declarations
class PackedBoolList;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
/*---------------------------------------------------------------------------*\
Namespace HashSetOps Declaration
\*---------------------------------------------------------------------------*/
namespace HashSetOps
{
//- Combine HashSet operation. Equivalent to 'a += b'
template<class Key=word, class Hash=string::hash>
struct plusEqOp
{
typedef HashSet<Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
a += b;
}
};
//- Convert a packed list of bits to a labelHashSet of the indices used.
//
// \param selection the list for which a 'true' entry corresponds
// to an index for be added to the labelHashSet
//
// \return a labelHashSet of the selected indices
labelHashSet used(const PackedBoolList& select);
//- Convert a list of bools to a labelHashSet of the indices used.
//
// \param selection the list for which a 'true' entry corresponds
// to an index for be added to the labelHashSet
//
// \return a labelHashSet of the selected indices
labelHashSet used(const UList<bool>& select);
//- Convert labels to a packed list of bits, with '1' for each
//- non-negative value and '0' for all others.
//
// \param labels the list of indices.
//
// \return a packed bit list of the selected indices
//
// \note The operation discards any negative values since these are
// invalid positions in the output list.
PackedBoolList bitset(const labelHashSet& labels);
//- Convert labels to a list of bools, with 'true' for each
//- non-negative value and 'false' for all others.
//
// \param labels the list of indices.
//
// \return a bool List of the selected indices
//
// \note The operation discards any negative values since these are
// invalid positions in the output list.
List<bool> bools(const labelHashSet& labels);
} // End namespace HashSetOps
/*---------------------------------------------------------------------------*\
Namespace HashTableOps Declaration
\*---------------------------------------------------------------------------*/
namespace HashTableOps
{
//- Combine HashTable operation. Equivalent to 'a += b'
template<class T, class Key=word, class Hash=string::hash>
struct plusEqOp
{
typedef HashTable<T, Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
a += b;
}
};
} // End namespace HashTableOps
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,79 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InNamspace
Foam
Description
Various functions to operate on HashTables.
SourceFiles
HashTableOps.H
\*---------------------------------------------------------------------------*/
#ifndef HashTableOps_H
#define HashTableOps_H
#include "HashSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Combine HashSet operation. Equivalent to 'a += b'
template<class Key=word, class Hash=string::hash>
struct HashSetPlusEqOp
{
typedef HashSet<Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
a += b;
}
};
//- Combine HashTable operation. Equivalent to 'a += b'
template<class T, class Key=word, class Hash=string::hash>
struct HashTablePlusEqOp
{
typedef HashTable<T, Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
a += b;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //