diff --git a/doc/Allwmake b/doc/Allwmake index 0e4ba76d8..e180b24e0 100755 --- a/doc/Allwmake +++ b/doc/Allwmake @@ -1,8 +1,11 @@ #!/bin/sh +cd ${0%/*} || exit 1 # run from this directory set -x chmod a+rX $WM_PROJECT_DIR chmod a+rX $WM_PROJECT_DIR/doc chmod -R a+rX Doxygen -( cd Doxygen && ./Allwmake ) +Doxygen/Allwmake + +# ----------------------------------------------------------------- end-of-file diff --git a/doc/Doxygen/Allwmake b/doc/Doxygen/Allwmake index f48d320d0..dab44579b 100755 --- a/doc/Doxygen/Allwmake +++ b/doc/Doxygen/Allwmake @@ -1,9 +1,12 @@ #!/bin/sh +cd ${0%/*} || exit 1 # run from this directory set -x umask 22 rm -rf html latex man doxygen -# fix permissions (NB: '-X' and not '-x'!) +# fix permissions (NB: '+X' and not '+x'!) chmod -R a+rX ./ + +# ----------------------------------------------------------------- end-of-file diff --git a/doc/Doxygen/Doxyfile b/doc/Doxygen/Doxyfile index ecc66763c..908fa543b 100644 --- a/doc/Doxygen/Doxyfile +++ b/doc/Doxygen/Doxyfile @@ -788,7 +788,7 @@ TREEVIEW_WIDTH = 250 # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# Path for OpenFOAM LaTeX macros +# Path for OpenCFD LaTeX macros @INCLUDE_PATH = $(WM_PROJECT_DIR)/doc/Doxygen/Macros/ diff --git a/doc/Doxygen/FoamFooter.html b/doc/Doxygen/FoamFooter.html index e3bfbb749..352a32682 100644 --- a/doc/Doxygen/FoamFooter.html +++ b/doc/Doxygen/FoamFooter.html @@ -1,4 +1,4 @@ -Copyright © 2000-2008 OpenFOAM Foundation +Copyright © 2000-2009 OpenCFD Ltd diff --git a/doc/Doxygen/FoamHeader.html b/doc/Doxygen/FoamHeader.html index 2a9c93021..3314d3dd6 100644 --- a/doc/Doxygen/FoamHeader.html +++ b/doc/Doxygen/FoamHeader.html @@ -1,7 +1,7 @@ -open + OpenFOAM programmer's C++ documentation @@ -12,8 +12,8 @@ - - + + @@ -40,6 +40,26 @@ horizontal-align: left; "> + + + + +
  + Source Guide + + OpenCFD + + Solutions + + Contact + + OpenFOAM +
diff --git a/doc/Doxygen/Macros/tensorOperator.sty b/doc/Doxygen/Macros/tensorOperator.sty new file mode 100644 index 000000000..711f17bc2 --- /dev/null +++ b/doc/Doxygen/Macros/tensorOperator.sty @@ -0,0 +1,129 @@ +%----------------------------------------------------------------------------- +% ========= | +% \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +% \\ / O peration | +% \\ / A nd | Copyright held by original author +% \\/ 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 2 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, write to the Free Software Foundation, +% Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +% +% LaTeX Style file +% tensorOperator.sty +% +% Description +% Standard OpenCFD LaTeX macros for typesetting tensor algebra. +% +%------------------------------------------------------------------------------ + +% tensor style +% ~~~~~~~~~~~~ +\renewcommand{\vec}[1] {\ensuremath{\mathbf #1}} +\newcommand{\gvec}[1] {\ensuremath{\mbox{\boldmath$\bf#1$}}} + +% products +% ~~~~~~~~ +\newcommand{\anyprod}{\star} +\newcommand{\cprod} {\times} +\newcommand{\dprod} {\,{\scriptscriptstyle \stackrel{\bullet}{{}}}\,} +\newcommand{\ddprod} {\,{\scriptscriptstyle \stackrel{\bullet}{\bullet}}\,} +\newcommand{\tdprod} {\,{\scriptscriptstyle \stackrel{3}{\bullet}}\,} +\newcommand{\tprod} {\,{\scriptscriptstyle \stackrel{\otimes}{{}}}\,} + +% operations +% ~~~~~~~~~~ +\newcommand{\adj} {\ensuremath{\operatorname{adj}}} +\newcommand{\cof} {\ensuremath{\operatorname{cof}}} +\newcommand{\diag} {\ensuremath{\operatorname{diag}}} +\newcommand{\dev} {\ensuremath{\operatorname{dev}}} + +\newcommand{\Hodge} {\ensuremath{\operatorname{\stackrel{\displaystyle \ast}{}}}} +\newcommand{\hyd} {\ensuremath{\operatorname{hyd}}} +\renewcommand{\max} {\ensuremath{\operatorname{max}}} +\renewcommand{\min} {\ensuremath{\operatorname{min}}} +\newcommand{\inv} {\ensuremath{\operatorname{inv}}} +\newcommand{\sym} {\ensuremath{\operatorname{symm}}} % symm ? +\newcommand{\skw} {\ensuremath{\operatorname{skew}}} % skew already defined +\newcommand{\tr} {\ensuremath{\operatorname{tr}}} +\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}} + +% alternative tensor operators for hypersonics etc. +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\newcommand{\devs}[1] {\overset{\scriptscriptstyle\circ}{#1}} +%\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}} +\newcommand{\symms}[1] {\overleftrightarrow{#1}} +\newlength{\skewslength} +\newlength{\skewsheight} +\newcommand{\skews}[1]{ + \settowidth{\skewslength}{#1}% + \settoheight{\skewsheight}{#1}% + \addtolength{\skewsheight}{0.4mm}% + {\overleftrightarrow{#1}\hspace{-.5\skewslength}% + \rule[\skewsheight]{.4pt}{1.4mm} + \hspace{.5\skewslength}% +}} +%\newcommand{\skew}[1] {\ensuremath{#1^{\operatorname{A}}}} + +% spatial derivatives +% ~~~~~~~~~~~~~~~~~~~ +\newcommand{\curl}{\ensuremath{\nabla\cprod}} +\renewcommand{\div} {\ensuremath{\nabla\dprod}} +\newcommand{\grad}{\ensuremath{\nabla}} +\newcommand{\laplacian}{\ensuremath{\nabla^{2}}} + +% temporal derivatives +% ~~~~~~~~~~~~~~~~~~~~ +\newcommand{\ddt}[1] {\ensuremath{\frac{\partial #1}{\partial t }}} +\newcommand{\DDt}[1] {\ensuremath{\frac{D #1}{D t}}} +\newcommand{\DpDt}[2] {\ensuremath{\frac{d_{#1} #2}{d t }}} +\newcommand{\dsdts}[1] {\ensuremath{\frac{\partial ^2 #1}{\partial t^2}}} +\newcommand{\rate}[1] {\ensuremath{\dot{#1}}} + +\newcommand{\genDer}{\mathcal{L}} + +% time average symbols +% ~~~~~~~~~~~~~~~~~~~~ +\newcommand{\av}[1] {\ensuremath{\overline{#1}}} +\newcommand{\corrtwo}[2] {{\dwea{\dprime{#1} \dprime{#2}}}} +\newcommand{\curly}[1] {{\cal #1}} +\newcommand{\dprime}[1] {\ensuremath{{#1}^{^{\prime \prime}}}} +\newcommand{\dwea}[1] {\ensuremath{\widetilde{#1}}} +\newcommand{\dweafluc}[1] {\ensuremath{\dprime{#1}}} +\newcommand{\fluc}[1] {\ensuremath{#1^{\prime}}} + +% index style +% ~~~~~~~~~~~ +\newcommand{\veci}[2][i] {\ensuremath{#2_{#1}}} +\newcommand{\teni}[2][ij] {\ensuremath{#2_{#1}}} +\newcommand{\tenTi}[2][ji] {\ensuremath{#2_{#1}}} + +% index operations +% ~~~~~~~~~~~~~~~~ +\newcommand{\deltai}[1] {\ensuremath{\partial_{#1}}} + +% Sub-subscripts +% ~~~~~~~~~~~~~~ +\newcommand{\eff} {{\scriptscriptstyle e\!f\!\!f\!}} + +% unknown use +% ~~~~~~~~~~~ +%\font\bigtenrm=cmr12 scaled 1200 +%\newcommand{\eexp}[1]{{\hbox{$\textfont1=\bigtenrm e$}}^{\raise3pt +%\hbox{$#1$}}} + + +% ------------------------------------------------------------------------------ diff --git a/doc/Guides-a4/ProgrammersGuide.pdf b/doc/Guides-a4/ProgrammersGuide.pdf index 1484f7423..54fe181d4 100644 Binary files a/doc/Guides-a4/ProgrammersGuide.pdf and b/doc/Guides-a4/ProgrammersGuide.pdf differ diff --git a/doc/Guides-a4/UserGuide.pdf b/doc/Guides-a4/UserGuide.pdf index b2e71169e..fede8bf42 100644 Binary files a/doc/Guides-a4/UserGuide.pdf and b/doc/Guides-a4/UserGuide.pdf differ diff --git a/doc/Guides-usletter/ProgrammersGuide.pdf b/doc/Guides-usletter/ProgrammersGuide.pdf new file mode 100644 index 000000000..aff4c80af Binary files /dev/null and b/doc/Guides-usletter/ProgrammersGuide.pdf differ diff --git a/doc/Guides-usletter/UserGuide.pdf b/doc/Guides-usletter/UserGuide.pdf new file mode 100644 index 000000000..c708e4bc6 Binary files /dev/null and b/doc/Guides-usletter/UserGuide.pdf differ diff --git a/src/ODE/ODE/ODE.H b/src/ODE/ODE/ODE.H index 3d6728a64..08e803c26 100644 --- a/src/ODE/ODE/ODE.H +++ b/src/ODE/ODE/ODE.H @@ -23,7 +23,7 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - ODE + Foam::ODE Description Abstract base class for the ODE solvers. @@ -34,7 +34,7 @@ Description #define ODE_H #include "scalarField.H" -#include "Matrix.H" +#include "scalarMatrices.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -87,7 +87,7 @@ public: const scalar x, const scalarField& y, scalarField& dfdx, - Matrix& dfdy + scalarSquareMatrix& dfdy ) const = 0; //- Update ODE after the solution, advancing by delta diff --git a/src/ODE/ODESolvers/KRR4/KRR4.H b/src/ODE/ODESolvers/KRR4/KRR4.H index b29081d57..bfc2267d7 100644 --- a/src/ODE/ODESolvers/KRR4/KRR4.H +++ b/src/ODE/ODESolvers/KRR4/KRR4.H @@ -23,7 +23,7 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - KRR4 + Foam::KRR4 Description Fourth-order Kaps-Rentrop scheme with adjustive time-step size @@ -63,8 +63,8 @@ class KRR4 mutable scalarField g4_; mutable scalarField yErr_; mutable scalarField dfdx_; - mutable Matrix dfdy_; - mutable Matrix a_; + mutable scalarSquareMatrix dfdy_; + mutable scalarSquareMatrix a_; mutable labelList pivotIndices_; static const int maxtry = 40; diff --git a/src/ODE/ODESolvers/ODESolver/ODESolver.C b/src/ODE/ODESolvers/ODESolver/ODESolver.C index 19cdb168a..31ba4da1c 100644 --- a/src/ODE/ODESolvers/ODESolver/ODESolver.C +++ b/src/ODE/ODESolvers/ODESolver/ODESolver.C @@ -22,8 +22,6 @@ License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Description - \*---------------------------------------------------------------------------*/ #include "ODESolver.H" diff --git a/src/ODE/ODESolvers/ODESolver/ODESolver.H b/src/ODE/ODESolvers/ODESolver/ODESolver.H index ac83449de..2ffe904f3 100644 --- a/src/ODE/ODESolvers/ODESolver/ODESolver.H +++ b/src/ODE/ODESolvers/ODESolver/ODESolver.H @@ -23,9 +23,10 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - ODESolver + Foam::ODESolver Description + Selection for ODE solver SourceFiles ODESolver.C diff --git a/src/ODE/ODESolvers/RK/RK.H b/src/ODE/ODESolvers/RK/RK.H index cdbca7633..870402d2c 100644 --- a/src/ODE/ODESolvers/RK/RK.H +++ b/src/ODE/ODESolvers/RK/RK.H @@ -23,7 +23,7 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - RK + Foam::RK Description Fifth-order Cash-Karp embedded Runge-Kutta scheme with error control and diff --git a/src/ODE/ODESolvers/SIBS/SIBS.H b/src/ODE/ODESolvers/SIBS/SIBS.H index 7c5f1b299..20b36dccb 100644 --- a/src/ODE/ODESolvers/SIBS/SIBS.H +++ b/src/ODE/ODESolvers/SIBS/SIBS.H @@ -33,6 +33,7 @@ Description SourceFiles SIBS.C SIMPR.C + polyExtrapolate.C \*---------------------------------------------------------------------------*/ @@ -62,8 +63,8 @@ class SIBS static const scalar safe1, safe2, redMax, redMin, scaleMX; mutable scalarField a_; - mutable Matrix alpha_; - mutable Matrix d_p_; + mutable scalarSquareMatrix alpha_; + mutable scalarRectangularMatrix d_p_; mutable scalarField x_p_; mutable scalarField err_; @@ -71,7 +72,7 @@ class SIBS mutable scalarField ySeq_; mutable scalarField yErr_; mutable scalarField dfdx_; - mutable Matrix dfdy_; + mutable scalarSquareMatrix dfdy_; mutable label first_, kMax_, kOpt_; mutable scalar epsOld_, xNew_; @@ -85,13 +86,12 @@ class SIBS const scalarField& y, const scalarField& dydx, const scalarField& dfdx, - const Matrix& dfdy, + const scalarSquareMatrix& dfdy, const scalar deltaX, const label nSteps, scalarField& yEnd ) const; - void polyExtrapolate ( const label iest, @@ -100,7 +100,7 @@ class SIBS scalarField& yz, scalarField& dy, scalarField& x_p, - Matrix& d_p + scalarRectangularMatrix& d_p ) const; diff --git a/src/ODE/ODESolvers/SIBS/SIMPR.C b/src/ODE/ODESolvers/SIBS/SIMPR.C index afd71a626..1e4a67aaf 100644 --- a/src/ODE/ODESolvers/SIBS/SIMPR.C +++ b/src/ODE/ODESolvers/SIBS/SIMPR.C @@ -25,7 +25,6 @@ License \*---------------------------------------------------------------------------*/ #include "SIBS.H" -#include "simpleMatrix.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -35,7 +34,7 @@ void Foam::SIBS::SIMPR const scalarField& y, const scalarField& dydx, const scalarField& dfdx, - const Matrix& dfdy, + const scalarSquareMatrix& dfdy, const scalar deltaX, const label nSteps, scalarField& yEnd diff --git a/src/ODE/ODESolvers/SIBS/polyExtrapolate.C b/src/ODE/ODESolvers/SIBS/polyExtrapolate.C index efee665d7..ccc82d9fc 100644 --- a/src/ODE/ODESolvers/SIBS/polyExtrapolate.C +++ b/src/ODE/ODESolvers/SIBS/polyExtrapolate.C @@ -36,7 +36,7 @@ void Foam::SIBS::polyExtrapolate scalarField& yz, scalarField& dy, scalarField& x, - Matrix& d + scalarRectangularMatrix& d ) const { label n = yz.size(); diff --git a/src/OSspecific/Unix/Make/files b/src/OSspecific/POSIX/Make/files similarity index 88% rename from src/OSspecific/Unix/Make/files rename to src/OSspecific/POSIX/Make/files index 75dd3e441..532069a8e 100644 --- a/src/OSspecific/Unix/Make/files +++ b/src/OSspecific/POSIX/Make/files @@ -2,17 +2,18 @@ signals/sigFpe.C signals/sigSegv.C signals/sigInt.C signals/sigQuit.C +regExp.C timer.C fileStat.C -Unix.C +POSIX.C cpuTime/cpuTime.C clockTime/clockTime.C multiThreader/multiThreader.C -#ifndef SunOS64 -printStack.C -#else +#ifdef SunOS64 dummyPrintStack.C +#else +printStack.C #endif LIB = $(FOAM_LIBBIN)/libOSspecific diff --git a/src/OSspecific/POSIX/Make/options b/src/OSspecific/POSIX/Make/options new file mode 100644 index 000000000..e69de29bb diff --git a/src/OSspecific/Unix/Unix.C b/src/OSspecific/POSIX/POSIX.C similarity index 81% rename from src/OSspecific/Unix/Unix.C rename to src/OSspecific/POSIX/POSIX.C index e719b1dbb..791f3ead6 100644 --- a/src/OSspecific/Unix/Unix.C +++ b/src/OSspecific/POSIX/POSIX.C @@ -23,7 +23,7 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description - UNIX versions of the functions declated in OSspecific.H. + POSIX versions of the functions declared in OSspecific.H \*---------------------------------------------------------------------------*/ @@ -32,7 +32,7 @@ Description #endif #include "OSspecific.H" -#include "Unix.H" +#include "POSIX.H" #include "foamVersion.H" #include "fileName.H" #include "fileStat.H" @@ -56,7 +56,7 @@ Description // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -defineTypeNameAndDebug(Foam::Unix, 0); +defineTypeNameAndDebug(Foam::POSIX, 0); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -91,7 +91,9 @@ Foam::string Foam::getEnv(const word& envName) } else { - return string::null; + // Return null-constructed string rather than string::null + // to avoid cyclic dependencies in the construction of globals + return string(); } } @@ -211,23 +213,23 @@ bool Foam::chDir(const fileName& dir) } -Foam::fileName Foam::dotFoam(const fileName& name) +Foam::fileName Foam::findEtcFile(const fileName& name, bool mandatory) { // Search user files: // ~~~~~~~~~~~~~~~~~~ fileName searchDir = home()/".OpenFOAM"; - if (dir(searchDir)) + if (isDir(searchDir)) { // Check for user file in ~/.OpenFOAM/VERSION fileName fullName = searchDir/FOAMversion/name; - if (exists(fullName)) + if (isFile(fullName)) { return fullName; } // Check for version-independent user file in ~/.OpenFOAM fullName = searchDir/name; - if (exists(fullName)) + if (isFile(fullName)) { return fullName; } @@ -237,18 +239,18 @@ Foam::fileName Foam::dotFoam(const fileName& name) // Search site files: // ~~~~~~~~~~~~~~~~~~ searchDir = getEnv("WM_PROJECT_INST_DIR"); - if (dir(searchDir)) + if (isDir(searchDir)) { // Check for site file in $WM_PROJECT_INST_DIR/site/VERSION fileName fullName = searchDir/"site"/FOAMversion/name; - if (exists(fullName)) + if (isFile(fullName)) { return fullName; } // Check for version-independent site file in $WM_PROJECT_INST_DIR/site fullName = searchDir/"site"/name; - if (exists(fullName)) + if (isFile(fullName)) { return fullName; } @@ -257,25 +259,36 @@ Foam::fileName Foam::dotFoam(const fileName& name) // Search installation files: // ~~~~~~~~~~~~~~~~~~~~~~~~~~ searchDir = getEnv("WM_PROJECT_DIR"); - if (dir(searchDir)) + if (isDir(searchDir)) { // Check for shipped OpenFOAM file in $WM_PROJECT_DIR/etc fileName fullName = searchDir/"etc"/name; - if (exists(fullName)) + if (isFile(fullName)) { return fullName; } } // Not found - return fileName::null; + // abort if the file is mandatory, otherwise return null + if (mandatory) + { + cerr<< "--> FOAM FATAL ERROR in Foam::findEtcFile() :" + " could not find mandatory file\n '" + << name.c_str() << "'\n\n" << std::endl; + ::exit(1); + } + + // Return null-constructed fileName rather than fileName::null + // to avoid cyclic dependencies in the construction of globals + return fileName(); } bool Foam::mkDir(const fileName& pathName, mode_t mode) { // empty names are meaningless - if (!pathName.size()) + if (pathName.empty()) { return false; } @@ -419,7 +432,7 @@ bool Foam::mkDir(const fileName& pathName, mode_t mode) // Set the file mode -bool Foam::chmod(const fileName& name, const mode_t m) +bool Foam::chMod(const fileName& name, const mode_t m) { return ::chmod(name.c_str(), m) == 0; } @@ -429,7 +442,6 @@ bool Foam::chmod(const fileName& name, const mode_t m) mode_t Foam::mode(const fileName& name) { fileStat fileStatus(name); - if (fileStatus.isValid()) { return fileStatus.status().st_mode; @@ -462,28 +474,28 @@ Foam::fileName::Type Foam::type(const fileName& name) // Does the name exist in the filing system? -bool Foam::exists(const fileName& name) +bool Foam::exists(const fileName& name, const bool checkGzip) { - return mode(name) || file(name); + return mode(name) || isFile(name, checkGzip); } -// Does the file exist -bool Foam::file(const fileName& name) -{ - return S_ISREG(mode(name)) || S_ISREG(mode(name + ".gz")); -} - - -// Does the directory exist -bool Foam::dir(const fileName& name) +// Does the directory exist? +bool Foam::isDir(const fileName& name) { return S_ISDIR(mode(name)); } +// Does the file exist? +bool Foam::isFile(const fileName& name, const bool checkGzip) +{ + return S_ISREG(mode(name)) || (checkGzip && S_ISREG(mode(name + ".gz"))); +} + + // Return size of file -off_t Foam::size(const fileName& name) +off_t Foam::fileSize(const fileName& name) { fileStat fileStatus(name); if (fileStatus.isValid()) @@ -524,7 +536,7 @@ Foam::fileNameList Foam::readDir // also used as increment if initial size found to be insufficient static const int maxNnames = 100; - if (Unix::debug) + if (POSIX::debug) { Info<< "readDir(const fileName&, const fileType, const bool filtergz)" << " : reading directory " << directory << endl; @@ -533,7 +545,7 @@ Foam::fileNameList Foam::readDir // Setup empty string list MAXTVALUES long fileNameList dirEntries(maxNnames); - // Pointers to the Unix director system + // Pointers to the directory entries DIR *source; struct dirent *list; @@ -545,7 +557,7 @@ Foam::fileNameList Foam::readDir { dirEntries.setSize(0); - if (Unix::debug) + if (POSIX::debug) { Info<< "readDir(const fileName&, const fileType, " "const bool filtergz) : cannot open directory " @@ -559,10 +571,10 @@ Foam::fileNameList Foam::readDir { fileName fName(list->d_name); - // ignore files begining with ., i.e. ., .. and .??* - if (fName.size() > 0 && fName[size_t(0)] != '.') + // ignore files begining with ., i.e. '.', '..' and '.*' + if (fName.size() && fName[0] != '.') { - word fileNameExt = fName.ext(); + word fExt = fName.ext(); if ( @@ -570,11 +582,11 @@ Foam::fileNameList Foam::readDir || ( type == fileName::FILE - && fName[fName.size()-1] != '~' - && fileNameExt != "bak" - && fileNameExt != "BAK" - && fileNameExt != "old" - && fileNameExt != "save" + && fName[fName.size()-1] != '~' + && fExt != "bak" + && fExt != "BAK" + && fExt != "old" + && fExt != "save" ) ) { @@ -585,7 +597,7 @@ Foam::fileNameList Foam::readDir dirEntries.setSize(dirEntries.size() + maxNnames); } - if (filtergz && fileNameExt == "gz") + if (filtergz && fExt == "gz") { dirEntries[nEntries++] = fName.lessExt(); } @@ -608,17 +620,17 @@ Foam::fileNameList Foam::readDir } -// Copy, recursively if necessary, the source top the destination +// Copy, recursively if necessary, the source to the destination bool Foam::cp(const fileName& src, const fileName& dest) { - fileName destFile(dest); - // Make sure source exists. if (!exists(src)) { return false; } + fileName destFile(dest); + // Check type of source file. if (src.type() == fileName::FILE) { @@ -629,7 +641,7 @@ bool Foam::cp(const fileName& src, const fileName& dest) } // Make sure the destination directory exists. - if (!dir(destFile.path()) && !mkDir(destFile.path())) + if (!isDir(destFile.path()) && !mkDir(destFile.path())) { return false; } @@ -668,8 +680,8 @@ bool Foam::cp(const fileName& src, const fileName& dest) destFile = destFile/src.component(src.components().size() -1); } - // Make sure the destination directory extists. - if (!dir(destFile) && !mkDir(destFile)) + // Make sure the destination directory exists. + if (!isDir(destFile) && !mkDir(destFile)) { return false; } @@ -678,7 +690,7 @@ bool Foam::cp(const fileName& src, const fileName& dest) fileNameList contents = readDir(src, fileName::FILE, false); forAll(contents, i) { - if (Unix::debug) + if (POSIX::debug) { Info<< "Copying : " << src/contents[i] << " to " << destFile/contents[i] << endl; @@ -692,7 +704,7 @@ bool Foam::cp(const fileName& src, const fileName& dest) fileNameList subdirs = readDir(src, fileName::DIRECTORY); forAll(subdirs, i) { - if (Unix::debug) + if (POSIX::debug) { Info<< "Copying : " << src/subdirs[i] << " to " << destFile << endl; @@ -707,19 +719,19 @@ bool Foam::cp(const fileName& src, const fileName& dest) } -// Create a softlink. destFile should not exist. Returns true if successful. -bool Foam::ln(const fileName& src, const fileName& dest) +// Create a softlink. dst should not exist. Returns true if successful. +bool Foam::ln(const fileName& src, const fileName& dst) { - if (Unix::debug) + if (POSIX::debug) { - Info<< "Create softlink from : " << src << " to " << dest + Info<< "Create softlink from : " << src << " to " << dst << endl; } - if (exists(dest)) + if (exists(dst)) { WarningIn("ln(const fileName&, const fileName&)") - << "destination " << dest << " already exists. Not linking." + << "destination " << dst << " already exists. Not linking." << endl; return false; } @@ -731,48 +743,87 @@ bool Foam::ln(const fileName& src, const fileName& dest) return false; } - if (symlink(src.c_str(), dest.c_str()) == 0) + if (symlink(src.c_str(), dst.c_str()) == 0) { return true; } else { WarningIn("ln(const fileName&, const fileName&)") - << "symlink from " << src << " to " << dest << " failed." << endl; + << "symlink from " << src << " to " << dst << " failed." << endl; return false; } } -// Rename srcFile destFile -bool Foam::mv(const fileName& srcFile, const fileName& destFile) +// Rename srcFile dstFile +bool Foam::mv(const fileName& src, const fileName& dst) { - if (Unix::debug) + if (POSIX::debug) { - Info<< "Move : " << srcFile << " to " << destFile << endl; + Info<< "Move : " << src << " to " << dst << endl; } if ( - (destFile.type() == fileName::DIRECTORY) - && (srcFile.type() != fileName::DIRECTORY) + dst.type() == fileName::DIRECTORY + && src.type() != fileName::DIRECTORY ) { - const fileName destName(destFile/srcFile.name()); + const fileName dstName(dst/src.name()); - return rename(srcFile.c_str(), destName.c_str()) == 0; + return rename(src.c_str(), dstName.c_str()) == 0; } else { - return rename(srcFile.c_str(), destFile.c_str()) == 0; + return rename(src.c_str(), dst.c_str()) == 0; } } -// Remove a file returning true if successful otherwise false +//- Rename to a corresponding backup file +// If the backup file already exists, attempt with "01" .. "99" index +bool Foam::mvBak(const fileName& src, const std::string& ext) +{ + if (POSIX::debug) + { + Info<< "mvBak : " << src << " to extension " << ext << endl; + } + + if (exists(src, false)) + { + const int maxIndex = 99; + char index[3]; + + for (int n = 0; n <= maxIndex; n++) + { + fileName dstName(src + "." + ext); + if (n) + { + sprintf(index, "%02d", n); + dstName += index; + } + + // avoid overwriting existing files, except for the last + // possible index where we have no choice + if (!exists(dstName, false) || n == maxIndex) + { + return rename(src.c_str(), dstName.c_str()) == 0; + } + + } + } + + // fall-through: nothing to do + return false; +} + + + +// Remove a file, returning true if successful otherwise false bool Foam::rm(const fileName& file) { - if (Unix::debug) + if (POSIX::debug) { Info<< "Removing : " << file << endl; } @@ -792,20 +843,20 @@ bool Foam::rm(const fileName& file) // Remove a dirctory and its contents bool Foam::rmDir(const fileName& directory) { - if (Unix::debug) + if (POSIX::debug) { - Info<< "rmdir(const fileName&) : " + Info<< "rmDir(const fileName&) : " << "removing directory " << directory << endl; } - // Pointers to the Unix director system + // Pointers to the directory entries DIR *source; struct dirent *list; // Attempt to open directory and set the structure pointer if ((source = opendir(directory.c_str())) == NULL) { - WarningIn("rmdir(const fileName&)") + WarningIn("rmDir(const fileName&)") << "cannot open directory " << directory << endl; return false; @@ -825,7 +876,7 @@ bool Foam::rmDir(const fileName& directory) { if (!rmDir(path)) { - WarningIn("rmdir(const fileName&)") + WarningIn("rmDir(const fileName&)") << "failed to remove directory " << fName << " while removing directory " << directory << endl; @@ -839,7 +890,7 @@ bool Foam::rmDir(const fileName& directory) { if (!rm(path)) { - WarningIn("rmdir(const fileName&)") + WarningIn("rmDir(const fileName&)") << "failed to remove file " << fName << " while removing directory " << directory << endl; @@ -855,7 +906,7 @@ bool Foam::rmDir(const fileName& directory) if (!rm(directory)) { - WarningIn("rmdir(const fileName&)") + WarningIn("rmDir(const fileName&)") << "failed to remove directory " << directory << endl; closedir(source); diff --git a/src/OSspecific/Unix/Unix.H b/src/OSspecific/POSIX/POSIX.H similarity index 92% rename from src/OSspecific/Unix/Unix.H rename to src/OSspecific/POSIX/POSIX.H index b663af992..e10d89f69 100644 --- a/src/OSspecific/Unix/Unix.H +++ b/src/OSspecific/POSIX/POSIX.H @@ -23,18 +23,18 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Namespace - Foam::Unix + Foam::POSIX Description - UNIX versions of OS-specific functions. + OS-specific functions implemented in POSIX. SourceFiles - Unix.C + POSIX.C \*---------------------------------------------------------------------------*/ -#ifndef Unix_H -#define Unix_H +#ifndef POSIX_H +#define POSIX_H #include "className.H" @@ -45,10 +45,10 @@ namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -namespace Unix +namespace POSIX { //- Declare name of the class and its debug switch - NamespaceName("Unix"); + NamespaceName("POSIX"); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OSspecific/Unix/clockTime/clockTime.C b/src/OSspecific/POSIX/clockTime/clockTime.C similarity index 100% rename from src/OSspecific/Unix/clockTime/clockTime.C rename to src/OSspecific/POSIX/clockTime/clockTime.C diff --git a/src/OSspecific/Unix/clockTime/clockTime.H b/src/OSspecific/POSIX/clockTime/clockTime.H similarity index 100% rename from src/OSspecific/Unix/clockTime/clockTime.H rename to src/OSspecific/POSIX/clockTime/clockTime.H diff --git a/src/OSspecific/Unix/cpuTime/cpuTime.C b/src/OSspecific/POSIX/cpuTime/cpuTime.C similarity index 100% rename from src/OSspecific/Unix/cpuTime/cpuTime.C rename to src/OSspecific/POSIX/cpuTime/cpuTime.C diff --git a/src/OSspecific/Unix/cpuTime/cpuTime.H b/src/OSspecific/POSIX/cpuTime/cpuTime.H similarity index 100% rename from src/OSspecific/Unix/cpuTime/cpuTime.H rename to src/OSspecific/POSIX/cpuTime/cpuTime.H diff --git a/src/OSspecific/Unix/dummyPrintStack.C b/src/OSspecific/POSIX/dummyPrintStack.C similarity index 100% rename from src/OSspecific/Unix/dummyPrintStack.C rename to src/OSspecific/POSIX/dummyPrintStack.C diff --git a/src/OSspecific/Unix/fileStat.C b/src/OSspecific/POSIX/fileStat.C similarity index 100% rename from src/OSspecific/Unix/fileStat.C rename to src/OSspecific/POSIX/fileStat.C diff --git a/src/OSspecific/Unix/fileStat.H b/src/OSspecific/POSIX/fileStat.H similarity index 100% rename from src/OSspecific/Unix/fileStat.H rename to src/OSspecific/POSIX/fileStat.H diff --git a/src/OSspecific/Unix/multiThreader/multiThreader.C b/src/OSspecific/POSIX/multiThreader/multiThreader.C similarity index 100% rename from src/OSspecific/Unix/multiThreader/multiThreader.C rename to src/OSspecific/POSIX/multiThreader/multiThreader.C diff --git a/src/OSspecific/Unix/multiThreader/multiThreader.H b/src/OSspecific/POSIX/multiThreader/multiThreader.H similarity index 100% rename from src/OSspecific/Unix/multiThreader/multiThreader.H rename to src/OSspecific/POSIX/multiThreader/multiThreader.H diff --git a/src/OSspecific/Unix/multiThreader/threadHandler.H b/src/OSspecific/POSIX/multiThreader/threadHandler.H similarity index 100% rename from src/OSspecific/Unix/multiThreader/threadHandler.H rename to src/OSspecific/POSIX/multiThreader/threadHandler.H diff --git a/src/OSspecific/Unix/multiThreader/threadHandlerI.H b/src/OSspecific/POSIX/multiThreader/threadHandlerI.H similarity index 100% rename from src/OSspecific/Unix/multiThreader/threadHandlerI.H rename to src/OSspecific/POSIX/multiThreader/threadHandlerI.H diff --git a/src/OSspecific/Unix/printStack.C b/src/OSspecific/POSIX/printStack.C similarity index 96% rename from src/OSspecific/Unix/printStack.C rename to src/OSspecific/POSIX/printStack.C index 69b5489de..65e7c7ff6 100644 --- a/src/OSspecific/Unix/printStack.C +++ b/src/OSspecific/POSIX/printStack.C @@ -159,7 +159,7 @@ void getSymbolForRaw const word& address ) { - if (filename.size() > 0 && filename[0] == '/') + if (filename.size() && filename[0] == '/') { string fcnt = pOpen ( @@ -305,7 +305,7 @@ void error::printStack(Ostream& os) string::size_type space = line.rfind(' ') + 1; fileName libPath = line.substr(space, line.size()-space); - if (libPath.size() > 0 && libPath[0] == '/') + if (libPath.size() && libPath[0] == '/') { string offsetString(line.substr(0, line.find('-'))); IStringStream offsetStr(offsetString); @@ -350,7 +350,7 @@ void error::printStack(Ostream& os) // not an absolute path if (programFile[0] != '/') { - string tmp = pOpen("which "+programFile); + string tmp = pOpen("which " + programFile); if (tmp[0] == '/' || tmp[0] == '~') { programFile = tmp; @@ -361,13 +361,13 @@ void error::printStack(Ostream& os) string::size_type bracketPos = msg.find('('); - if (bracketPos != string::size_type(string::npos)) + if (bracketPos != string::npos) { string::size_type start = bracketPos+1; string::size_type plusPos = msg.find('+', start); - if (plusPos != string::size_type(string::npos)) + if (plusPos != string::npos) { string cName(msg.substr(start, plusPos-start)); @@ -394,7 +394,7 @@ void error::printStack(Ostream& os) { string::size_type endBracketPos = msg.find(')', start); - if (endBracketPos != string::size_type(string::npos)) + if (endBracketPos != string::npos) { string fullName(msg.substr(start, endBracketPos-start)); diff --git a/src/OSspecific/POSIX/regExp.C b/src/OSspecific/POSIX/regExp.C new file mode 100644 index 000000000..26930f958 --- /dev/null +++ b/src/OSspecific/POSIX/regExp.C @@ -0,0 +1,216 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright held by original author + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include + +#include "regExp.H" +#include "label.H" +#include "string.H" +#include "List.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::regExp::regExp() +: + preg_(0) +{} + + +Foam::regExp::regExp(const char* pattern, const bool ignoreCase) +: + preg_(0) +{ + set(pattern, ignoreCase); +} + + +Foam::regExp::regExp(const std::string& pattern, const bool ignoreCase) +: + preg_(0) +{ + set(pattern.c_str(), ignoreCase); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::regExp::~regExp() +{ + clear(); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::regExp::set(const char* pattern, const bool ignoreCase) const +{ + clear(); + + // avoid NULL pointer and zero-length patterns + if (pattern && *pattern) + { + preg_ = new regex_t; + + int cflags = REG_EXTENDED; + if (ignoreCase) + { + cflags |= REG_ICASE; + } + + if (regcomp(preg_, pattern, cflags) != 0) + { + FatalErrorIn + ( + "regExp::set(const char*)" + ) << "Failed to compile regular expression '" << pattern << "'" + << exit(FatalError); + } + } +} + + +void Foam::regExp::set(const std::string& pattern, const bool ignoreCase) const +{ + return set(pattern.c_str(), ignoreCase); +} + + +bool Foam::regExp::clear() const +{ + if (preg_) + { + regfree(preg_); + delete preg_; + preg_ = 0; + + return true; + } + + return false; +} + + +std::string::size_type Foam::regExp::find(const std::string& str) const +{ + if (preg_ && str.size()) + { + size_t nmatch = 1; + regmatch_t pmatch[1]; + + if (regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0) + { + return pmatch[0].rm_so; + } + } + + return string::npos; +} + + +bool Foam::regExp::match(const std::string& str) const +{ + if (preg_ && str.size()) + { + size_t nmatch = 1; + regmatch_t pmatch[1]; + + // also verify that the entire string was matched + // pmatch[0] is the entire match + if + ( + regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0 + && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size())) + ) + { + return true; + } + } + + return false; +} + + +bool Foam::regExp::match(const string& str, List& groups) const +{ + if (preg_ && str.size()) + { + size_t nmatch = ngroups() + 1; + regmatch_t pmatch[nmatch]; + + // also verify that the entire string was matched + // pmatch[0] is the entire match + // pmatch[1..] are the (...) sub-groups + if + ( + regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0 + && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size())) + ) + { + groups.setSize(ngroups()); + label groupI = 0; + + for (size_t matchI = 1; matchI < nmatch; matchI++) + { + if (pmatch[matchI].rm_so != -1 && pmatch[matchI].rm_eo != -1) + { + groups[groupI] = str.substr + ( + pmatch[matchI].rm_so, + pmatch[matchI].rm_eo - pmatch[matchI].rm_so + ); + } + else + { + groups[groupI].clear(); + } + groupI++; + } + + return true; + } + } + + groups.clear(); + return false; +} + + +// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * // + +void Foam::regExp::operator=(const char* pat) +{ + set(pat); +} + + +void Foam::regExp::operator=(const std::string& pat) +{ + set(pat); +} + + +// ************************************************************************* // diff --git a/src/OSspecific/POSIX/regExp.H b/src/OSspecific/POSIX/regExp.H new file mode 100644 index 000000000..f0231f8d2 --- /dev/null +++ b/src/OSspecific/POSIX/regExp.H @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright held by original author + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::regExp + +Description + Wrapper around POSIX extended regular expressions. + +SeeAlso + The manpage regex(7) for more information about POSIX regular expressions. + These differ somewhat from @c Perl and @c sed regular expressions. + +SourceFiles + regExp.C + +\*---------------------------------------------------------------------------*/ + +#ifndef regExp_H +#define regExp_H + +#include +#include + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class string; +template class List; + +/*---------------------------------------------------------------------------*\ + Class regExp Declaration +\*---------------------------------------------------------------------------*/ + +class regExp +{ + // Private data + + //- Precompiled regular expression + mutable regex_t* preg_; + + // Private member functions + + //- Disallow default bitwise copy construct + regExp(const regExp&); + + //- Disallow default bitwise assignment + void operator=(const regExp&); + +public: + + //- Is character a regular expression meta-character? + // any character: '.' \n + // quantifiers: '*', '+', '?' \n + // grouping: '(', '|', ')' \n + // range: '[', ']' \n + // + // Don't bother checking for '{digit}' bounds + inline static bool meta(char c) + { + return + ( + (c == '.') // any character + || (c == '*' || c == '+' || c == '?') // quantifiers + || (c == '(' || c == ')' || c == '|') // grouping/branching + || (c == '[' || c == ']') // range + ); + } + + + // Constructors + + //- Construct null + regExp(); + + //- Construct from character array, optionally ignoring case + regExp(const char*, const bool ignoreCase=false); + + //- Construct from std::string (or string), optionally ignoring case + regExp(const std::string&, const bool ignoreCase=false); + + // Destructor + + ~regExp(); + + + // Member functions + + //- Access + + //- Return true if a precompiled expression does not exist + inline bool empty() const + { + return !preg_; + } + + //- Does a precompiled expression exist? + inline bool exists() const + { + return preg_ ? true : false; + } + + //- Return the number of (groups) + inline int ngroups() const + { + return preg_ ? preg_->re_nsub : 0; + } + + + //- Editing + + //- Compile pattern into a regular expression, optionally ignoring case + void set(const char*, const bool ignoreCase=false) const; + + //- Compile pattern into a regular expression, optionally ignoring case + void set(const std::string&, const bool ignoreCase=false) const; + + + //- Release precompiled expression. + // Returns true if precompiled expression existed before clear + bool clear() const; + + + //- Searching + + //- Find position within string. + // Returns the index where it begins or string::npos if not found + std::string::size_type find(const std::string& str) const; + + //- Return true if it matches the entire string + // The begin-of-line (^) and end-of-line ($) anchors are implicit + bool match(const std::string&) const; + + //- Return true if it matches and sets the sub-groups matched + // The begin-of-line (^) and end-of-line ($) anchors are implicit + bool match(const string&, List& groups) const; + + //- Return true if the regex was found in within string + bool search(const std::string& str) const + { + return std::string::npos != find(str); + } + + + // Member Operators + + //- Assign and compile pattern from a character array + // Always case sensitive + void operator=(const char*); + + //- Assign and compile pattern from string + // Always case sensitive + void operator=(const std::string&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OSspecific/Unix/signals/sigFpe.C b/src/OSspecific/POSIX/signals/sigFpe.C similarity index 92% rename from src/OSspecific/Unix/signals/sigFpe.C rename to src/OSspecific/POSIX/signals/sigFpe.C index 571a645ec..54cb6559f 100644 --- a/src/OSspecific/Unix/signals/sigFpe.C +++ b/src/OSspecific/POSIX/signals/sigFpe.C @@ -24,8 +24,6 @@ License \*---------------------------------------------------------------------------*/ -#include - #include "error.H" #include "sigFpe.H" @@ -69,7 +67,7 @@ void* Foam::sigFpe::my_malloc_hook(size_t size, const void *caller) result = malloc (size); // initialize to signalling nan -# ifdef SP +# ifdef WM_SP const uint32_t sNAN = 0x7ff7fffflu; @@ -155,7 +153,7 @@ Foam::sigFpe::~sigFpe() ( "Foam::sigFpe::~sigFpe()" ) << "Cannot reset SIGFPE trapping" - << abort(FatalError); + << abort(FatalError); } # endif @@ -178,7 +176,7 @@ Foam::sigFpe::~sigFpe() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::sigFpe::set() +void Foam::sigFpe::set(const bool verbose) { if (oldAction_.sa_handler) { @@ -191,6 +189,12 @@ void Foam::sigFpe::set() if (env("FOAM_SIGFPE")) { + if (verbose) + { + Info<< "SigFpe : Enabling floating point exception trapping" + << " (FOAM_SIGFPE)." << endl; + } + # ifdef LINUX_GNUC feenableexcept @@ -210,7 +214,7 @@ void Foam::sigFpe::set() ( "Foam::sigFpe::set()" ) << "Cannot set SIGFPE trapping" - << abort(FatalError); + << abort(FatalError); } @@ -241,6 +245,12 @@ void Foam::sigFpe::set() if (env("FOAM_SETNAN")) { + if (verbose) + { + Info<< "SetNaN : Initialising allocated memory to NaN" + << " (FOAM_SETNAN)." << endl; + } + # ifdef LINUX_GNUC // Set our malloc diff --git a/src/OSspecific/Unix/signals/sigFpe.H b/src/OSspecific/POSIX/signals/sigFpe.H similarity index 98% rename from src/OSspecific/Unix/signals/sigFpe.H rename to src/OSspecific/POSIX/signals/sigFpe.H index cea24ec85..d50eed8ab 100644 --- a/src/OSspecific/Unix/signals/sigFpe.H +++ b/src/OSspecific/POSIX/signals/sigFpe.H @@ -107,7 +107,7 @@ public: // Member functions - void set(); + void set(const bool verbose); }; diff --git a/src/OSspecific/Unix/signals/sigInt.C b/src/OSspecific/POSIX/signals/sigInt.C similarity index 98% rename from src/OSspecific/Unix/signals/sigInt.C rename to src/OSspecific/POSIX/signals/sigInt.C index 84842f5eb..6ce912ce7 100644 --- a/src/OSspecific/Unix/signals/sigInt.C +++ b/src/OSspecific/POSIX/signals/sigInt.C @@ -81,7 +81,7 @@ Foam::sigInt::~sigInt() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::sigInt::set() +void Foam::sigInt::set(const bool verbose) { if (oldAction_.sa_handler) { diff --git a/src/OSspecific/Unix/signals/sigInt.H b/src/OSspecific/POSIX/signals/sigInt.H similarity index 98% rename from src/OSspecific/Unix/signals/sigInt.H rename to src/OSspecific/POSIX/signals/sigInt.H index 05aba55b9..6a0af7734 100644 --- a/src/OSspecific/Unix/signals/sigInt.H +++ b/src/OSspecific/POSIX/signals/sigInt.H @@ -78,7 +78,7 @@ public: // Member functions - void set(); + void set(const bool verbose); }; diff --git a/src/OSspecific/Unix/signals/sigQuit.C b/src/OSspecific/POSIX/signals/sigQuit.C similarity index 98% rename from src/OSspecific/Unix/signals/sigQuit.C rename to src/OSspecific/POSIX/signals/sigQuit.C index e62c426f8..01644e486 100644 --- a/src/OSspecific/Unix/signals/sigQuit.C +++ b/src/OSspecific/POSIX/signals/sigQuit.C @@ -83,7 +83,7 @@ Foam::sigQuit::~sigQuit() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::sigQuit::set() +void Foam::sigQuit::set(const bool verbose) { if (oldAction_.sa_handler) { diff --git a/src/OSspecific/Unix/signals/sigQuit.H b/src/OSspecific/POSIX/signals/sigQuit.H similarity index 98% rename from src/OSspecific/Unix/signals/sigQuit.H rename to src/OSspecific/POSIX/signals/sigQuit.H index ce084c504..014e14115 100644 --- a/src/OSspecific/Unix/signals/sigQuit.H +++ b/src/OSspecific/POSIX/signals/sigQuit.H @@ -78,7 +78,7 @@ public: // Member functions - void set(); + void set(const bool verbose); }; diff --git a/src/OSspecific/Unix/signals/sigSegv.C b/src/OSspecific/POSIX/signals/sigSegv.C similarity index 98% rename from src/OSspecific/Unix/signals/sigSegv.C rename to src/OSspecific/POSIX/signals/sigSegv.C index b9e33e9a4..c3df5ec9f 100644 --- a/src/OSspecific/Unix/signals/sigSegv.C +++ b/src/OSspecific/POSIX/signals/sigSegv.C @@ -83,7 +83,7 @@ Foam::sigSegv::~sigSegv() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::sigSegv::set() +void Foam::sigSegv::set(const bool verbose) { if (oldAction_.sa_handler) { diff --git a/src/OSspecific/Unix/signals/sigSegv.H b/src/OSspecific/POSIX/signals/sigSegv.H similarity index 98% rename from src/OSspecific/Unix/signals/sigSegv.H rename to src/OSspecific/POSIX/signals/sigSegv.H index 75ff3f3d9..ac87a2b0e 100644 --- a/src/OSspecific/Unix/signals/sigSegv.H +++ b/src/OSspecific/POSIX/signals/sigSegv.H @@ -78,7 +78,7 @@ public: // Member functions - void set(); + void set(const bool verbose); }; diff --git a/src/OSspecific/Unix/timer.C b/src/OSspecific/POSIX/timer.C similarity index 100% rename from src/OSspecific/Unix/timer.C rename to src/OSspecific/POSIX/timer.C diff --git a/src/OSspecific/Unix/timer.H b/src/OSspecific/POSIX/timer.H similarity index 100% rename from src/OSspecific/Unix/timer.H rename to src/OSspecific/POSIX/timer.H diff --git a/src/OSspecific/Unix/Make/options b/src/OSspecific/Unix/Make/options deleted file mode 100644 index 3308f1753..000000000 --- a/src/OSspecific/Unix/Make/options +++ /dev/null @@ -1,4 +0,0 @@ -EXE_INC = \ - -LIB_LIBS = \ - -lpthread diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index c07b8aecc..eec21db5d 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -3,32 +3,42 @@ global/dimensionedConstants/dimensionedConstants.C global/argList/argList.C global/clock/clock.C -primitives/bool/bool.C -primitives/bool/boolIO.C +bools = primitives/bools +$(bools)/bool/bool.C +$(bools)/bool/boolIO.C +$(bools)/Switch/Switch.C +$(bools)/Switch/SwitchIO.C + primitives/char/charIO.C -primitives/int/intIO.C -primitives/uint/uintIO.C -primitives/long/longIO.C -primitives/longLong/longLongIO.C -primitives/ulong/ulongIO.C -primitives/label/label.C + +ints = primitives/ints +$(ints)/int/intIO.C +$(ints)/uint/uintIO.C +$(ints)/long/longIO.C +$(ints)/longLong/longLongIO.C +$(ints)/ulong/ulongIO.C +$(ints)/label/label.C +$(ints)/uLabel/uLabel.C + primitives/Scalar/doubleScalar/doubleScalar.C primitives/Scalar/floatScalar/floatScalar.C primitives/Scalar/scalar/scalar.C -primitives/labelVector/labelVector.C -primitives/vector/vector.C -primitives/vector2D/vector2D.C -primitives/sphericalTensor/sphericalTensor.C -primitives/sphericalTensor2D/sphericalTensor2D.C -primitives/diagTensor/diagTensor.C -primitives/symmTensor/symmTensor.C -primitives/tensor/tensor.C -primitives/tensor2D/tensor2D.C -primitives/labelSphericalTensor/labelSphericalTensor.C -primitives/labelSymmTensor/labelSymmTensor.C -primitives/labelTensor/labelTensor.C +primitives/DiagTensor/diagTensor/diagTensor.C +primitives/SphericalTensor/sphericalTensor/sphericalTensor.C +primitives/SphericalTensor/labelSphericalTensor/labelSphericalTensor.C +primitives/SymmTensor/labelSymmTensor/labelSymmTensor.C +primitives/SymmTensor/symmTensor/symmTensor.C +primitives/Tensor/labelTensor/labelTensor.C +primitives/Tensor/tensor/tensor.C +primitives/Vector/complexVector/complexVector.C +primitives/Vector/labelVector/labelVector.C +primitives/Vector/vector/vector.C + +primitives/Tensor2D/tensor2D/tensor2D.C +primitives/SphericalTensor2D/sphericalTensor2D/sphericalTensor2D.C +primitives/Vector2D/vector2D/vector2D.C + primitives/complex/complex.C -primitives/complexVector/complexVector.C primitives/quaternion/quaternion.C primitives/septernion/septernion.C @@ -39,6 +49,14 @@ $(strings)/word/word.C $(strings)/word/wordIO.C $(strings)/fileName/fileName.C $(strings)/fileName/fileNameIO.C +$(strings)/keyType/keyTypeIO.C +$(strings)/wordRe/wordReIO.C + +primitives/hashes/Hasher/Hasher.C + +sha1 = primitives/hashes/SHA1 +$(sha1)/SHA1.C +$(sha1)/SHA1Digest.C coordinateSystems/coordinateSystem.C coordinateSystems/coordinateSystems.C @@ -68,6 +86,7 @@ primitiveLists = primitives/Lists $(primitiveLists)/boolList.C $(primitiveLists)/labelIOList.C $(primitiveLists)/scalarList.C +$(primitiveLists)/scalarIOList.C $(primitiveLists)/vectorList.C $(primitiveLists)/sphericalTensorList.C $(primitiveLists)/symmTensorList.C @@ -81,19 +100,14 @@ IOstreams = $(Streams)/IOstreams $(IOstreams)/IOstream.C $(IOstreams)/versionNumber.C $(IOstreams)/Istream.C -$(IOstreams)/IOprint.C -$(IOstreams)/IOcheck.C $(IOstreams)/Ostream.C Sstreams = $(Streams)/Sstreams -$(Sstreams)/ISread.C -$(Sstreams)/ISnextValid.C -$(Sstreams)/ISreadToken.C +$(Sstreams)/ISstream.C +$(Sstreams)/OSstream.C +$(Sstreams)/SstreamsPrint.C $(Sstreams)/readHexLabel.C -$(Sstreams)/OSwrite.C -$(Sstreams)/Sprint.C -$(Sstreams)/prefixOSstream/prefixOSwrite.C -$(Sstreams)/prefixOSstream/prefixOSprint.C +$(Sstreams)/prefixOSstream.C gzstream = $(Streams)/gzstream $(gzstream)/gzstream.C @@ -103,19 +117,17 @@ $(Fstreams)/IFstream.C $(Fstreams)/OFstream.C Tstreams = $(Streams)/Tstreams -$(Tstreams)/ITread.C -$(Tstreams)/Tprint.C +$(Tstreams)/ITstream.C StringStreams = $(Streams)/StringStreams -$(StringStreams)/StringStreamPrint.C +$(StringStreams)/StringStreamsPrint.C Pstreams = $(Streams)/Pstreams $(Pstreams)/Pstream.C $(Pstreams)/PstreamCommsStruct.C -$(Pstreams)/IPread.C -$(Pstreams)/OPwrite.C -$(Pstreams)/Pprint.C -$(Pstreams)/IPreadToken.C +$(Pstreams)/IPstream.C +$(Pstreams)/OPstream.C +$(Pstreams)/PstreamsPrint.C dictionary = db/dictionary $(dictionary)/dictionary.C @@ -136,6 +148,7 @@ $(dictionaryEntry)/dictionaryEntryIO.C functionEntries = $(dictionary)/functionEntries $(functionEntries)/functionEntry/functionEntry.C $(functionEntries)/includeEntry/includeEntry.C +$(functionEntries)/includeIfPresentEntry/includeIfPresentEntry.C $(functionEntries)/inputModeEntry/inputModeEntry.C $(functionEntries)/removeEntry/removeEntry.C @@ -158,14 +171,13 @@ $(regIOobject)/regIOobjectWrite.C db/IOobjectList/IOobjectList.C db/objectRegistry/objectRegistry.C -db/functionObject/functionObject.C -db/functionObjectList/functionObjectList.C db/CallbackRegistry/CallbackRegistryName.C db/dlLibraryTable/dlLibraryTable.C -Switch = db/Switch -$(Switch)/Switch.C -$(Switch)/SwitchIO.C +db/functionObjects/functionObject/functionObject.C +db/functionObjects/functionObjectList/functionObjectList.C +db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C + Time = db/Time $(Time)/TimePaths.C @@ -319,7 +331,6 @@ $(tetCell)/tetCell.C cellModeller = $(meshShapes)/cellModeller $(cellModeller)/cellModeller.C -$(cellModeller)/cellModellerIO.C cellModel = $(meshShapes)/cellModel $(cellModel)/cellModel.C @@ -383,7 +394,7 @@ faceZone = $(zones)/faceZone $(faceZone)/faceZone.C $(faceZone)/newFaceZone.C -pointZone = $(zones)/pointZone +pointZone = $(polyMesh)/zones/pointZone $(pointZone)/pointZone.C $(pointZone)/newPointZone.C @@ -434,7 +445,6 @@ $(cellMatcher)/degenerateMatcher.C mapPolyMesh = $(polyMesh)/mapPolyMesh $(mapPolyMesh)/mapPolyMesh.C -$(mapPolyMesh)/pointMapper/pointMapper.C $(mapPolyMesh)/faceMapper/faceMapper.C $(mapPolyMesh)/cellMapper/cellMapper.C $(mapPolyMesh)/mapDistribute/mapDistribute.C @@ -486,6 +496,9 @@ meshTools = meshes/meshTools $(meshTools)/matchPoints.C $(meshTools)/mergePoints.C +fields/UniformDimensionedFields/uniformDimensionedFields.C +fields/cloud/cloud.C + Fields = fields/Fields $(Fields)/labelField/labelField.C $(Fields)/scalarField/scalarField.C @@ -495,8 +508,6 @@ $(Fields)/symmTensorField/symmTensorField.C $(Fields)/tensorField/tensorField.C $(Fields)/complexFields/complexFields.C -fields/cloud/cloud.C - $(Fields)/labelField/labelIOField.C $(Fields)/scalarField/scalarIOField.C $(Fields)/vectorField/vectorIOField.C @@ -506,6 +517,7 @@ $(Fields)/diagTensorField/diagTensorIOField.C $(Fields)/symmTensorField/symmTensorIOField.C $(Fields)/tensorField/tensorIOField.C $(Fields)/transformField/transformField.C + pointPatchFields = fields/pointPatchFields $(pointPatchFields)/pointPatchField/pointPatchFields.C diff --git a/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.C b/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.C index 2273ccf53..2d809fe9e 100644 --- a/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.C +++ b/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.C @@ -28,22 +28,15 @@ Description #include "Dictionary.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -// Null constructor template -Dictionary::Dictionary() +Foam::Dictionary::Dictionary() {} -// Copy constructor template -Dictionary::Dictionary(const Dictionary& dict) +Foam::Dictionary::Dictionary(const Dictionary& dict) : DictionaryBase, T>(dict) {} @@ -52,10 +45,10 @@ Dictionary::Dictionary(const Dictionary& dict) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -bool Dictionary::erase(const word& Keyword) +bool Foam::Dictionary::erase(const word& keyword) { T* tPtr; - if ((tPtr = this->remove(Keyword))) + if (tPtr = this->remove(keyword)) { delete tPtr; return true; @@ -69,6 +62,4 @@ bool Dictionary::erase(const word& Keyword) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -} // End namespace Foam - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.H b/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.H index 085e49580..9a39f787f 100644 --- a/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.H +++ b/src/OpenFOAM/containers/Dictionaries/Dictionary/Dictionary.H @@ -27,8 +27,10 @@ Class Description Gerneral purpose template dictionary class which manages the storage - associated with it. It is derived from DictionaryBase instantiated on - a memory managed form of intrusive doubly-linked list of \. + associated with it. + + It is derived from DictionaryBase instantiated on a memory managed form + of intrusive doubly-linked list of \. SourceFiles Dictionary.C @@ -47,7 +49,7 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class Dictionary Declaration + Class Dictionary Declaration \*---------------------------------------------------------------------------*/ template @@ -69,11 +71,9 @@ public: // Member functions - // Editing - - //- Remove an entry specified by keyword from the dictionary - // and delete it - bool erase(const word& keyword); + //- Remove an entry specified by keyword and delete the pointer. + // Returns true if the keyword was found + bool erase(const word& keyword); }; diff --git a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C index 586481437..8281c88a7 100644 --- a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C +++ b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C @@ -26,15 +26,10 @@ License #include "DictionaryBase.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template -void DictionaryBase::addEntries() +void Foam::DictionaryBase::addEntries() { for ( @@ -51,12 +46,15 @@ void DictionaryBase::addEntries() // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template -DictionaryBase::DictionaryBase() +Foam::DictionaryBase::DictionaryBase() {} template -DictionaryBase::DictionaryBase(const DictionaryBase& dict) +Foam::DictionaryBase::DictionaryBase +( + const DictionaryBase& dict +) : IDLListType(dict) { @@ -66,17 +64,20 @@ DictionaryBase::DictionaryBase(const DictionaryBase& dict) template template -DictionaryBase::DictionaryBase(Istream& is, const INew& inewt) +Foam::DictionaryBase::DictionaryBase +( + Istream& is, + const INew& iNew +) : - IDLListType(is, inewt) + IDLListType(is, iNew) { addEntries(); } -// Istream constructor template -DictionaryBase::DictionaryBase(Istream& is) +Foam::DictionaryBase::DictionaryBase(Istream& is) : IDLListType(is) { @@ -88,25 +89,60 @@ DictionaryBase::DictionaryBase(Istream& is) // Find and return T template -bool DictionaryBase::found(const word& keyword) const +bool Foam::DictionaryBase::found(const word& keyword) const { return hashedTs_.found(keyword); } -// Find and return T* +// Find and return T*, return NULL if not found template -const T* DictionaryBase::lookup(const word& keyword) const +const T* Foam::DictionaryBase::lookupPtr +( + const word& keyword +) const +{ + typename HashTable::const_iterator iter = hashedTs_.find(keyword); + + if (iter != hashedTs_.end()) + { + return *iter; + } + else + { + return NULL; + } +} + + +// Find and return T*, return NULL if not found +template +T* Foam::DictionaryBase::lookupPtr(const word& keyword) +{ + typename HashTable::iterator iter = hashedTs_.find(keyword); + + if (iter != hashedTs_.end()) + { + return *iter; + } + else + { + return NULL; + } +} + + +// Find and return T*, FatalError if keyword not found +template +const T* Foam::DictionaryBase::lookup(const word& keyword) const { typename HashTable::const_iterator iter = hashedTs_.find(keyword); if (iter == hashedTs_.end()) { - // If keyword not found print error message ... FatalErrorIn ( - "DictionaryBase::" - "lookup(const word& keyword) const" + "DictionaryBase::lookup(const word&) const" ) << keyword << " is undefined" << exit(FatalError); } @@ -115,18 +151,17 @@ const T* DictionaryBase::lookup(const word& keyword) const } -// Find and return T* +// Find and return T*, FatalError if keyword not found template -T* DictionaryBase::lookup(const word& keyword) +T* Foam::DictionaryBase::lookup(const word& keyword) { typename HashTable::iterator iter = hashedTs_.find(keyword); if (iter == hashedTs_.end()) { - // If keyword not found print error message ... FatalErrorIn ( - "DictionaryBase::lookup(const word& keyword)" + "DictionaryBase::lookup(const word&)" ) << keyword << " is undefined" << exit(FatalError); } @@ -137,7 +172,7 @@ T* DictionaryBase::lookup(const word& keyword) // Return the table of contents template -wordList DictionaryBase::toc() const +Foam::wordList Foam::DictionaryBase::toc() const { wordList keywords(this->size()); @@ -158,26 +193,28 @@ wordList DictionaryBase::toc() const // Add at head of dictionary template -void DictionaryBase::insert(const word& keyword, T* tPtr) +void Foam::DictionaryBase::insert(const word& keyword, T* tPtr) { - IDLListType::insert(tPtr); + // NOTE: we should probably check that HashTable::insert actually worked hashedTs_.insert(keyword, tPtr); + IDLListType::insert(tPtr); } // Add at tail of dictionary template -void DictionaryBase::append(const word& keyword, T* tPtr) +void Foam::DictionaryBase::append(const word& keyword, T* tPtr) { - IDLListType::append(tPtr); + // NOTE: we should probably check that HashTable::insert actually worked hashedTs_.insert(keyword, tPtr); + IDLListType::append(tPtr); } template -T* DictionaryBase::remove(const word& Keyword) +T* Foam::DictionaryBase::remove(const word& keyword) { - typename HashTable::iterator iter = hashedTs_.find(Keyword); + typename HashTable::iterator iter = hashedTs_.find(keyword); if (iter != hashedTs_.end()) { @@ -192,19 +229,29 @@ T* DictionaryBase::remove(const word& Keyword) } -//- Clear the dictionary template -void DictionaryBase::clear() +void Foam::DictionaryBase::clear() { IDLListType::clear(); hashedTs_.clear(); } +template +void Foam::DictionaryBase::transfer +( + DictionaryBase& dict +) +{ + IDLListType::transfer(dict); + hashedTs_.transfer(dict.hashedTs_); +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template -void DictionaryBase::operator= +void Foam::DictionaryBase::operator= ( const DictionaryBase& dict ) @@ -218,25 +265,11 @@ void DictionaryBase::operator= } IDLListType::operator=(dict); - this->hashedTs_.clear(); - - for - ( - typename IDLListType::iterator iter = this->begin(); - iter != this->end(); - ++iter - ) - { - this->hashedTs_.insert((*iter).keyword(), &(*iter)); - } + this->addEntries(); } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "DictionaryBaseIO.C" diff --git a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.H b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.H index 986458e4d..340dee77b 100644 --- a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.H +++ b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.H @@ -29,12 +29,12 @@ Description Base dictionary class templated on both the form of doubly-linked list it uses as well as the type it holds. - The double templating allows for the instantiation of forms with and + The double templating allows for the instantiation of forms with or without storage management. Note The IDLListType parameter should itself be a template but this confused - gcc 2.95.2 so it has to be instantiated for T when an intantiation of + gcc 2.95.2 so it has to be instantiated for T when an instantiation of DictionaryBase is requested See Also @@ -67,7 +67,7 @@ Ostream& operator<<(Ostream&, const DictionaryBase&); /*---------------------------------------------------------------------------*\ - Class DictionaryBase Declaration + Class DictionaryBase Declaration \*---------------------------------------------------------------------------*/ template @@ -77,7 +77,7 @@ class DictionaryBase { // Private data - //- HashTable of the enries held on the DL-list for quick lookup + //- HashTable of the entries held on the IDLListType for quick lookup HashTable hashedTs_; @@ -99,10 +99,10 @@ public: //- Construct from Istream using given Istream constructor class template - DictionaryBase(Istream& is, const INew& inewt); + DictionaryBase(Istream&, const INew&); - //- Construct from Istream - DictionaryBase(Istream& is); + //- Construct from Istream using default Istream constructor class + DictionaryBase(Istream&); // Member functions @@ -110,7 +110,13 @@ public: // Search and lookup //- Search DictionaryBase for given keyword - bool found(const word& keyword) const; + bool found(const word&) const; + + //- Find and return an entry if present, otherwise return NULL + const T* lookupPtr(const word&) const; + + //- Find and return an entry if present, otherwise return NULL + T* lookupPtr(const word&); //- Find and return entry const T* lookup(const word&) const; @@ -125,17 +131,21 @@ public: // Editing //- Add at head of dictionary - void insert(const word& keyword, T*); + void insert(const word&, T*); //- Add at tail of dictionary - void append(const word& keyword, T*); + void append(const word&, T*); - //- Remove and return entry specified by keyword - T* remove(const word& keyword); + //- Remove and return entry specified by keyword. + // Return NULL if the keyword was not found. + T* remove(const word&); //- Clear the dictionary void clear(); + //- Transfer the contents of the argument into this DictionaryBase + // and annull the argument. + void transfer(DictionaryBase&); // Member operators diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C new file mode 100644 index 000000000..48d4437b4 --- /dev/null +++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C @@ -0,0 +1,199 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright held by original author + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#ifndef HashSet_C +#define HashSet_C + +#include "HashSet.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +template +Foam::HashSet::HashSet +( + const HashTable& h +) +: + HashTable(h.size()) +{ + for + ( + typename HashTable::const_iterator + cit = h.cbegin(); + cit != h.cend(); + ++cit + ) + { + insert(cit.key()); + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline bool Foam::HashSet::operator[](const Key& key) const +{ + return found(key); +} + + +template +bool Foam::HashSet::operator==(const HashSet& rhs) const +{ + // Are all lhs elements in rhs? + for (const_iterator iter = this->cbegin(); iter != this->cend(); ++iter) + { + if (!rhs.found(iter.key())) + { + return false; + } + } + + // Are all rhs elements in lhs? + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + if (!found(iter.key())) + { + return false; + } + } + + return true; +} + + +template +bool Foam::HashSet::operator!=(const HashSet& rhs) const +{ + return !(operator==(rhs)); +} + + +template +void Foam::HashSet::operator|=(const HashSet& rhs) +{ + // Add rhs elements into lhs + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + insert(iter.key()); + } +} + + +template +void Foam::HashSet::operator&=(const HashSet& rhs) +{ + // Remove elements not also found in rhs + for (iterator iter = this->begin(); iter != this->end(); ++iter) + { + if (!rhs.found(iter.key())) + { + erase(iter); + } + } +} + + +template +void Foam::HashSet::operator^=(const HashSet& rhs) +{ + // Add missed rhs elements, remove duplicate elements + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + if (found(iter.key())) + { + erase(iter.key()); + } + else + { + insert(iter.key()); + } + } +} + + +// same as HashTable::erase() +template +void Foam::HashSet::operator-=(const HashSet& rhs) +{ + // Remove rhs elements from lhs + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + erase(iter.key()); + } +} + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +template +Foam::HashSet +Foam::operator| +( + const HashSet& hash1, + const HashSet& hash2 +) +{ + HashSet out(hash1); + out |= hash2; + return out; +} + + +template +Foam::HashSet +Foam::operator& +( + const HashSet& hash1, + const HashSet& hash2 +) +{ + HashSet out(hash1); + out &= hash2; + return out; +} + + +template +Foam::HashSet +Foam::operator^ +( + const HashSet& hash1, + const HashSet& hash2 +) +{ + HashSet out(hash1); + out ^= hash2; + return out; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H index 25ab0b6bf..5d54cc0b7 100644 --- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H +++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H @@ -26,7 +26,7 @@ Class Foam::HashSet Description - A HashTable with word keys but without contents. + A HashTable with keys but without contents. Typedef Foam::wordHashSet @@ -34,13 +34,19 @@ Typedef Description A HashSet with (the default) word keys. +Typedef + Foam::labelHashSet + +Description + A HashSet with label keys. + \*---------------------------------------------------------------------------*/ #ifndef HashSet_H #define HashSet_H #include "HashTable.H" -#include "empty.H" +#include "nil.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -54,57 +60,149 @@ namespace Foam template class HashSet : - public HashTable + public HashTable { public: + typedef typename HashTable::iterator iterator; + typedef typename HashTable::const_iterator const_iterator; + + // Constructors - //- Construct given initial map size - explicit HashSet(label size = 100) + //- Construct given initial size + HashSet(const label size = 128) : - HashTable(size) + HashTable(size) {} //- Construct from Istream - explicit HashSet(Istream& is) + HashSet(Istream& is) : - HashTable(is) + HashTable(is) {} //- Construct from UList of Key - explicit HashSet(const UList& ul) + HashSet(const UList& lst) : - HashTable(2*ul.size()) + HashTable(2*lst.size()) { - forAll (ul, i) + forAll(lst, i) { - insert(ul[i]); + insert(lst[i]); } } //- Construct as copy HashSet(const HashSet& hs) : - HashTable(hs) + HashTable(hs) {} + //- Construct by transferring the parameter contents + HashSet(const Xfer >& hs) + : + HashTable(hs) + {} + + //- Construct by transferring the parameter contents + HashSet(const Xfer >& hs) + : + HashTable(hs) + {} + + //- Construct from the keys of another HashTable, + // the type of values held is arbitrary. + template + HashSet(const HashTable&); + // Member Functions // Edit - //- Insert a new hashedEntry - bool insert(const Key& key) - { - return HashTable::insert(key, empty()); - } + //- Insert a new entry + bool insert(const Key& key) + { + return HashTable::insert(key, nil()); + } + + //- Same as insert (cannot overwrite nil content) + bool set(const Key& key) + { + return HashTable::insert(key, nil()); + } + + + // Member Operators + + //- Return true if the entry exists, same as found() + inline bool operator[](const Key&) const; + + //- Equality. Two hashtables are equal when their contents are equal. + // Independent of table size or order. + bool operator==(const HashSet&) const; + + //- The opposite of the equality operation. + bool operator!=(const HashSet&) const; + + + //- Combine entries from HashSets + void operator|=(const HashSet&); + + //- Only retain entries found in both HashSets + void operator&=(const HashSet&); + + //- Only retain unique entries (xor) + void operator^=(const HashSet&); + + //- Add entries listed in the given HashSet to this HashSet + inline void operator+=(const HashSet& rhs) + { + this->operator|=(rhs); + } + + //- Remove entries listed in the given HashSet from this HashSet + void operator-=(const HashSet&); }; +// Global Operators + +//- Combine entries from HashSets +template +HashSet operator| +( + const HashSet& hash1, + const HashSet& hash2 +); + + +//- Create a HashSet that only contains entries found in both HashSets +template +HashSet operator& +( + const HashSet& hash1, + const HashSet& hash2 +); + + +//- Create a HashSet that only contains unique entries (xor) +template +HashSet operator^ +( + const HashSet& hash1, + const HashSet& hash2 +); + + +//- A HashSet with word keys. typedef HashSet<> wordHashSet; +//- A HashSet with label keys. +typedef HashSet > labelHashSet; + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -112,6 +210,12 @@ typedef HashSet<> wordHashSet; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository +# include "HashSet.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C index a58debf6e..054013796 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C @@ -30,40 +30,64 @@ License #include "HashTable.H" #include "List.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // -namespace Foam +template +Foam::label Foam::HashTable::canonicalSize(const label size) { + if (size < 1) + { + return 0; + } + + // enforce power of two + unsigned int goodSize = size; + + if (goodSize & (goodSize - 1)) + { + // brute-force is fast enough + goodSize = 1; + while (goodSize < unsigned(size)) + { + goodSize <<= 1; + } + } + + return goodSize; +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template -HashTable::HashTable(const label size) +Foam::HashTable::HashTable(const label size) : - tableSize_(size), - table_(NULL), + HashTableName(), nElmts_(0), + tableSize_(canonicalSize(size)), + table_(NULL), endIter_(*this, NULL, 0), endConstIter_(*this, NULL, 0) { if (tableSize_) { table_ = new hashedEntry*[tableSize_]; - for (label i=0; i -HashTable::HashTable(const HashTable& ht) +Foam::HashTable::HashTable(const HashTable& ht) : HashTableName(), + nElmts_(0), tableSize_(ht.tableSize_), table_(NULL), - nElmts_(0), endIter_(*this, NULL, 0), endConstIter_(*this, NULL, 0) { @@ -71,23 +95,39 @@ HashTable::HashTable(const HashTable& ht) { table_ = new hashedEntry*[tableSize_]; - for (label i=0; i +Foam::HashTable::HashTable +( + const Xfer >& ht +) +: + HashTableName(), + nElmts_(0), + tableSize_(0), + table_(NULL), + endIter_(*this, NULL, 0), + endConstIter_(*this, NULL, 0) +{ + transfer(ht()); +} + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template -HashTable::~HashTable() +Foam::HashTable::~HashTable() { if (table_) { @@ -100,15 +140,18 @@ HashTable::~HashTable() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -bool HashTable::found(const Key& key) const +bool Foam::HashTable::found(const Key& key) const { - if (tableSize_) + if (nElmts_) { - label ii = Hash()(key, tableSize_); + const label hashIdx = hashKeyIndex(key); - for (hashedEntry* n=table_[ii]; n; n=n->next_) + for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { - if (key == n->key_) return true; + if (key == ep->key_) + { + return true; + } } } @@ -125,20 +168,22 @@ bool HashTable::found(const Key& key) const template -typename HashTable::iterator HashTable::find +typename Foam::HashTable::iterator +Foam::HashTable::find ( const Key& key ) { - if (tableSize_) + if (nElmts_) { - label ii = Hash()(key, tableSize_); - hashedEntry* prev = 0; + const label hashIdx = hashKeyIndex(key); - for (hashedEntry* n=table_[ii]; n; n=n->next_) + for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { - if (key == n->key_) return iterator(*this, n, ii); - prev = n; + if (key == ep->key_) + { + return iterator(*this, ep, hashIdx); + } } } @@ -155,20 +200,22 @@ typename HashTable::iterator HashTable::find template -typename HashTable::const_iterator HashTable::find +typename Foam::HashTable::const_iterator +Foam::HashTable::find ( const Key& key ) const { - if (tableSize_) + if (nElmts_) { - label ii = Hash()(key, tableSize_); - hashedEntry* prev = 0; + const label hashIdx = hashKeyIndex(key); - for (hashedEntry* n=table_[ii]; n; n=n->next_) + for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { - if (key == n->key_) return const_iterator(*this, n, ii); - prev = n; + if (key == ep->key_) + { + return const_iterator(*this, ep, hashIdx); + } } } @@ -180,19 +227,18 @@ typename HashTable::const_iterator HashTable::find } # endif - return end(); + return cend(); } // Return the table of contents template -List HashTable::toc() const +Foam::List Foam::HashTable::toc() const { List tofc(nElmts_); - label i = 0; - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { tofc[i++] = iter.key(); } @@ -202,36 +248,37 @@ List HashTable::toc() const template -bool HashTable::set +bool Foam::HashTable::set ( const Key& key, const T& newEntry, const bool protect ) { - if (tableSize_ == 0) + if (!tableSize_) { resize(2); } - label ii = Hash()(key, tableSize_); + const label hashIdx = hashKeyIndex(key); + hashedEntry* existing = 0; hashedEntry* prev = 0; - for (hashedEntry* curr = table_[ii]; curr; curr = curr->next_) + for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { - if (key == curr->key_) + if (key == ep->key_) { - existing = curr; + existing = ep; break; } - prev = curr; + prev = ep; } // not found, insert it at the head if (!existing) { - table_[ii] = new hashedEntry(key, table_[ii], newEntry); + table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry); nElmts_++; if (double(nElmts_)/tableSize_ > 0.8) @@ -256,7 +303,7 @@ bool HashTable::set if (debug) { Info<< "HashTable::set" - "(const Key& key, T newEntry, false) : " + "(const Key& key, T newEntry, true) : " "Cannot insert " << key << " already in hash table\n"; } # endif @@ -266,16 +313,16 @@ bool HashTable::set { // found - overwrite existing entry // this corresponds to the Perl convention - hashedEntry* elemPtr = new hashedEntry(key, existing->next_, newEntry); + hashedEntry* ep = new hashedEntry(key, existing->next_, newEntry); // replace existing element - within list or insert at the head if (prev) { - prev->next_ = elemPtr; + prev->next_ = ep; } else { - table_[ii] = elemPtr; + table_[hashIdx] = ep; } delete existing; @@ -286,34 +333,34 @@ bool HashTable::set template -bool HashTable::erase(const iterator& cit) +bool Foam::HashTable::erase(const iterator& cit) { if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_ { iterator& it = const_cast(cit); // Search element before elmtPtr_ - hashedEntry* prevElmtPtr = 0; + hashedEntry* prev = 0; - for (hashedEntry* n=table_[it.hashIndex_]; n; n=n->next_) + for (hashedEntry* ep = table_[it.hashIndex_]; ep; ep = ep->next_) { - if (n == it.elmtPtr_) + if (ep == it.elmtPtr_) { break; } - prevElmtPtr = n; + prev = ep; } - if (prevElmtPtr) + if (prev) { // Have element before elmtPtr - prevElmtPtr->next_ = it.elmtPtr_->next_; + prev->next_ = it.elmtPtr_->next_; delete it.elmtPtr_; - it.elmtPtr_ = prevElmtPtr; + it.elmtPtr_ = prev; } else { - // elmtPtr is first element on SLlist + // elmtPtr is first element on SLList table_[it.hashIndex_] = it.elmtPtr_->next_; delete it.elmtPtr_; @@ -334,7 +381,7 @@ bool HashTable::erase(const iterator& cit) else { // No previous found. Mark with special value which is - // - not end() + // - not end()/cend() // - handled by operator++ it.elmtPtr_ = reinterpret_cast(this); it.hashIndex_ = -1; @@ -369,13 +416,13 @@ bool HashTable::erase(const iterator& cit) template -bool HashTable::erase(const Key& key) +bool Foam::HashTable::erase(const Key& key) { - iterator it = find(key); + iterator fnd = find(key); - if (it != end()) + if (fnd != end()) { - return erase(it); + return erase(fnd); } else { @@ -385,14 +432,60 @@ bool HashTable::erase(const Key& key) template -void HashTable::resize(const label newSize) +Foam::label Foam::HashTable::erase(const UList& keys) { + label count = 0; + + // Remove listed keys from this table + if (this->size()) + { + forAll(keys, keyI) + { + if (erase(keys[keyI])) + { + count++; + } + } + } + + return count; +} + + +template +template +Foam::label Foam::HashTable::erase +( + const HashTable& rhs +) +{ + label count = 0; + + // Remove rhs keys from this table - terminates early if possible + // Could optimize depending on which hash is smaller ... + for (iterator iter = begin(); iter != end(); ++iter) + { + if (rhs.found(iter.key()) && erase(iter)) + { + count++; + } + } + + return count; +} + + +template +void Foam::HashTable::resize(const label sz) +{ + label newSize = canonicalSize(sz); + if (newSize == tableSize_) { # ifdef FULLDEBUG if (debug) { - Info<< "HashTable::resize(const label newSize) : " + Info<< "HashTable::resize(const label) : " << "new table size == old table size\n"; } # endif @@ -402,7 +495,7 @@ void HashTable::resize(const label newSize) HashTable* newTable = new HashTable(newSize); - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { newTable->insert(iter.key(), *iter); } @@ -420,22 +513,22 @@ void HashTable::resize(const label newSize) template -void HashTable::clear() +void Foam::HashTable::clear() { if (nElmts_) { - for (label i=0; inext_) + hashedEntry* ep = table_[hashIdx]; + while (hashedEntry* next = ep->next_) { - delete n; - n = next; + delete ep; + ep = next; } - delete n; - table_[i] = 0; + delete ep; + table_[hashIdx] = 0; } } nElmts_ = 0; @@ -444,10 +537,22 @@ void HashTable::clear() template -void HashTable::transfer(HashTable& ht) +void Foam::HashTable::clearStorage() { clear(); - delete[] table_; + resize(0); +} + + +template +void Foam::HashTable::transfer(HashTable& ht) +{ + // as per the Destructor + if (table_) + { + clear(); + delete[] table_; + } tableSize_ = ht.tableSize_; ht.tableSize_ = 0; @@ -463,10 +568,13 @@ void HashTable::transfer(HashTable& ht) // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template -void HashTable::operator=(const HashTable& ht) +void Foam::HashTable::operator= +( + const HashTable& rhs +) { // Check for assignment to self - if (this == &ht) + if (this == &rhs) { FatalErrorIn ( @@ -476,18 +584,63 @@ void HashTable::operator=(const HashTable& ht) << abort(FatalError); } - clear(); + // could be zero-sized from a previous transfer() + if (!tableSize_) + { + resize(rhs.tableSize_); + } + else + { + clear(); + } - for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { insert(iter.key(), *iter); } } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +template +bool Foam::HashTable::operator== +( + const HashTable& rhs +) const +{ + // Are all my elements in rhs? + for (const_iterator iter = cbegin(); iter != cend(); ++iter) + { + const_iterator fnd = rhs.find(iter.key()); + + if (fnd == rhs.cend() || fnd() != iter()) + { + return false; + } + } + + // Are all rhs elements in me? + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + const_iterator fnd = find(iter.key()); + + if (fnd == cend() || fnd() != iter()) + { + return false; + } + } + return true; +} + + +template +bool Foam::HashTable::operator!= +( + const HashTable& rhs +) const +{ + return !(operator==(rhs)); +} -} // End namespace Foam // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H index 18092ad57..51c916e9b 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H @@ -28,6 +28,13 @@ Class Description An STL-conforming hash table. +Note + Hashing index collisions are handled via chaining using a singly-linked + list with the colliding entry being added to the head of the linked + list. Thus copying the hash table (or indeed even resizing it) will + often result in a different hash order. Use a sorted table-of-contents + when the hash order is important. + SourceFiles HashTableI.H HashTable.C @@ -39,7 +46,9 @@ SourceFiles #define HashTable_H #include "label.H" +#include "uLabel.H" #include "word.H" +#include "Xfer.H" #include "className.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -49,22 +58,16 @@ namespace Foam // Forward declaration of friend functions and operators -template -class List; - +template class List; +template class UList; template class HashTable; +template class HashPtrTable; -template Istream& operator>> -( - Istream&, - HashTable& -); +template +Istream& operator>>(Istream&, HashTable&); -template Ostream& operator<< -( - Ostream&, - const HashTable& -); +template +Ostream& operator<<(Ostream&, const HashTable&); /*---------------------------------------------------------------------------*\ @@ -101,7 +104,7 @@ class HashTable //- Construct given key, next pointer and object inline hashedEntry ( - const Key& key, + const Key&, hashedEntry* next, const T& newEntry ); @@ -113,20 +116,28 @@ class HashTable // Private data: size of table, the table and current number of elements + //- The current number of elements in table + label nElmts_; + //- Number of primary entries allocated in table (not necessarily used) label tableSize_; //- The table of primary entries hashedEntry** table_; - //- The current number of elements in table - label nElmts_; - // Private Member Functions + //- Return a canonical (power-of-two) size + static label canonicalSize(const label); + + //- Return the hash index of the Key within the current table size. + // No checks for zero-sized tables. + inline label hashKeyIndex(const Key&) const; + //- Assign a new hashedEntry to a possibly already existing key - bool set(const Key& key, const T& newElmt, bool protect); + bool set(const Key&, const T& newElmt, bool protect); + public: @@ -147,14 +158,17 @@ public: // Constructors //- Construct given initial table size - HashTable(const label size = 100); + HashTable(const label size = 128); //- Construct from Istream - HashTable(Istream&, const label size = 100); + HashTable(Istream&, const label size = 128); //- Construct as copy HashTable(const HashTable&); + //- Construct by transferring the parameter contents + HashTable(const Xfer >&); + // Destructor @@ -168,34 +182,50 @@ public: //- Return number of elements in table. inline label size() const; + //- Return true if the hash table is empty + inline bool empty() const; + //- Return true if hashedEntry is found in table - bool found(const Key& key) const; + bool found(const Key&) const; //- Find and return an iterator set at the hashedEntry // If not found iterator = end() - iterator find(const Key& key); + iterator find(const Key&); //- Find and return an const_iterator set at the hashedEntry // If not found iterator = end() - const_iterator find(const Key& key) const; + const_iterator find(const Key&) const; //- Return the table of contents List toc() const; + //- Print information + Ostream& printInfo(Ostream&) const; // Edit //- Insert a new hashedEntry - inline bool insert(const Key& key, const T& newElmt); + inline bool insert(const Key&, const T& newElmt); //- Assign a new hashedEntry, overwriting existing entries - inline bool set(const Key& key, const T& newElmt); + inline bool set(const Key&, const T& newElmt); //- Erase an hashedEntry specified by given iterator - bool erase(const iterator& it); + bool erase(const iterator&); //- Erase an hashedEntry specified by given key if in table - bool erase(const Key& key); + bool erase(const Key&); + + //- Remove entries given by the listed keys from this HashTable + // Return the number of elements removed + label erase(const UList&); + + //- Remove entries given by the given keys from this HashTable + // Return the number of elements removed. + // The parameter HashTable needs the same type of key, but the + // type of values held and the hashing function are arbitrary. + template + label erase(const HashTable&); //- Resize the hash table for efficiency void resize(const label newSize); @@ -203,26 +233,40 @@ public: //- Clear all entries from table void clear(); + //- Clear the table entries and the table itself. + // Equivalent to clear() followed by resize(0) + void clearStorage(); + //- Transfer the contents of the argument table into this table // and annull the argument table. void transfer(HashTable&); + //- Transfer contents to the Xfer container + inline Xfer > xfer(); + // Member Operators //- Find and return an hashedEntry - inline T& operator[](const Key& key); + inline T& operator[](const Key&); //- Find and return an hashedEntry - inline const T& operator[](const Key& key) const; + inline const T& operator[](const Key&) const; - //- Find and return an hashedEntry and - // if it is not present create it null. - inline T& operator()(const Key& key); + //- Find and return an hashedEntry, create it null if not present. + inline T& operator()(const Key&); //- Assignment void operator=(const HashTable&); + //- Equality. Two hash tables are equal if all contents of first are + // also in second and vice versa. So does not depend on table size or + // order! + bool operator==(const HashTable&) const; + + //- The opposite of the equality operation. Takes linear time. + bool operator!=(const HashTable&) const; + // STL type definitions @@ -253,7 +297,7 @@ public: // Private data //- Reference to the HashTable this is an iterator for - HashTable& curHashTable_; + HashTable& hashTable_; //- Current element hashedEntry* elmtPtr_; @@ -261,7 +305,6 @@ public: //- Current hash index label hashIndex_; - public: // Constructors @@ -274,24 +317,26 @@ public: label hashIndex ); - // Member operators - inline void operator=(const iterator& iter); + inline void operator=(const iterator&); - inline bool operator==(const iterator& iter) const; - inline bool operator!=(const iterator& iter) const; + inline bool operator==(const iterator&) const; + inline bool operator!=(const iterator&) const; - inline bool operator==(const const_iterator& iter) const; - inline bool operator!=(const const_iterator& iter) const; + inline bool operator==(const const_iterator&) const; + inline bool operator!=(const const_iterator&) const; inline T& operator*(); inline T& operator()(); + inline const T& operator*() const; + inline const T& operator()() const; + inline iterator& operator++(); inline iterator operator++(int); - inline const Key& key(); + inline const Key& key() const; }; @@ -312,7 +357,7 @@ public: // Private data //- Reference to the HashTable this is an iterator for - const HashTable& curHashTable_; + const HashTable& hashTable_; //- Current element const hashedEntry* elmtPtr_; @@ -339,24 +384,30 @@ public: // Member operators - inline void operator=(const const_iterator& iter); + inline void operator=(const const_iterator&); - inline bool operator==(const const_iterator& iter) const; - inline bool operator!=(const const_iterator& iter) const; + inline bool operator==(const const_iterator&) const; + inline bool operator!=(const const_iterator&) const; - inline bool operator==(const iterator& iter) const; - inline bool operator!=(const iterator& iter) const; + inline bool operator==(const iterator&) const; + inline bool operator!=(const iterator&) const; - inline const T& operator*(); - inline const T& operator()(); + inline const T& operator*() const; + inline const T& operator()() const; inline const_iterator& operator++(); inline const_iterator operator++(int); - inline const Key& key(); + inline const Key& key() const; }; + //- const_iterator set to the beginning of the HashTable + inline const_iterator cbegin() const; + + //- const_iterator set to beyond the end of the HashTable + inline const const_iterator& cend() const; + //- const_iterator set to the beginning of the HashTable inline const_iterator begin() const; @@ -366,19 +417,13 @@ public: // IOstream Operator - friend Istream& operator>> - #ifndef __CINT__ - - #endif + friend Istream& operator>> ( Istream&, HashTable& ); - friend Ostream& operator<< - #ifndef __CINT__ - - #endif + friend Ostream& operator<< ( Ostream&, const HashTable& diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H index 90f9dd057..8b3f4aa7f 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H @@ -26,15 +26,10 @@ License #include "error.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * // template -inline HashTable::hashedEntry::hashedEntry +inline Foam::HashTable::hashedEntry::hashedEntry ( const Key& key, hashedEntry* next, @@ -47,39 +42,74 @@ inline HashTable::hashedEntry::hashedEntry {} +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +template +inline Foam::label +Foam::HashTable::hashKeyIndex(const Key& key) const +{ + // size is power of two - this is the modulus + return Hash()(key) & (tableSize_ - 1); +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -inline label HashTable::size() const +inline Foam::label Foam::HashTable::size() const { return nElmts_; } template -inline bool HashTable::insert(const Key& key, const T& newEntry) +inline bool Foam::HashTable::empty() const +{ + return !nElmts_; +} + + +template +inline bool Foam::HashTable::insert +( + const Key& key, + const T& newEntry +) { return set(key, newEntry, true); } template -inline bool HashTable::set(const Key& key, const T& newEntry) +inline bool Foam::HashTable::set +( + const Key& key, + const T& newEntry +) { return set(key, newEntry, false); } + +template +inline Foam::Xfer > +Foam::HashTable::xfer() +{ + return xferMove(*this); +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template -inline T& HashTable::operator[](const Key& key) +inline T& Foam::HashTable::operator[](const Key& key) { iterator iter = find(key); if (iter == end()) { FatalErrorIn("HashTable::operator[](const Key&)") - << key << " not found in table. Valid entries are " + << key << " not found in table. Valid entries: " << toc() << exit(FatalError); } @@ -87,15 +117,16 @@ inline T& HashTable::operator[](const Key& key) return *iter; } + template -inline const T& HashTable::operator[](const Key& key) const +inline const T& Foam::HashTable::operator[](const Key& key) const { const_iterator iter = find(key); - if (iter == end()) + if (iter == cend()) { FatalErrorIn("HashTable::operator[](const Key&) const") - << key << " not found in table. Valid entries are " + << key << " not found in table. Valid entries: " << toc() << exit(FatalError); } @@ -105,7 +136,7 @@ inline const T& HashTable::operator[](const Key& key) const template -inline T& HashTable::operator()(const Key& key) +inline T& Foam::HashTable::operator()(const Key& key) { iterator iter = find(key); @@ -124,21 +155,24 @@ inline T& HashTable::operator()(const Key& key) // * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // template -inline HashTable::iterator::iterator +inline Foam::HashTable::iterator::iterator ( - HashTable& curHashTable, + HashTable& hashTbl, hashedEntry* elmt, label hashIndex ) : - curHashTable_(curHashTable), + hashTable_(hashTbl), elmtPtr_(elmt), hashIndex_(hashIndex) {} template -inline void HashTable::iterator::operator=(const iterator& iter) +inline void Foam::HashTable::iterator::operator= +( + const iterator& iter +) { elmtPtr_ = iter.elmtPtr_; hashIndex_ = iter.hashIndex_; @@ -146,7 +180,7 @@ inline void HashTable::iterator::operator=(const iterator& iter) template -inline bool HashTable::iterator::operator== +inline bool Foam::HashTable::iterator::operator== ( const iterator& iter ) const @@ -156,7 +190,7 @@ inline bool HashTable::iterator::operator== template -inline bool HashTable::iterator::operator!= +inline bool Foam::HashTable::iterator::operator!= ( const iterator& iter ) const @@ -166,7 +200,7 @@ inline bool HashTable::iterator::operator!= template -inline bool HashTable::iterator::operator== +inline bool Foam::HashTable::iterator::operator== ( const const_iterator& iter ) const @@ -176,7 +210,7 @@ inline bool HashTable::iterator::operator== template -inline bool HashTable::iterator::operator!= +inline bool Foam::HashTable::iterator::operator!= ( const const_iterator& iter ) const @@ -186,28 +220,46 @@ inline bool HashTable::iterator::operator!= template -inline T& HashTable::iterator::operator*() +inline T& +Foam::HashTable::iterator::operator*() { return elmtPtr_->obj_; } template -inline T& HashTable::iterator::operator()() +inline T& +Foam::HashTable::iterator::operator()() { - return operator*(); + return elmtPtr_->obj_; +} + + +template +inline const T& +Foam::HashTable::iterator::operator*() const +{ + return elmtPtr_->obj_; +} + + +template +inline const T& +Foam::HashTable::iterator::operator()() const +{ + return elmtPtr_->obj_; } template inline -typename HashTable::iterator& -HashTable::iterator::operator++() +typename Foam::HashTable::iterator& +Foam::HashTable::iterator::operator++() { // Check for special value from erase. (sets hashIndex to -1) if (hashIndex_ >= 0) { - // Do we have additional elements on the singly linked list? + // Do we have additional elements on the SLList? if (elmtPtr_ && elmtPtr_->next_) { elmtPtr_ = elmtPtr_->next_; @@ -218,24 +270,24 @@ HashTable::iterator::operator++() // Step to the next table entry while ( - ++hashIndex_ < curHashTable_.tableSize_ - && !(elmtPtr_ = curHashTable_.table_[hashIndex_]) + ++hashIndex_ < hashTable_.tableSize_ + && !(elmtPtr_ = hashTable_.table_[hashIndex_]) ) {} - if (hashIndex_ == curHashTable_.tableSize_) + if (hashIndex_ == hashTable_.tableSize_) { // make end iterator - hashIndex_ = 0; elmtPtr_ = 0; + hashIndex_ = 0; } return *this; } template -inline typename HashTable::iterator -HashTable::iterator::operator++ +inline typename Foam::HashTable::iterator +Foam::HashTable::iterator::operator++ ( int ) @@ -248,20 +300,27 @@ HashTable::iterator::operator++ template inline -const Key& HashTable::iterator::key() +const Key& Foam::HashTable::iterator::key() const { return elmtPtr_->key_; } template -inline typename HashTable::iterator -HashTable::begin() +inline typename Foam::HashTable::iterator +Foam::HashTable::begin() { label i = 0; - while (table_ && !table_[i] && ++i < tableSize_) - {} + if (nElmts_) + { + while (table_ && !table_[i] && ++i < tableSize_) + {} + } + else + { + i = tableSize_; + } if (i == tableSize_) { @@ -282,8 +341,8 @@ HashTable::begin() template -inline const typename HashTable::iterator& -HashTable::end() +inline const typename Foam::HashTable::iterator& +Foam::HashTable::end() { return HashTable::endIter_; } @@ -292,33 +351,33 @@ HashTable::end() // * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * // template -inline HashTable::const_iterator::const_iterator +inline Foam::HashTable::const_iterator::const_iterator ( - const HashTable& curHashTable, + const HashTable& hashTbl, const hashedEntry* elmt, label hashIndex ) : - curHashTable_(curHashTable), + hashTable_(hashTbl), elmtPtr_(elmt), hashIndex_(hashIndex) {} template -inline HashTable::const_iterator::const_iterator +inline Foam::HashTable::const_iterator::const_iterator ( const iterator& iter ) : - curHashTable_(iter.curHashTable_), + hashTable_(iter.hashTable_), elmtPtr_(iter.elmtPtr_), hashIndex_(iter.hashIndex_) {} template -inline void HashTable::const_iterator::operator= +inline void Foam::HashTable::const_iterator::operator= ( const const_iterator& iter ) @@ -329,7 +388,7 @@ inline void HashTable::const_iterator::operator= template -inline bool HashTable::const_iterator::operator== +inline bool Foam::HashTable::const_iterator::operator== ( const const_iterator& iter ) const @@ -339,7 +398,7 @@ inline bool HashTable::const_iterator::operator== template -inline bool HashTable::const_iterator::operator!= +inline bool Foam::HashTable::const_iterator::operator!= ( const const_iterator& iter ) const @@ -349,7 +408,7 @@ inline bool HashTable::const_iterator::operator!= template -inline bool HashTable::const_iterator::operator== +inline bool Foam::HashTable::const_iterator::operator== ( const iterator& iter ) const @@ -359,7 +418,7 @@ inline bool HashTable::const_iterator::operator== template -inline bool HashTable::const_iterator::operator!= +inline bool Foam::HashTable::const_iterator::operator!= ( const iterator& iter ) const @@ -369,35 +428,36 @@ inline bool HashTable::const_iterator::operator!= template -inline const T& HashTable::const_iterator::operator*() +inline const T& +Foam::HashTable::const_iterator::operator*() const { return elmtPtr_->obj_; } -#ifndef __CINT__ template -inline const T& HashTable::const_iterator::operator()() +inline const T& +Foam::HashTable::const_iterator::operator()() const { - return operator*(); + return elmtPtr_->obj_; } -#endif + template inline -typename HashTable::const_iterator& -HashTable::const_iterator::operator++() +typename Foam::HashTable::const_iterator& +Foam::HashTable::const_iterator::operator++() { if ( !(elmtPtr_ = elmtPtr_->next_) - && ++hashIndex_ < curHashTable_.tableSize_ - && !(elmtPtr_ = curHashTable_.table_[hashIndex_]) + && ++hashIndex_ < hashTable_.tableSize_ + && !(elmtPtr_ = hashTable_.table_[hashIndex_]) ) { while ( - ++hashIndex_ < curHashTable_.tableSize_ - && !(elmtPtr_ = curHashTable_.table_[hashIndex_]) + ++hashIndex_ < hashTable_.tableSize_ + && !(elmtPtr_ = hashTable_.table_[hashIndex_]) ) {} } @@ -407,8 +467,8 @@ HashTable::const_iterator::operator++() template -inline typename HashTable::const_iterator -HashTable::const_iterator::operator++ +inline typename Foam::HashTable::const_iterator +Foam::HashTable::const_iterator::operator++ ( int ) @@ -421,20 +481,27 @@ HashTable::const_iterator::operator++ template inline -const Key& HashTable::const_iterator::key() +const Key& Foam::HashTable::const_iterator::key() const { return elmtPtr_->key_; } template -inline typename HashTable::const_iterator -HashTable::begin() const +inline typename Foam::HashTable::const_iterator +Foam::HashTable::cbegin() const { label i = 0; - while (table_ && !table_[i] && ++i < tableSize_) - {} + if (nElmts_) + { + while (table_ && !table_[i] && ++i < tableSize_) + {} + } + else + { + i = tableSize_; + } if (i == tableSize_) { @@ -455,15 +522,27 @@ HashTable::begin() const template -inline const typename HashTable::const_iterator& -HashTable::end() const +inline const typename Foam::HashTable::const_iterator& +Foam::HashTable::cend() const { return HashTable::endConstIter_; } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +template +inline typename Foam::HashTable::const_iterator +Foam::HashTable::begin() const +{ + return this->cbegin(); +} + + +template +inline const typename Foam::HashTable::const_iterator& +Foam::HashTable::end() const +{ + return HashTable::endConstIter_; +} -} // End namespace Foam // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C index 127187153..863e5c9e5 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C @@ -33,38 +33,82 @@ License template Foam::HashTable::HashTable(Istream& is, const label size) : - tableSize_(size), - table_(new hashedEntry*[tableSize_]), + HashTableName(), nElmts_(0), + tableSize_(canonicalSize(size)), + table_(new hashedEntry*[tableSize_]), endIter_(*this, NULL, 0), endConstIter_(*this, NULL, 0) { - for (label i=0; i>(is, *this); } +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +template +Foam::Ostream& +Foam::HashTable::printInfo(Ostream& os) const +{ + label used = 0; + label maxChain = 0; + unsigned avgChain = 0; + + for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx) + { + label count = 0; + for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) + { + ++count; + } + + if (count) + { + ++used; + avgChain += count; + + if (maxChain < count) + { + maxChain = count; + } + } + } + + os << "HashTable" + << " elements:" << size() << " slots:" << used << "/" << tableSize_ + << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0) + << "/" << maxChain << endl; + + return os; +} + + // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // template -Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) +Foam::Istream& Foam::operator>> +( + Istream& is, + HashTable& L +) { is.fatalCheck("operator>>(Istream&, HashTable&)"); // Anull list L.clear(); - is.fatalCheck("operator>>(Istream& is, HashTable& L)"); + is.fatalCheck("operator>>(Istream&, HashTable&)"); token firstToken(is); is.fatalCheck ( - "operator>>(Istream& is, HashTable& L) : " + "operator>>(Istream&, HashTable&) : " "reading first token" ); @@ -73,7 +117,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) label s = firstToken.labelToken(); // Read beginning of contents - char listDelimiter = is.readBeginList("HashTable"); + char delimiter = is.readBeginList("HashTable"); if (s) { @@ -82,7 +126,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) L.resize(2*s); } - if (listDelimiter == token::BEGIN_LIST) + if (delimiter == token::BEGIN_LIST) { for (label i=0; i>(Istream& is, HashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, HashTable& L)", + "operator>>(Istream&, HashTable&)", is ) << "incorrect first token, '(', found " << firstToken.info() << exit(FatalIOError); @@ -117,7 +161,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, HashTable& L)", + "operator>>(Istream&, HashTable&)", is ) << "incorrect first token, '(', found " << firstToken.info() << exit(FatalIOError); @@ -133,10 +177,13 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) ) { is.putBack(lastToken); + Key key; is >> key; + T element; is >> element; + L.insert(key, element); is.fatalCheck @@ -152,7 +199,7 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, HashTable& L)", + "operator>>(Istream&, HashTable&)", is ) << "incorrect first token, expected or '(', found " << firstToken.info() @@ -166,26 +213,27 @@ Foam::Istream& Foam::operator>>(Istream& is, HashTable& L) template -Foam::Ostream& Foam::operator<<(Ostream& os, const HashTable& L) +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const HashTable& L +) { - // Write size of HashTable - os << nl << L.size(); + // Write size and start delimiter + os << nl << L.size() << nl << token::BEGIN_LIST << nl; - // Write beginning of contents - os << nl << token::BEGIN_LIST << nl; - - // Write HashTable contents + // Write contents for ( - typename HashTable::const_iterator iter = L.begin(); - iter != L.end(); + typename HashTable::const_iterator iter = L.cbegin(); + iter != L.cend(); ++iter ) { os << iter.key() << token::SPACE << iter() << nl; } - // Write end of contents + // Write end delimiter os << token::END_LIST; // Check state of IOstream diff --git a/src/OpenFOAM/containers/HashTables/Map/Map.H b/src/OpenFOAM/containers/HashTables/Map/Map.H index b573cd317..c1b500d28 100644 --- a/src/OpenFOAM/containers/HashTables/Map/Map.H +++ b/src/OpenFOAM/containers/HashTables/Map/Map.H @@ -55,10 +55,15 @@ class Map public: + typedef typename HashTable >::iterator iterator; + + typedef typename HashTable >::const_iterator + const_iterator; + // Constructors - //- Construct given initial map size - Map(label size = 100) + //- Construct given initial size + Map(const label size = 128) : HashTable >(size) {} @@ -74,6 +79,19 @@ public: : HashTable >(map) {} + + //- Construct by transferring the parameter contents + Map(const Xfer >& map) + : + HashTable >(map) + {} + + //- Construct by transferring the parameter contents + Map(const Xfer > >& map) + : + HashTable >(map) + {} + }; diff --git a/src/OpenFOAM/containers/HashTables/PtrMap/PtrMap.H b/src/OpenFOAM/containers/HashTables/PtrMap/PtrMap.H index 277199a65..78c3a93b2 100644 --- a/src/OpenFOAM/containers/HashTables/PtrMap/PtrMap.H +++ b/src/OpenFOAM/containers/HashTables/PtrMap/PtrMap.H @@ -58,7 +58,7 @@ public: // Constructors //- Construct given initial map size - PtrMap(label size = 100) + PtrMap(const label size = 128) : HashPtrTable >(size) {} diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C index 4a53d23b1..136fb6b25 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C @@ -31,20 +31,42 @@ License #include "List.H" #include "IOstreams.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // -namespace Foam +template +Foam::label Foam::StaticHashTable::canonicalSize(const label size) { + if (size < 1) + { + return 0; + } + + // enforce power of two + unsigned int goodSize = size; + + if (goodSize & (goodSize - 1)) + { + // brute-force is fast enough + goodSize = 1; + while (goodSize < unsigned(size)) + { + goodSize <<= 1; + } + } + + return goodSize; +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct given initial table size template -StaticHashTable::StaticHashTable(const label size) +Foam::StaticHashTable::StaticHashTable(const label size) : StaticHashTableName(), - keys_(size), - objects_(size), + keys_(canonicalSize(size)), + objects_(keys_.size()), nElmts_(0), endIter_(*this, keys_.size(), 0), endConstIter_(*this, keys_.size(), 0) @@ -62,7 +84,7 @@ StaticHashTable::StaticHashTable(const label size) // Construct as copy template -StaticHashTable::StaticHashTable +Foam::StaticHashTable::StaticHashTable ( const StaticHashTable& ht ) @@ -76,34 +98,54 @@ StaticHashTable::StaticHashTable {} + +template +Foam::StaticHashTable::StaticHashTable +( + const Xfer< StaticHashTable >& ht +) +: + StaticHashTableName(), + keys_(0), + objects_(0), + nElmts_(0), + endIter_(*this, 0, 0), + endConstIter_(*this, 0, 0) +{ + transfer(ht()); +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template -StaticHashTable::~StaticHashTable() +Foam::StaticHashTable::~StaticHashTable() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -bool StaticHashTable::found(const Key& key) const +bool Foam::StaticHashTable::found(const Key& key) const { - label ii = Hash()(key, keys_.size()); - - const List& localKeys = keys_[ii]; - - forAll(localKeys, n) + if (nElmts_) { - if (localKeys[n] == key) + const label hashIdx = hashKeyIndex(key); + const List& localKeys = keys_[hashIdx]; + + forAll(localKeys, elemIdx) { - return true; + if (key == localKeys[elemIdx]) + { + return true; + } } } # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::found(const Key& key) : " + Info<< "StaticHashTable::found(const Key&) : " << "Entry " << key << " not found in hash table\n"; } # endif @@ -113,28 +155,30 @@ bool StaticHashTable::found(const Key& key) const template -typename StaticHashTable::iterator -StaticHashTable::find +typename Foam::StaticHashTable::iterator +Foam::StaticHashTable::find ( const Key& key ) { - label ii = Hash()(key, keys_.size()); - - const List& localKeys = keys_[ii]; - - forAll(localKeys, n) + if (nElmts_) { - if (localKeys[n] == key) + const label hashIdx = hashKeyIndex(key); + const List& localKeys = keys_[hashIdx]; + + forAll(localKeys, elemIdx) { - return iterator(*this, ii, n); + if (key == localKeys[elemIdx]) + { + return iterator(*this, hashIdx, elemIdx); + } } } # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::find(const Key& key) : " + Info<< "StaticHashTable::find(const Key&) : " << "Entry " << key << " not found in hash table\n"; } # endif @@ -144,45 +188,46 @@ StaticHashTable::find template -typename StaticHashTable::const_iterator -StaticHashTable::find +typename Foam::StaticHashTable::const_iterator +Foam::StaticHashTable::find ( const Key& key ) const { - label ii = Hash()(key, keys_.size()); - - const List& localKeys = keys_[ii]; - - forAll(localKeys, n) + if (nElmts_) { - if (localKeys[n] == key) + const label hashIdx = hashKeyIndex(key); + const List& localKeys = keys_[hashIdx]; + + forAll(localKeys, elemIdx) { - return const_iterator(*this, ii, n); + if (key == localKeys[elemIdx]) + { + return const_iterator(*this, hashIdx, elemIdx); + } } } # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::find(const Key& key) const : " + Info<< "StaticHashTable::find(const Key&) const : " << "Entry " << key << " not found in hash table\n"; } # endif - return end(); + return cend(); } // Return the table of contents template -List StaticHashTable::toc() const +Foam::List Foam::StaticHashTable::toc() const { List tofc(nElmts_); - label i = 0; - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { tofc[i++] = iter.key(); } @@ -192,57 +237,74 @@ List StaticHashTable::toc() const template -bool StaticHashTable::insert(const Key& key, const T& newEntry) +bool Foam::StaticHashTable::set +( + const Key& key, + const T& newEntry, + const bool protect +) { - label ii = Hash()(key, keys_.size()); + const label hashIdx = hashKeyIndex(key); + List& localKeys = keys_[hashIdx]; - List& localKeys = keys_[ii]; - - forAll(localKeys, n) + label existing = localKeys.size(); + forAll(localKeys, elemIdx) { - if (localKeys[n] == key) + if (key == localKeys[elemIdx]) { -# ifdef FULLDEBUG - if (debug) - { - Pout<< "StaticHashTable::insert" - "(const Key& key, T newEntry) : " - "Cannot insert " << key << " already in hash table\n"; - } -# endif - - return false; + existing = elemIdx; + break; } } + if (existing == localKeys.size()) + { + // not found, append + List& localObjects = objects_[hashIdx]; - // Append. - List& localObjects = objects_[ii]; + localKeys.setSize(existing+1); + localObjects.setSize(existing+1); - label sz = localKeys.size(); + localKeys[existing] = key; + localObjects[existing] = newEntry; - localKeys.setSize(sz+1); - localObjects.setSize(sz+1); - - localKeys[sz] = key; - localObjects[sz] = newEntry; - - nElmts_++; + nElmts_++; + } + else if (protect) + { + // found - but protected from overwriting + // this corresponds to the STL 'insert' convention +# ifdef FULLDEBUG + if (debug) + { + Info<< "StaticHashTable::set" + "(const Key& key, T newEntry, true) : " + "Cannot insert " << key << " already in hash table\n"; + } +# endif + return false; + } + else + { + // found - overwrite existing entry + // this corresponds to the Perl convention + objects_[hashIdx][existing] = newEntry; + } return true; } template -bool StaticHashTable::erase(const iterator& it) +bool Foam::StaticHashTable::erase(const iterator& cit) { - if (it != end()) + if (cit != end()) { - List& localKeys = keys_[it.hashIndex_]; - List& localObjects = objects_[it.hashIndex_]; + List& localKeys = keys_[cit.hashIndex_]; + List& localObjects = objects_[cit.hashIndex_]; // Copy down - for (label i = it.elementIndex_+1; i < localKeys.size(); i++) + for (label i = cit.elemIndex_+1; i < localKeys.size(); i++) { localKeys[i-1] = localKeys[i]; localObjects[i-1] = localObjects[i]; @@ -250,12 +312,39 @@ bool StaticHashTable::erase(const iterator& it) localKeys.setSize(localKeys.size()-1); localObjects.setSize(localObjects.size()-1); + // adjust iterator after erase + iterator& it = const_cast(cit); + + it.elemIndex_--; + if (it.elemIndex_ < 0) + { + // No previous element in the local list + + // Search back for previous non-zero table entry + while (--it.hashIndex_ >= 0 && !objects_[it.hashIndex_].size()) + {} + + if (it.hashIndex_ >= 0) + { + // The last element in the local list + it.elemIndex_ = objects_[it.hashIndex_].size() - 1; + } + else + { + // No previous found. Mark with special value which is + // - not end() + // - handled by operator++ + it.hashIndex_ = -1; + it.elemIndex_ = 0; + } + } + nElmts_--; # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::erase(iterator&) : " + Info<< "StaticHashTable::erase(iterator&) : " << "hashedEntry removed.\n"; } # endif @@ -267,7 +356,7 @@ bool StaticHashTable::erase(const iterator& it) # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::erase(iterator&) : " + Info<< "StaticHashTable::erase(iterator&) : " << "cannot remove hashedEntry from hash table\n"; } # endif @@ -278,7 +367,7 @@ bool StaticHashTable::erase(const iterator& it) template -bool StaticHashTable::erase(const Key& key) +bool Foam::StaticHashTable::erase(const Key& key) { iterator it = find(key); @@ -294,14 +383,38 @@ bool StaticHashTable::erase(const Key& key) template -void StaticHashTable::resize(const label newSize) +Foam::label Foam::StaticHashTable::erase +( + const StaticHashTable& rhs +) { + label count = 0; + + // Remove rhs elements from this table + // NOTE: could optimize depending on which hash is smaller + for (iterator iter = this->begin(); iter != this->end(); ++iter) + { + if (rhs.found(iter.key()) && erase(iter)) + { + count++; + } + } + + return count; +} + + +template +void Foam::StaticHashTable::resize(const label sz) +{ + label newSize = canonicalSize(sz); + if (newSize == keys_.size()) { # ifdef FULLDEBUG if (debug) { - Pout<< "StaticHashTable::resize(const label) : " + Info<< "StaticHashTable::resize(const label) : " << "new table size == old table size\n"; } # endif @@ -313,7 +426,7 @@ void StaticHashTable::resize(const label newSize) { FatalErrorIn ( - "StaticHashTable::StaticHashTable(const label size)" + "StaticHashTable::resize(const label)" ) << "Illegal size " << newSize << " for StaticHashTable." << " Minimum size is 1" << abort(FatalError); } @@ -321,7 +434,7 @@ void StaticHashTable::resize(const label newSize) StaticHashTable newTable(newSize); - for (iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { newTable.insert(iter.key(), *iter); } @@ -335,46 +448,62 @@ void StaticHashTable::resize(const label newSize) template -void StaticHashTable::clear() +void Foam::StaticHashTable::clear() { - forAll(keys_, ii) + forAll(keys_, hashIdx) { - keys_[ii].clear(); - objects_[ii].clear(); + keys_[hashIdx].clear(); + objects_[hashIdx].clear(); } + + nElmts_ = 0; } template -void StaticHashTable::transfer(StaticHashTable& ht) +void Foam::StaticHashTable::clearStorage() { - // Remove my existing elements + clear(); + resize(1); +} + + + +template +void Foam::StaticHashTable::transfer +( + StaticHashTable& ht +) +{ + // Remove existing elements clear(); // Copy data from ht keys_.transfer(ht.keys_); objects_.transfer(ht.objects_); + nElmts_ = ht.nElmts_; + ht.nElmts_ = 0; // Adapt end() iterators endIter_.hashIndex_ = keys_.size(); endConstIter_.hashIndex_ = keys_.size(); - // Clear ht - ht.nElmts_ = 0; + ht.endIter_.hashIndex_ = 0; + ht.endConstIter_.hashIndex_ = 0; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template -void StaticHashTable::operator= +void Foam::StaticHashTable::operator= ( - const StaticHashTable& ht + const StaticHashTable& rhs ) { // Check for assignment to self - if (this == &ht) + if (this == &rhs) { FatalErrorIn ( @@ -384,20 +513,70 @@ void StaticHashTable::operator= << abort(FatalError); } - clear(); - for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter) + // keys could be empty from a previous transfer() + if (keys_.empty()) + { + keys_.setSize(rhs.keys_.size()); + objects_.setSize(keys_.size()); + + // Adapt end() iterators + endIter_.hashIndex_ = keys_.size(); + endConstIter_.hashIndex_ = keys_.size(); + } + else + { + clear(); + // keys_.size() does not change so neither does end() iterator. + } + + + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { insert(iter.key(), *iter); } +} - // keys_.size() does not change so neither does end() iterator. +template +bool Foam::StaticHashTable::operator== +( + const StaticHashTable& rhs +) const +{ + // Are all my elements in rhs? + for (const_iterator iter = cbegin(); iter != cend(); ++iter) + { + const_iterator fnd = rhs.find(iter.key()); + + if (fnd == rhs.cend() || fnd() != iter()) + { + return false; + } + } + + // Are all rhs elements in me? + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) + { + const_iterator fnd = find(iter.key()); + + if (fnd == cend() || fnd() != iter()) + { + return false; + } + } + return true; } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +template +bool Foam::StaticHashTable::operator!= +( + const StaticHashTable& rhs +) const +{ + return !(operator==(rhs)); +} -} // End namespace Foam // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H index 86fc91a06..0c5d0433a 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H @@ -28,10 +28,10 @@ Class Description STL conforming hash table. +Note Uses straight lists as underlying type. Is slower to insert than the standard HashTable, but should be more memory efficient and faster to access. - Explicitly does not have default size. SourceFiles StaticHashTableI.H @@ -44,7 +44,9 @@ SourceFiles #define StaticHashTable_H #include "label.H" +#include "uLabel.H" #include "word.H" +#include "Xfer.H" #include "className.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -54,9 +56,7 @@ namespace Foam // Forward declaration of friend functions and operators -template -class List; - +template class List; template class StaticHashTable; template Istream& operator>> @@ -73,14 +73,14 @@ template Ostream& operator<< /*---------------------------------------------------------------------------*\ - Class StaticHashTableName Declaration + Class StaticHashTableName Declaration \*---------------------------------------------------------------------------*/ TemplateName(StaticHashTable); /*---------------------------------------------------------------------------*\ - Class StaticHashTable Declaration + Class StaticHashTable Declaration \*---------------------------------------------------------------------------*/ template @@ -99,6 +99,16 @@ class StaticHashTable //- The current number of elements in table label nElmts_; + //- Return a canonical (power-of-two) size + static label canonicalSize(const label); + + //- Return the hash index of the Key within the current table size. + // No checks for zero-sized tables. + inline label hashKeyIndex(const Key&) const; + + //- Assign a new hashed entry to a possibly already existing key + bool set(const Key&, const T& newElmt, bool protect); + public: @@ -138,14 +148,16 @@ public: // Constructors //- Construct given initial table size - StaticHashTable(const label size = 100); + StaticHashTable(const label size = 128); //- Construct from Istream - StaticHashTable(Istream&, const label size = 100); + StaticHashTable(Istream&, const label size = 128); //- Construct as copy StaticHashTable(const StaticHashTable&); + //- Construct by transferring the parameter contents + StaticHashTable(const Xfer< StaticHashTable >&); // Destructor @@ -159,54 +171,83 @@ public: //- Return number of elements in table. inline label size() const; - //- Return true if hashedEntry is found in table + //- Return true if the hash table is empty + inline bool empty() const; + + //- Return true if hashed entry is found in table bool found(const Key& key) const; - //- Find and return an iterator set at the hashedEntry + //- Find and return an iterator set at the hashed entry // If not found iterator = end() iterator find(const Key& key); - //- Find and return an const_iterator set at the hashedEntry + //- Find and return an const_iterator set at the hashed entry // If not found iterator = end() const_iterator find(const Key& key) const; //- Return the table of contents List toc() const; + //- Print information + Ostream& printInfo(Ostream&) const; + // Edit - //- Insert a new hashedEntry + //- Insert a new hashed entry bool insert(const Key& key, const T& newElmt); - //- Erase an hashedEntry specified by given iterator + //- Assign a new hashed entry, overwriting existing entries + inline bool set(const Key&, const T& newElmt); + + //- Erase an hashed entry specified by given iterator bool erase(const iterator& it); - //- Erase an hashedEntry specified by given key if in table + //- Erase an hashed entry specified by given key if in table bool erase(const Key& key); //- Resize the hash table for efficiency void resize(const label newSize); + //- Remove entries in the given hash table from this hash table + // Return the number of elements removed + label erase(const StaticHashTable&); + //- Clear all entries from table void clear(); + //- Clear the table entries and the table itself. + // Equivalent to clear() followed by resize(1) + void clearStorage(); + //- Transfer the contents of the argument table into this table // and annull the argument table. void transfer(StaticHashTable&); + //- Transfer contents to the Xfer container + inline Xfer< StaticHashTable > xfer(); + // Member Operators - //- Find and return an hashedEntry - inline T& operator[](const Key& key); + //- Find and return an hashed entry + inline T& operator[](const Key&); - //- Find and return an hashedEntry - inline const T& operator[](const Key& key) const; + //- Find and return an hashed entry + inline const T& operator[](const Key&) const; + + //- Find and return an hashed entry, create it null if not present. + inline T& operator()(const Key&); //- Assignment void operator=(const StaticHashTable&); + //- Equality. Two hash tables are equal if all contents of first are + // also in second and vice versa. + bool operator==(const StaticHashTable&) const; + + //- The opposite of the equality operation. + bool operator!=(const StaticHashTable&) const; // STL type definitions @@ -242,24 +283,24 @@ public: // Private data //- Reference to the StaticHashTable this is an iterator for - TableRef curStaticHashTable_; + TableRef hashTable_; //- Current hash index label hashIndex_; //- Index of current element at hashIndex - label elementIndex_; + label elemIndex_; public: // Constructors - //- Construct from hash table, element and hash index + //- Construct from hash table, hash index and element index inline Iterator ( - TableRef curStaticHashTable, + TableRef, label hashIndex_, - label elementIndex_ + label elemIndex_ ); //- Construct from the non-const iterator @@ -268,13 +309,13 @@ public: // Member operators - inline void operator=(const iterator& iter); + inline void operator=(const iterator&); - inline bool operator==(const iterator& iter) const; - inline bool operator==(const const_iterator& iter) const; + inline bool operator==(const iterator&) const; + inline bool operator==(const const_iterator&) const; - inline bool operator!=(const iterator& iter) const; - inline bool operator!=(const const_iterator& iter) const; + inline bool operator!=(const iterator&) const; + inline bool operator!=(const const_iterator&) const; inline TRef operator*(); inline TRef operator()(); @@ -282,23 +323,28 @@ public: inline Iterator& operator++(); inline Iterator operator++(int); - inline const Key& key(); + inline const Key& key() const; }; - //- iterator set to the begining of the StaticHashTable + //- iterator set to the beginning of the StaticHashTable inline iterator begin(); //- iterator set to beyond the end of the StaticHashTable inline const iterator& end(); - //- const_iterator set to the begining of the StaticHashTable + //- const_iterator set to the beginning of the StaticHashTable + inline const_iterator cbegin() const; + + //- const_iterator set to beyond the end of the StaticHashTable + inline const const_iterator& cend() const; + + //- const_iterator set to the beginning of the StaticHashTable inline const_iterator begin() const; //- const_iterator set to beyond the end of the StaticHashTable inline const const_iterator& end() const; - // IOstream Operator friend Istream& operator>> diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H index 08e2a177c..f3eee6e02 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H @@ -27,34 +27,76 @@ License #include "error.H" #include "IOstreams.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * // +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +template +inline Foam::label +Foam::StaticHashTable::hashKeyIndex(const Key& key) const +{ + // size is power of two - this is the modulus + return Hash()(key) & (keys_.size() - 1); +} + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -inline label StaticHashTable::size() const +inline Foam::label Foam::StaticHashTable::size() const { return nElmts_; } +template +inline bool Foam::StaticHashTable::empty() const +{ + return !nElmts_; +} + + +template +inline bool Foam::StaticHashTable::insert +( + const Key& key, + const T& newEntry +) +{ + return set(key, newEntry, true); +} + + +template +inline bool Foam::StaticHashTable::set +( + const Key& key, + const T& newEntry +) +{ + return set(key, newEntry, false); +} + + +template +inline Foam::Xfer< Foam::StaticHashTable > +Foam::StaticHashTable::xfer() +{ + return xferMove(*this); +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template -inline T& StaticHashTable::operator[](const Key& key) +inline T& Foam::StaticHashTable::operator[](const Key& key) { iterator iter = find(key); if (iter == end()) { FatalErrorIn("StaticHashTable::operator[](const Key&)") - << key << " not found in table. Valid entries are " + << key << " not found in table. Valid entries: " << toc() << exit(FatalError); } @@ -62,17 +104,21 @@ inline T& StaticHashTable::operator[](const Key& key) return *iter; } + template -inline const T& StaticHashTable::operator[](const Key& key) const +inline const T& Foam::StaticHashTable::operator[] +( + const Key& key +) const { const_iterator iter = find(key); - if (iter == end()) + if (iter == cend()) { FatalErrorIn ( "StaticHashTable::operator[](const Key&) const" - ) << key << " not found in table. Valid entries are " + ) << key << " not found in table. Valid entries: " << toc() << exit(FatalError); } @@ -81,74 +127,97 @@ inline const T& StaticHashTable::operator[](const Key& key) const } +template +inline T& Foam::StaticHashTable::operator()(const Key& key) +{ + iterator iter = find(key); + + if (iter == end()) + { + insert(key, T()); + return *find(key); + } + else + { + return *iter; + } +} + + // * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // template template -inline StaticHashTable::Iterator:: -Iterator +inline Foam::StaticHashTable::Iterator::Iterator ( - TableRef curStaticHashTable, + TableRef hashTbl, label hashIndex, - label elementIndex + label elemIndex ) : - curStaticHashTable_(curStaticHashTable), + hashTable_(hashTbl), hashIndex_(hashIndex), - elementIndex_(elementIndex) + elemIndex_(elemIndex) {} template template -inline StaticHashTable::Iterator:: -Iterator(const iterator& iter) +inline Foam::StaticHashTable::Iterator::Iterator +( + const iterator& iter +) : - curStaticHashTable_(iter.curStaticHashTable_), + hashTable_(iter.hashTable_), hashIndex_(iter.hashIndex_), - elementIndex_(iter.elementIndex_) + elemIndex_(iter.elemIndex_) {} template template -inline void StaticHashTable::Iterator:: -operator=(const iterator& iter) +inline void +Foam::StaticHashTable::Iterator::operator= +( + const iterator& iter +) { this->hashIndex_ = iter.hashIndex_; - this->elementIndex_ = iter.elementIndex_; + this->elemIndex_ = iter.elemIndex_; } template template -inline bool StaticHashTable::Iterator:: -operator==(const iterator& iter) const +inline bool +Foam::StaticHashTable::Iterator::operator== +( + const iterator& iter +) const { - return hashIndex_ == iter.hashIndex_ && elementIndex_ == iter.elementIndex_; + return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_; } + template template -inline bool StaticHashTable::Iterator:: -operator==(const const_iterator& iter) const +inline bool +Foam::StaticHashTable::Iterator::operator== +( + const const_iterator& iter +) const { - return hashIndex_ == iter.hashIndex_ && elementIndex_ == iter.elementIndex_; + return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_; } template template -inline bool StaticHashTable::Iterator:: -operator!=(const iterator& iter) const -{ - return !operator==(iter); -} - -template -template -inline bool StaticHashTable::Iterator:: -operator!=(const const_iterator& iter) const +inline bool +Foam::StaticHashTable::Iterator::operator!= +( + const iterator& iter +) const { return !operator==(iter); } @@ -156,17 +225,29 @@ operator!=(const const_iterator& iter) const template template -inline TRef StaticHashTable::Iterator:: -operator*() +inline bool +Foam::StaticHashTable::Iterator::operator!= +( + const const_iterator& iter +) const { - return curStaticHashTable_.objects_[hashIndex_][elementIndex_]; + return !operator==(iter); } template template -inline TRef StaticHashTable::Iterator:: -operator()() +inline TRef +Foam::StaticHashTable::Iterator::operator*() +{ + return hashTable_.objects_[hashIndex_][elemIndex_]; +} + + +template +template +inline TRef +Foam::StaticHashTable::Iterator::operator()() { return operator*(); } @@ -175,40 +256,44 @@ operator()() template template inline -typename StaticHashTable::template Iterator +typename Foam::StaticHashTable::template Iterator < TRef, TableRef >& -StaticHashTable::Iterator +Foam::StaticHashTable::Iterator < TRef, TableRef >::operator++() { - const List& localObjects = curStaticHashTable_.objects_[hashIndex_]; - - if (elementIndex_ == localObjects.size()-1) + // Check for special value from erase. (sets hashIndex to -1) + if (hashIndex_ >= 0) { - elementIndex_ = 0; + // Try the next element on the local list + elemIndex_++; - // Find first non-zero entry - for - ( - hashIndex_++; - hashIndex_ < curStaticHashTable_.objects_.size(); - hashIndex_++ - ) + if (elemIndex_ < hashTable_.objects_[hashIndex_].size()) { - if (curStaticHashTable_.objects_[hashIndex_].size() > 0) - { - break; - } + return *this; } } - else + + // Step to the next table entry + elemIndex_ = 0; + + while + ( + ++hashIndex_ < hashTable_.objects_.size() + && !hashTable_.objects_[hashIndex_].size() + ) + {} + + + if (hashIndex_ >= hashTable_.objects_.size()) { - elementIndex_++; + // make end iterator + hashIndex_ = hashTable_.keys_.size(); } return *this; @@ -218,12 +303,12 @@ StaticHashTable::Iterator template template inline -typename StaticHashTable::template Iterator +typename Foam::StaticHashTable::template Iterator < TRef, TableRef > -StaticHashTable::Iterator +Foam::StaticHashTable::Iterator < TRef, TableRef @@ -240,24 +325,23 @@ StaticHashTable::Iterator template template -inline -const Key& StaticHashTable::Iterator:: -key() +inline const Key& +Foam::StaticHashTable::Iterator::key() const { - return curStaticHashTable_.keys_[hashIndex_][elementIndex_]; + return hashTable_.keys_[hashIndex_][elemIndex_]; } template -inline typename StaticHashTable::iterator -StaticHashTable::begin() +inline typename Foam::StaticHashTable::iterator +Foam::StaticHashTable::begin() { // Find first non-empty entry - forAll(keys_, i) + forAll(keys_, hashIdx) { - if (keys_[i].size() > 0) + if (keys_[hashIdx].size()) { - return iterator(*this, i, 0); + return iterator(*this, hashIdx, 0); } } @@ -273,23 +357,23 @@ StaticHashTable::begin() template -inline const typename StaticHashTable::iterator& -StaticHashTable::end() +inline const typename Foam::StaticHashTable::iterator& +Foam::StaticHashTable::end() { return StaticHashTable::endIter_; } template -inline typename StaticHashTable::const_iterator -StaticHashTable::begin() const +inline typename Foam::StaticHashTable::const_iterator +Foam::StaticHashTable::cbegin() const { // Find first non-empty entry - forAll(keys_, i) + forAll(keys_, hashIdx) { - if (keys_[i].size() > 0) + if (keys_[hashIdx].size()) { - return const_iterator(*this, i, 0); + return const_iterator(*this, hashIdx, 0); } } @@ -305,8 +389,24 @@ StaticHashTable::begin() const template -inline const typename StaticHashTable::const_iterator& -StaticHashTable::end() const +inline const typename Foam::StaticHashTable::const_iterator& +Foam::StaticHashTable::cend() const +{ + return StaticHashTable::endConstIter_; +} + + +template +inline typename Foam::StaticHashTable::const_iterator +Foam::StaticHashTable::begin() const +{ + return this->cbegin(); +} + + +template +inline const typename Foam::StaticHashTable::const_iterator& +Foam::StaticHashTable::end() const { return StaticHashTable::endConstIter_; } @@ -314,6 +414,4 @@ StaticHashTable::end() const // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -} // End namespace Foam - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C index 73a9ff701..96c988146 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C @@ -28,16 +28,14 @@ License #include "Istream.H" #include "Ostream.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -// Construct from Istream template -StaticHashTable::StaticHashTable(Istream& is, const label size) +Foam::StaticHashTable::StaticHashTable +( + Istream& is, + const label size +) : StaticHashTableName(), keys_(size), @@ -59,23 +57,58 @@ StaticHashTable::StaticHashTable(Istream& is, const label size) } +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +template +Foam::Ostream& +Foam::StaticHashTable::printInfo(Ostream& os) const +{ + label used = 0; + label maxChain = 0; + unsigned avgChain = 0; + + // Find first non-empty entry + forAll(keys_, hashIdx) + { + const label count = keys_[hashIdx].size(); + if (count) + { + ++used; + avgChain += count; + + if (maxChain < count) + { + maxChain = count; + } + } + } + + os << "StaticHashTable" + << " elements:" << size() << " slots:" << used << "/" << keys_.size() + << " chaining(avg/max):" << (used ? float(avgChain/used) : 0) + << "/" << maxChain << endl; + + return os; +} + + // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // template -Istream& operator>>(Istream& is, StaticHashTable& L) +Foam::Istream& Foam::operator>>(Istream& is, StaticHashTable& L) { is.fatalCheck("operator>>(Istream&, StaticHashTable&)"); // Anull list L.clear(); - is.fatalCheck("operator>>(Istream& is, StaticHashTable& L)"); + is.fatalCheck("operator>>(Istream&, StaticHashTable&)"); token firstToken(is); is.fatalCheck ( - "operator>>(Istream& is, StaticHashTable& L) : " + "operator>>(Istream&, StaticHashTable&) : " "reading first token" ); @@ -84,7 +117,7 @@ Istream& operator>>(Istream& is, StaticHashTable& L) label s = firstToken.labelToken(); // Read beginning of contents - char listDelimiter = is.readBeginList("StaticHashTable"); + char delimiter = is.readBeginList("StaticHashTable"); if (s) { @@ -93,7 +126,7 @@ Istream& operator>>(Istream& is, StaticHashTable& L) L.resize(2*s); } - if (listDelimiter == token::BEGIN_LIST) + if (delimiter == token::BEGIN_LIST) { for (label i=0; i>(Istream& is, StaticHashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, StaticHashTable& L)", + "operator>>(Istream&, StaticHashTable&)", is ) << "incorrect first token, '(', found " << firstToken.info() << exit(FatalIOError); @@ -128,7 +161,7 @@ Istream& operator>>(Istream& is, StaticHashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, StaticHashTable& L)", + "operator>>(Istream&, StaticHashTable&)", is ) << "incorrect first token, '(', found " << firstToken.info() << exit(FatalIOError); @@ -144,10 +177,13 @@ Istream& operator>>(Istream& is, StaticHashTable& L) ) { is.putBack(lastToken); + Key key; is >> key; + T element; is >> element; + L.insert(key, element); is.fatalCheck @@ -163,7 +199,7 @@ Istream& operator>>(Istream& is, StaticHashTable& L) { FatalIOErrorIn ( - "operator>>(Istream& is, StaticHashTable& L)", + "operator>>(Istream&, StaticHashTable&)", is ) << "incorrect first token, expected or '(', found " << firstToken.info() @@ -177,15 +213,15 @@ Istream& operator>>(Istream& is, StaticHashTable& L) template -Ostream& operator<<(Ostream& os, const StaticHashTable& L) +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const StaticHashTable& L) { - // Write size of StaticHashTable - os << nl << L.size(); + // Write size and start delimiter + os << nl << L.size() << nl << token::BEGIN_LIST << nl; - // Write beginning of contents - os << nl << token::BEGIN_LIST << nl; - - // Write StaticHashTable contents + // Write contents for ( typename StaticHashTable::const_iterator iter = L.begin(); @@ -196,7 +232,7 @@ Ostream& operator<<(Ostream& os, const StaticHashTable& L) os << iter.key() << token::SPACE << iter() << nl; } - // Write end of contents + // Write end delimiter os << token::END_LIST; // Check state of IOstream @@ -206,8 +242,4 @@ Ostream& operator<<(Ostream& os, const StaticHashTable& L) } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Identifiers/Keyed/Keyed.H b/src/OpenFOAM/containers/Identifiers/Keyed/Keyed.H new file mode 100644 index 000000000..1e6639423 --- /dev/null +++ b/src/OpenFOAM/containers/Identifiers/Keyed/Keyed.H @@ -0,0 +1,132 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright held by original author + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::Keyed + +Description + A container with an integer key attached to any item. + + The key can useful for sorting. + +SourceFiles + KeyedI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef Keyed_H +#define Keyed_H + +#include "List.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of friend functions and operators + +template class Keyed; + +template Istream& operator>>(Istream&, Keyed&); +template Ostream& operator<<(Ostream&, const Keyed&); + +/*---------------------------------------------------------------------------*\ + Class Keyed Declaration +\*---------------------------------------------------------------------------*/ + +template +class Keyed +: + public T +{ + // Private data + + label key_; + +public: + + // Static Members + + //- Add labels to a list of values + inline static List > createList + ( + const List&, + const label key=0 + ); + + //- Add labels to a list of values + inline static List > createList + ( + const List&, + const List