From dbb24d9cc99d9ef3183dfabf6d8055de53e578c9 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 2 Oct 2004 05:07:16 +0000 Subject: [PATCH] phash_map, etc. --- dtool/Config.pp | 9 + dtool/LocalSetup.pp | 3 + dtool/src/dconfig/configTable.h | 4 +- dtool/src/dtoolbase/Sources.pp | 6 + .../linmath => dtool/src/dtoolbase}/cmath.I | 42 ++-- .../linmath => dtool/src/dtoolbase}/cmath.h | 44 ++-- .../src/dtoolbase}/nearly_zero.h | 10 +- dtool/src/dtoolbase/pmap.h | 51 +++- dtool/src/dtoolbase/pset.h | 51 +++- dtool/src/dtoolbase/stl_compares.I | 194 +++++++++++++++ dtool/src/dtoolbase/stl_compares.h | 221 ++++++++++++++++++ dtool/src/parser-inc/Sources.pp | 2 +- dtool/src/parser-inc/hash_map | 57 +++++ dtool/src/parser-inc/hash_set | 55 +++++ dtool/src/parser-inc/stdcompare.h | 5 + panda/src/audiotraits/fmodAudioManager.h | 6 +- panda/src/downloader/httpChannel.h | 2 +- panda/src/downloader/httpClient.h | 3 +- panda/src/downloadertools/multify.cxx | 6 +- panda/src/event/eventHandler.h | 6 +- panda/src/express/pointerToBase.I | 11 + panda/src/express/pointerToBase.h | 1 + panda/src/express/typeHandle.I | 10 + panda/src/express/typeHandle.h | 1 + panda/src/express/typeRegistry.h | 2 +- panda/src/express/unicodeLatinMap.h | 2 +- panda/src/express/virtualFileSystem.h | 1 - panda/src/gobj/geom.h | 2 + panda/src/gobj/materialPool.h | 3 +- panda/src/gobj/preparedGraphicsObjects.h | 8 +- panda/src/gobj/texCoordName.h | 2 +- panda/src/gobj/texture.h | 2 +- panda/src/gobj/texturePool.h | 2 +- panda/src/lerp/lerpfunctor.h | 2 +- panda/src/linmath/Sources.pp | 8 +- panda/src/linmath/lmatrix3_src.I | 54 +++++ panda/src/linmath/lmatrix3_src.h | 4 + panda/src/linmath/lmatrix4_src.I | 62 +++++ panda/src/linmath/lmatrix4_src.h | 4 + panda/src/linmath/luse.h | 1 + panda/src/linmath/lvecBase2_src.I | 43 ++++ panda/src/linmath/lvecBase2_src.h | 5 +- panda/src/linmath/lvecBase3_src.I | 44 ++++ panda/src/linmath/lvecBase3_src.h | 4 + panda/src/linmath/lvecBase4_src.I | 45 ++++ panda/src/linmath/lvecBase4_src.h | 4 + panda/src/net/connectionManager.h | 6 +- panda/src/pgraph/cullResult.h | 2 +- panda/src/pgraph/nodePath.h | 4 +- panda/src/pgraph/pandaNode.h | 4 +- panda/src/pgraph/renderAttrib.h | 3 +- panda/src/pgraph/renderEffect.h | 3 +- panda/src/pgraph/renderEffects.h | 3 +- panda/src/pgraph/renderState.h | 5 +- panda/src/pgraph/transformState.cxx | 49 ++++ panda/src/pgraph/transformState.h | 6 +- panda/src/pstatclient/pStatClient.h | 1 + panda/src/putil/bamReader.h | 16 +- panda/src/putil/bamWriter.h | 6 +- panda/src/putil/buttonRegistry.h | 3 +- panda/src/putil/globalPointerRegistry.h | 2 +- panda/src/putil/nameUniquifier.h | 2 +- panda/src/testbed/Sources.pp | 5 + panda/src/testbed/test_map.cxx | 171 ++++++++++++++ 64 files changed, 1281 insertions(+), 114 deletions(-) rename {panda/src/linmath => dtool/src/dtoolbase}/cmath.I (80%) rename {panda/src/linmath => dtool/src/dtoolbase}/cmath.h (52%) rename {panda/src/linmath => dtool/src/dtoolbase}/nearly_zero.h (89%) create mode 100644 dtool/src/dtoolbase/stl_compares.I create mode 100644 dtool/src/dtoolbase/stl_compares.h create mode 100644 dtool/src/parser-inc/hash_map create mode 100644 dtool/src/parser-inc/hash_set create mode 100644 panda/src/testbed/test_map.cxx diff --git a/dtool/Config.pp b/dtool/Config.pp index 50efbcd866..001795b508 100644 --- a/dtool/Config.pp +++ b/dtool/Config.pp @@ -244,6 +244,15 @@ #define STL_CFLAGS #define STL_LIBS +// Does your STL library provide hashed associative containers like +// hash_map and hash_set? Define this true if you have a nonstandard +// STL library that provides these, like Visual Studio .NET's. (These +// hashtable containers are not part of the C++ standard yet, but the +// Dinkum STL library that VC7 ships with includes a preliminary +// implementation that Panda can optionally use.) For now, we assume +// you have this by default only on a Windows platform. +#define HAVE_STL_HASH $[WINDOWS_PLATFORM] + // Is OpenSSL installed, and where? #define SSL_IPATH /usr/local/ssl/include #define SSL_LPATH /usr/local/ssl/lib diff --git a/dtool/LocalSetup.pp b/dtool/LocalSetup.pp index 4fe2689012..9782692dbc 100644 --- a/dtool/LocalSetup.pp +++ b/dtool/LocalSetup.pp @@ -271,6 +271,9 @@ $[cdefine SIMPLE_STRUCT_POINTERS] /* Define if we have Dinkumware STL installed. */ $[cdefine HAVE_DINKUM] +/* Define if we have STL hash_map etc. available */ +$[cdefine HAVE_STL_HASH] + /* Define if we have a gettimeofday() function. */ $[cdefine HAVE_GETTIMEOFDAY] diff --git a/dtool/src/dconfig/configTable.h b/dtool/src/dconfig/configTable.h index e64b8cf488..99ad3e027c 100644 --- a/dtool/src/dconfig/configTable.h +++ b/dtool/src/dconfig/configTable.h @@ -40,8 +40,8 @@ public: typedef vector_SymbolEnt Symbol; private: - typedef pmap SymbolTable; - typedef pmap TableMap; + typedef phash_map > SymbolTable; + typedef phash_map > TableMap; typedef pvector Globs; SymbolTable unqualified; diff --git a/dtool/src/dtoolbase/Sources.pp b/dtool/src/dtoolbase/Sources.pp index 31ba6b437a..34b3ffeaee 100644 --- a/dtool/src/dtoolbase/Sources.pp +++ b/dtool/src/dtoolbase/Sources.pp @@ -2,15 +2,21 @@ #define TARGET dtoolbase #define SOURCES \ + cmath.I cmath.h \ dallocator.T dallocator.h \ dtoolbase.cxx dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \ fakestringstream.h \ + nearly_zero.h \ + stl_compares.I stl_compares.h \ pallocator.T pallocator.h \ pdeque.h plist.h pmap.h pset.h pvector.h #define INSTALL_HEADERS \ + cmath.I cmath.h \ dallocator.T dallocator.h \ dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \ + nearly_zero.h \ + stl_compares.I stl_compares.h \ pallocator.T pallocator.h \ pdeque.h plist.h pmap.h pset.h pvector.h #end lib_target diff --git a/panda/src/linmath/cmath.I b/dtool/src/dtoolbase/cmath.I similarity index 80% rename from panda/src/linmath/cmath.I rename to dtool/src/dtoolbase/cmath.I index 71e785ecf2..501a0ac072 100644 --- a/panda/src/linmath/cmath.I +++ b/dtool/src/dtoolbase/cmath.I @@ -30,23 +30,23 @@ __isnan ( x ) ) #endif -INLINE_LINMATH float csqrt(float v) { +INLINE float csqrt(float v) { return sqrtf(v); } -INLINE_LINMATH float csin(float v) { +INLINE float csin(float v) { return sinf(v); } -INLINE_LINMATH float ccos(float v) { +INLINE float ccos(float v) { return cosf(v); } -INLINE_LINMATH float ctan(float v) { +INLINE float ctan(float v) { return tanf(v); } -INLINE_LINMATH void +INLINE void sincosf(float v, float *pSinResult, float *pCosResult) { // MS VC defines _M_IX86 for x86. gcc should define _X86_ @@ -66,7 +66,7 @@ sincosf(float v, float *pSinResult, float *pCosResult) { #endif //!_X86_ } -INLINE_LINMATH void +INLINE void sincosd(double v, double *pSinResult, double *pCosResult) { #if defined(_M_IX86) || defined(_X86_) //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb @@ -84,23 +84,23 @@ sincosd(double v, double *pSinResult, double *pCosResult) { #endif //!_X86_ } -INLINE_LINMATH void csincos(float v,float *pSinResult, float *pCosResult) { +INLINE void csincos(float v,float *pSinResult, float *pCosResult) { sincosf(v,pSinResult,pCosResult); } -INLINE_LINMATH void csincos(double v,double *pSinResult, double *pCosResult) { +INLINE void csincos(double v,double *pSinResult, double *pCosResult) { sincosd(v,pSinResult,pCosResult); } -INLINE_LINMATH float cabs(float v) { +INLINE float cabs(float v) { return fabs(v); } -INLINE_LINMATH float catan(float v) { +INLINE float catan(float v) { return atanf(v); } -INLINE_LINMATH float catan2(float y, float x) { +INLINE float catan2(float y, float x) { return atan2f(y, x); } @@ -110,7 +110,7 @@ INLINE_LINMATH float catan2(float y, float x) { #define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT #endif -INLINE_LINMATH double cfloor(double f) { +INLINE double cfloor(double f) { #ifdef __INTEL_COMPILER // intel floor doesnt work right if fpu mode is not double, so make double-prec mode is on unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); @@ -123,7 +123,7 @@ INLINE_LINMATH double cfloor(double f) { #endif } -INLINE_LINMATH double cceil(double f) { +INLINE double cceil(double f) { #ifdef __INTEL_COMPILER // intel ceil doesnt work right if fpu mode is not double, so make double-prec mode is on unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); @@ -136,35 +136,35 @@ INLINE_LINMATH double cceil(double f) { #endif } -INLINE_LINMATH double csqrt(double v) { +INLINE double csqrt(double v) { return sqrt(v); } -INLINE_LINMATH double csin(double v) { +INLINE double csin(double v) { return sin(v); } -INLINE_LINMATH double ccos(double v) { +INLINE double ccos(double v) { return cos(v); } -INLINE_LINMATH double ctan(double v) { +INLINE double ctan(double v) { return tan(v); } -INLINE_LINMATH double cabs(double v) { +INLINE double cabs(double v) { return fabs(v); } -INLINE_LINMATH double catan(double v) { +INLINE double catan(double v) { return atan(v); } -INLINE_LINMATH double catan2(double y, double x) { +INLINE double catan2(double y, double x) { return atan2(y, x); } -INLINE_LINMATH bool cnan(double v) { +INLINE bool cnan(double v) { #ifndef _WIN32 return (isnan(v) != 0); #else diff --git a/panda/src/linmath/cmath.h b/dtool/src/dtoolbase/cmath.h similarity index 52% rename from panda/src/linmath/cmath.h rename to dtool/src/dtoolbase/cmath.h index 39ca3ab289..1e2a4eddb1 100644 --- a/panda/src/linmath/cmath.h +++ b/dtool/src/dtoolbase/cmath.h @@ -19,7 +19,7 @@ #ifndef CMATH_H #define CMATH_H -#include "pandabase.h" +#include "dtoolbase.h" #include @@ -29,31 +29,31 @@ // explicitly whether we need to call, for instance, sqrtf() or // sqrt(). -INLINE_LINMATH float csqrt(float v); -INLINE_LINMATH float csin(float v); -INLINE_LINMATH float ccos(float v); -INLINE_LINMATH float ctan(float v); -INLINE_LINMATH void csincos(float v, float *pSinResult, float *pCosResult); // does both at once (faster on x86) -INLINE_LINMATH float cabs(float v); -INLINE_LINMATH float catan(float v); -INLINE_LINMATH float catan2(float y, float x); -//INLINE_LINMATH float cfloor(float f); -//INLINE_LINMATH float cceil(float f); +INLINE float csqrt(float v); +INLINE float csin(float v); +INLINE float ccos(float v); +INLINE float ctan(float v); +INLINE void csincos(float v, float *pSinResult, float *pCosResult); // does both at once (faster on x86) +INLINE float cabs(float v); +INLINE float catan(float v); +INLINE float catan2(float y, float x); +//INLINE float cfloor(float f); +//INLINE float cceil(float f); -INLINE_LINMATH double cfloor(double f); -INLINE_LINMATH double cceil(double f); -INLINE_LINMATH double csqrt(double v); -INLINE_LINMATH double csin(double v); -INLINE_LINMATH double ccos(double v); -INLINE_LINMATH double ctan(double v); -INLINE_LINMATH double cabs(double v); -INLINE_LINMATH double catan(double v); -INLINE_LINMATH double catan2(double y, double x); -INLINE_LINMATH void csincos(double v, double *pSinResult, double *pCosResult); // does both at once (faster on x86) +INLINE double cfloor(double f); +INLINE double cceil(double f); +INLINE double csqrt(double v); +INLINE double csin(double v); +INLINE double ccos(double v); +INLINE double ctan(double v); +INLINE double cabs(double v); +INLINE double catan(double v); +INLINE double catan2(double y, double x); +INLINE void csincos(double v, double *pSinResult, double *pCosResult); // does both at once (faster on x86) // Returns true if the number is nan, false if it's a genuine number // or infinity. -INLINE_LINMATH bool cnan(double v); +INLINE bool cnan(double v); #include "cmath.I" diff --git a/panda/src/linmath/nearly_zero.h b/dtool/src/dtoolbase/nearly_zero.h similarity index 89% rename from panda/src/linmath/nearly_zero.h rename to dtool/src/dtoolbase/nearly_zero.h index 4715f13e19..31e3ee0388 100644 --- a/panda/src/linmath/nearly_zero.h +++ b/dtool/src/dtoolbase/nearly_zero.h @@ -19,16 +19,22 @@ #ifndef NEARLY_ZERO_H #define NEARLY_ZERO_H +#include "dtoolbase.h" // The following two functions are defined just to make the // NEARLY_ZERO() macro work. They each return a suitable nearly-zero // value for their corresponding numeric type. -INLINE_LINMATH double + +// Note that declaring these small numeric values first as a static +// const identifier, and then returning the value of that identifier, +// seems to lead to compilation errors (at least in VC7) in which +// sometimes IS_THRESHOLD_COMPEQ(a, a, get_nearly_zero_value(a)) != 0. +INLINE double get_nearly_zero_value(double) { return 1.0e-12; } -INLINE_LINMATH float +INLINE float get_nearly_zero_value(float) { return 1.0e-6f; } diff --git a/dtool/src/dtoolbase/pmap.h b/dtool/src/dtoolbase/pmap.h index fc4fa719db..f7654bb558 100644 --- a/dtool/src/dtoolbase/pmap.h +++ b/dtool/src/dtoolbase/pmap.h @@ -21,15 +21,28 @@ #include "dtoolbase.h" #include "pallocator.h" +#include "stl_compares.h" #include +#ifdef HAVE_STL_HASH +#include +#endif #ifdef NO_STYLE_ALLOCATOR // If we're not using custom allocators, just use the standard class // definition. #define pmap map #define pmultimap multimap -#else + +#ifdef HAVE_STL_HASH +#define phash_map hash_map +#define phash_multimap hash_multimap +#else // HAVE_STL_HASH +#define phash_map map +#define phash_multimap multimap +#endif // HAVE_STL_HASH + +#else // NO_STYLE_ALLOCATOR //////////////////////////////////////////////////////////////////// // Class : pmap @@ -61,5 +74,41 @@ public: pmultimap(const Compare &comp) : multimap >(comp) { } }; +#ifdef HAVE_STL_HASH +//////////////////////////////////////////////////////////////////// +// Class : phash_map +// Description : This is our own Panda specialization on the default +// STL hash_map. Its main purpose is to call the hooks +// for MemoryUsage to properly track STL-allocated +// memory. +//////////////////////////////////////////////////////////////////// +template > > +class phash_map : public hash_map > { +public: + phash_map() : hash_map >() { } + phash_map(const phash_map ©) : hash_map >(copy) { } + phash_map(const Compare &comp) : hash_map >(comp) { } +}; + +//////////////////////////////////////////////////////////////////// +// Class : phash_multimap +// Description : This is our own Panda specialization on the default +// STL hash_multimap. Its main purpose is to call the hooks +// for MemoryUsage to properly track STL-allocated +// memory. +//////////////////////////////////////////////////////////////////// +template > > +class phash_multimap : public hash_multimap > { +public: + phash_multimap() : hash_multimap >() { } + phash_multimap(const phash_multimap ©) : hash_multimap >(copy) { } + phash_multimap(const Compare &comp) : hash_multimap >(comp) { } +}; + +#else // HAVE_STL_HASH +#define phash_map pmap +#define phash_multimap pmultimap +#endif // HAVE_STL_HASH + #endif // NO_STYLE_ALLOCATOR #endif diff --git a/dtool/src/dtoolbase/pset.h b/dtool/src/dtoolbase/pset.h index 84c857ebd8..2169d08292 100644 --- a/dtool/src/dtoolbase/pset.h +++ b/dtool/src/dtoolbase/pset.h @@ -21,15 +21,28 @@ #include "dtoolbase.h" #include "pallocator.h" +#include "stl_compares.h" #include +#ifdef HAVE_STL_HASH +#include +#endif #ifdef NO_STYLE_ALLOCATOR // If we're not using custom allocators, just use the standard class // definition. #define pset set #define pmultiset multiset -#else + +#ifdef HAVE_STL_HASH +#define phash_set hash_set +#define phash_multiset hash_multiset +#else // HAVE_STL_HASH +#define phash_set set +#define phash_multiset multiset +#endif // HAVE_STL_HASH + +#else // NO_STYLE_ALLOCATOR //////////////////////////////////////////////////////////////////// // Class : pset @@ -61,5 +74,41 @@ public: pmultiset(const Compare &comp) : multiset >(comp) { } }; +#ifdef HAVE_STL_HASH +//////////////////////////////////////////////////////////////////// +// Class : phash_set +// Description : This is our own Panda specialization on the default +// STL hash_set. Its main purpose is to call the hooks +// for MemoryUsage to properly track STL-allocated +// memory. +//////////////////////////////////////////////////////////////////// +template > > +class phash_set : public hash_set > { +public: + phash_set() : hash_set >() { } + phash_set(const phash_set ©) : hash_set >(copy) { } + phash_set(const Compare &comp) : hash_set >(comp) { } +}; + +//////////////////////////////////////////////////////////////////// +// Class : phash_multiset +// Description : This is our own Panda specialization on the default +// STL hash_multiset. Its main purpose is to call the hooks +// for MemoryUsage to properly track STL-allocated +// memory. +//////////////////////////////////////////////////////////////////// +template > > +class phash_multiset : public hash_multiset > { +public: + phash_multiset() : hash_multiset >() { } + phash_multiset(const phash_multiset ©) : hash_multiset >(copy) { } + phash_multiset(const Compare &comp) : hash_multiset >(comp) { } +}; + +#else // HAVE_STL_HASH +#define phash_set pset +#define phash_multiset pmultiset +#endif // HAVE_STL_HASH + #endif // NO_STYLE_ALLOCATOR #endif diff --git a/dtool/src/dtoolbase/stl_compares.I b/dtool/src/dtoolbase/stl_compares.I new file mode 100644 index 0000000000..7e9603883f --- /dev/null +++ b/dtool/src/dtoolbase/stl_compares.I @@ -0,0 +1,194 @@ +// Filename: stl_compares.I +// Created by: drose (28Sep04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_threshold::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE floating_point_threshold:: +floating_point_threshold(Key threshold) : + _threshold(threshold) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_threshold::operator () +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool floating_point_threshold:: +operator () (const Key &a, const Key &b) const { + return cfloor(a / _threshold + 0.5f) < cfloor(b / _threshold + 0.5f); +} + +//////////////////////////////////////////////////////////////////// +// Function: compare_to::operator () +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool compare_to:: +operator () (const Key &a, const Key &b) const { + return (a.compare_to(b) < 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: indirect_less::operator () +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool indirect_less:: +operator () (const Key &a, const Key &b) const { + return (a != b && (*a) < (*b)); +} + +//////////////////////////////////////////////////////////////////// +// Function: indirect_compare_to::operator () +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool indirect_compare_to:: +operator () (const Key &a, const Key &b) const { + return (a != b && (*a).compare_to(*b) < 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: indirect_compare_names::operator () +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool indirect_compare_names:: +operator () (const Key &a, const Key &b) const { + return (a != b && (*a).get_name() < (*b).get_name()); +} + +#ifdef HAVE_STL_HASH + +//////////////////////////////////////////////////////////////////// +// Function: integer_hash::add_hash +// Access: Public, Static +// Description: Adds the indicated key into a running hash. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t integer_hash:: +add_hash(size_t hash, const Key &key) { + return (hash * 31) + (size_t)key; +} + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_hash::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE floating_point_hash:: +floating_point_hash(Key threshold) : + _threshold(threshold) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_hash::operator () +// Access: Public +// Description: Computes a size_t hash from the float. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t floating_point_hash:: +operator () (const Key &key) const { + return add_hash(0, key); +} + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_hash::operator () (two parameters) +// Access: Public +// Description: Returns true if a sorts before b, false otherwise. +//////////////////////////////////////////////////////////////////// +template +INLINE bool floating_point_hash:: +operator () (const Key &a, const Key &b) const { + return cfloor(a / _threshold + 0.5f) < cfloor(b / _threshold + 0.5f); +} + +//////////////////////////////////////////////////////////////////// +// Function: floating_point_hash::add_hash +// Access: Public +// Description: Adds the indicated key into a running hash. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t floating_point_hash:: +add_hash(size_t hash, const Key &key) const { + return (hash * 31) + (size_t)(cfloor(key / _threshold + 0.5f)); +} + +//////////////////////////////////////////////////////////////////// +// Function: sequence_hash::operator () +// Access: Public +// Description: Trivially computes a size_t hash from the components +// of the string. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t sequence_hash:: +operator () (const Key &key) const { + return add_hash(0, key); +} + +//////////////////////////////////////////////////////////////////// +// Function: sequence_hash::add_hash +// Access: Public, Static +// Description: Adds the elements of the indicated key into a running +// hash. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t sequence_hash:: +add_hash(size_t hash, const Key &key) { + Key::const_iterator ki; + for (ki = key.begin(); ki != key.end(); ++ki) { + hash = (hash * 31) + (size_t)(*ki); + } + return hash; +} + +//////////////////////////////////////////////////////////////////// +// Function: method_hash::operator () +// Access: Public +// Description: Calls the Key's get_hash() method. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t method_hash:: +operator () (const Key &key) const { + return key.get_hash(); +} + +//////////////////////////////////////////////////////////////////// +// Function: indirect_method_hash::operator () +// Access: Public +// Description: Calls the Key's get_hash() method. +//////////////////////////////////////////////////////////////////// +template +INLINE size_t indirect_method_hash:: +operator () (const Key &key) const { + return (*key).get_hash(); +} + +#endif // HAVE_STL_HASH diff --git a/dtool/src/dtoolbase/stl_compares.h b/dtool/src/dtoolbase/stl_compares.h new file mode 100644 index 0000000000..c4aad15bdc --- /dev/null +++ b/dtool/src/dtoolbase/stl_compares.h @@ -0,0 +1,221 @@ +// Filename: stl_compares.h +// Created by: drose (28Sep04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef STL_COMPARES_H +#define STL_COMPARES_H + +#include "dtoolbase.h" +#include "cmath.h" +#include "nearly_zero.h" + +#ifdef HAVE_STL_HASH +#include +#include +#endif // HAVE_STL_HASH + +//////////////////////////////////////////////////////////////////// +// Class : floating_point_threshold +// Description : Compares two floating point numbers, within threshold +// of equivalence. +//////////////////////////////////////////////////////////////////// +template +class floating_point_threshold { +public: + INLINE floating_point_threshold(Key threshold = get_nearly_zero_value((Key)0)); + INLINE bool operator () (const Key &a, const Key &b) const; + const Key _threshold; +}; + +//////////////////////////////////////////////////////////////////// +// Class : compare_to +// Description : An STL function object class, this is intended to be +// used on any ordered collection of class objects that +// contain a compare_to() method. It defines the order +// of the objects via compare_to(). +//////////////////////////////////////////////////////////////////// +template +class compare_to { +public: + INLINE bool operator () (const Key &a, const Key &b) const; +}; + +//////////////////////////////////////////////////////////////////// +// Class : indirect_less +// Description : An STL function object class, this is intended to be +// used on any ordered collection of pointers to classes +// that contain an operator <() method. It defines the +// order of the pointers via operator <(). +//////////////////////////////////////////////////////////////////// +template +class indirect_less { +public: + INLINE bool operator () (const Key &a, const Key &b) const; +}; + +//////////////////////////////////////////////////////////////////// +// Class : indirect_compare_to +// Description : An STL function object class, this is intended to be +// used on any ordered collection of pointers to classes +// that contain a compare_to() method. It defines the +// order of the pointers via compare_to(). +//////////////////////////////////////////////////////////////////// +template +class indirect_compare_to { +public: + INLINE bool operator () (const Key &a, const Key &b) const; +}; + +//////////////////////////////////////////////////////////////////// +// Class : indirect_compare_names +// Description : An STL function object class, this is intended to be +// used on any ordered collection of pointers to classes +// that define a get_name() method, particularly for +// things that derive from Namable. It defines the +// order of the pointers by case-sensitive name +// comparison. +//////////////////////////////////////////////////////////////////// +template +class indirect_compare_names { +public: + INLINE bool operator () (const Key &a, const Key &b) const; +}; + +#ifdef HAVE_STL_HASH + +//////////////////////////////////////////////////////////////////// +// Class : integer_hash +// Description : This is the default hash_compare class, which assumes +// the Key is a size_t value or can be implicitly +// converted to a size_t value (for instance, via a +// size_t typecast operator). It is the same as the +// system-provided hash_compare. +//////////////////////////////////////////////////////////////////// +template > +class integer_hash : public hash_compare { +public: + INLINE static size_t add_hash(size_t start, const Key &key); +}; + +//////////////////////////////////////////////////////////////////// +// Class : floating_point_hash +// Description : This hash_compare class hashes a float or a double. +//////////////////////////////////////////////////////////////////// +template +class floating_point_hash : public hash_compare { +public: + INLINE floating_point_hash(Key threshold = get_nearly_zero_value((Key)0)); + INLINE size_t operator () (const Key &key) const; + INLINE bool operator () (const Key &a, const Key &b) const; + INLINE size_t add_hash(size_t start, const Key &key) const; + const Key _threshold; +}; + +//////////////////////////////////////////////////////////////////// +// Class : sequence_hash +// Description : This hash_compare class hashes a string. It assumes +// the Key is a string or provides begin() and end() +// methods that iterate through Key::value_type. +//////////////////////////////////////////////////////////////////// +template > +class sequence_hash : public hash_compare { +public: + INLINE size_t operator () (const Key &key) const; + INLINE bool operator () (const Key &a, const Key &b) const { + return hash_compare::operator () (a, b); + } + INLINE static size_t add_hash(size_t start, const Key &key); +}; + +//////////////////////////////////////////////////////////////////// +// Class : method_hash +// Description : This hash_compare class hashes a class object. It +// assumes the Key provides a method called get_hash() +// that returns a size_t. +//////////////////////////////////////////////////////////////////// +template > +class method_hash : public hash_compare { +public: + INLINE size_t operator () (const Key &key) const; + INLINE bool operator () (const Key &a, const Key &b) const { + return hash_compare::operator () (a, b); + } +}; + +//////////////////////////////////////////////////////////////////// +// Class : indirect_method_hash +// Description : This hash_compare class hashes a pointer to a class +// object. It assumes the Key is a pointer to a class +// that provides a method called get_hash() that returns +// a size_t. +//////////////////////////////////////////////////////////////////// +template +class indirect_method_hash : public hash_compare { +public: + INLINE size_t operator () (const Key &key) const; + INLINE bool operator () (const Key &a, const Key &b) const { + return hash_compare::operator () (a, b); + } +}; + +#else // HAVE_STL_HASH + +// If the STL doesn't provide any hash methods, then all of the above +// simply map to their Compare function. +template > +class floating_point_hash : public Compare { +}; +template > +class integer_hash : public Compare { +}; +template > +class sequence_hash : public Compare { +}; +template > +class method_hash : public Compare { +}; +template +class indirect_method_hash : public Compare { +}; + +#endif // HAVE_STL_HASH + +#include "stl_compares.I" + +typedef floating_point_hash float_hash; +typedef floating_point_hash double_hash; +typedef integer_hash pointer_hash; +typedef integer_hash int_hash; +typedef integer_hash size_t_hash; +typedef sequence_hash string_hash; +typedef sequence_hash wstring_hash; + +template +class indirect_less_hash : public indirect_method_hash > { +}; + +template +class indirect_compare_to_hash : public indirect_method_hash > { +}; + +template +class indirect_compare_names_hash : public indirect_method_hash > { +}; + +#endif + + diff --git a/dtool/src/parser-inc/Sources.pp b/dtool/src/parser-inc/Sources.pp index f4b0d22a08..9fce5bc820 100644 --- a/dtool/src/parser-inc/Sources.pp +++ b/dtool/src/parser-inc/Sources.pp @@ -1,5 +1,5 @@ #define INSTALL_PARSER_INC \ - algorithm deque ft2build.h iostream list map memory \ + algorithm deque ft2build.h hash_map hash_set iostream list map memory \ pair queue set stack stdcompare.h stdtypedefs.h \ string vector windows.h zlib.h md5.h files.h hex.h \ nurbs.hh stddef.h krb5.h MainHelix.h dllpath.h hxcom.h \ diff --git a/dtool/src/parser-inc/hash_map b/dtool/src/parser-inc/hash_map new file mode 100644 index 0000000000..b8db9ba528 --- /dev/null +++ b/dtool/src/parser-inc/hash_map @@ -0,0 +1,57 @@ +// Filename: hash_map +// Created by: drose (12May00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +// This file, and all the other files in this directory, aren't +// intended to be compiled--they're just parsed by CPPParser (and +// interrogate) in lieu of the actual system headers, to generate the +// interrogate database. + +#ifndef HASH_MAP_H +#define HASH_MAP_H + +#include +#include +#include + +template > > +class hash_map { +public: + typedef key key_type; + typedef element data_type; + typedef element mapped_type; + typedef pair value_type; + typedef compare key_compare; + + typedef element *pointer; + typedef const element *const_pointer; + typedef element &reference; + typedef const element &const_reference; + + class iterator; + class const_iterator; + class reverse_iterator; + class const_reverse_iterator; + typedef size_t size_type; + class difference_type; +}; + +template > > +class hash_multimap : public hash_map { +}; + +#endif diff --git a/dtool/src/parser-inc/hash_set b/dtool/src/parser-inc/hash_set new file mode 100644 index 0000000000..f6a428f123 --- /dev/null +++ b/dtool/src/parser-inc/hash_set @@ -0,0 +1,55 @@ +// Filename: hash_set +// Created by: drose (28Sep04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +// This file, and all the other files in this directory, aren't +// intended to be compiled--they're just parsed by CPPParser (and +// interrogate) in lieu of the actual system headers, to generate the +// interrogate database. + +#ifndef HASH_SET_H +#define HASH_SET_H + +#include +#include + +template > > +class hash_set { +public: + typedef key key_type; + typedef key value_type; + typedef compare key_compare; + typedef compare value_compare; + + typedef key *pointer; + typedef const key *const_pointer; + typedef key &reference; + typedef const key &const_reference; + + class iterator; + class const_iterator; + class reverse_iterator; + class const_reverse_iterator; + typedef size_t size_type; + class difference_type; +}; + +template > > +class hash_multiset : public hash_set { +}; + +#endif diff --git a/dtool/src/parser-inc/stdcompare.h b/dtool/src/parser-inc/stdcompare.h index 0da64943cb..63ddc35dbe 100644 --- a/dtool/src/parser-inc/stdcompare.h +++ b/dtool/src/parser-inc/stdcompare.h @@ -29,5 +29,10 @@ class less { public: }; +template > +class hash_compare { +public: +}; + #endif diff --git a/panda/src/audiotraits/fmodAudioManager.h b/panda/src/audiotraits/fmodAudioManager.h index eec98b414e..53eaa1e836 100644 --- a/panda/src/audiotraits/fmodAudioManager.h +++ b/panda/src/audiotraits/fmodAudioManager.h @@ -120,15 +120,15 @@ private: bool stale; // can this entry be purged from the cache? char *data; // the memory-mapped audio file. } SoundCacheEntry; - typedef pmap SoundMap; + typedef phash_map SoundMap; SoundMap _sounds; - typedef pset AudioSet; + typedef phash_set AudioSet; // The offspring of this manager: AudioSet _soundsOnLoan; unsigned int _concurrent_sound_limit; - typedef pset SoundsPlaying; + typedef phash_set SoundsPlaying; // The sounds from this manager that are currently playing SoundsPlaying _sounds_playing; diff --git a/panda/src/downloader/httpChannel.h b/panda/src/downloader/httpChannel.h index 40ad46a344..128be40875 100644 --- a/panda/src/downloader/httpChannel.h +++ b/panda/src/downloader/httpChannel.h @@ -365,7 +365,7 @@ private: }; ResponseType _response_type; - + // Not a phash_map, to maintain sorted order. typedef pmap Headers; Headers _headers; diff --git a/panda/src/downloader/httpClient.h b/panda/src/downloader/httpClient.h index 1ca3e1c8e3..d0ce047431 100644 --- a/panda/src/downloader/httpClient.h +++ b/panda/src/downloader/httpClient.h @@ -168,7 +168,7 @@ private: typedef pmap Usernames; Usernames _usernames; - typedef pmap Realms; + typedef pmap Realms; class Domain { public: Realms _realms; @@ -176,6 +176,7 @@ private: typedef pmap Domains; Domains _proxy_domains, _www_domains; + // Not a phash_set, since we want this to be maintained in order. typedef pset Cookies; Cookies _cookies; diff --git a/panda/src/downloadertools/multify.cxx b/panda/src/downloadertools/multify.cxx index 37f0f57961..a29ef96bf9 100644 --- a/panda/src/downloadertools/multify.cxx +++ b/panda/src/downloadertools/multify.cxx @@ -31,7 +31,7 @@ bool create = false; // -c bool append = false; // -r bool update = false; // -u -bool list = false; // -t +bool tlist = false; // -t bool extract = false; // -x bool verbose = false; // -v bool compress = false; // -z @@ -504,7 +504,7 @@ main(int argc, char *argv[]) { update = true; break; case 't': - list = true; + tlist = true; break; case 'x': extract = true; @@ -605,7 +605,7 @@ main(int argc, char *argv[]) { argv += (optind - 1); // We should have exactly one of these options. - if ((create?1:0) + (append?1:0) + (update?1:0) + (list?1:0) + (extract?1:0) != 1) { + if ((create?1:0) + (append?1:0) + (update?1:0) + (tlist?1:0) + (extract?1:0) != 1) { cerr << "Exactly one of -c, -r, -u, -t, -x must be specified.\n"; usage(); return 1; diff --git a/panda/src/event/eventHandler.h b/panda/src/event/eventHandler.h index b77ef5f2ab..e57f6c8ae4 100644 --- a/panda/src/event/eventHandler.h +++ b/panda/src/event/eventHandler.h @@ -72,11 +72,11 @@ public: protected: - typedef pset Functions; - typedef pmap Hooks; + typedef phash_set Functions; + typedef phash_map Hooks; typedef pair CallbackFunction; typedef pset CallbackFunctions; - typedef pmap CallbackHooks; + typedef phash_map CallbackHooks; Hooks _hooks; CallbackHooks _cbhooks; diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index e9c99db072..3be98596d3 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -296,6 +296,17 @@ operator < (const PointerToBase &other) const { #endif // CPPPARSER +//////////////////////////////////////////////////////////////////// +// Function: PointerToBase::get_hash +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE size_t PointerToBase:: +get_hash() const { + return (size_t)_void_ptr; +} + //////////////////////////////////////////////////////////////////// diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index b1af263bb9..556d6cd7c9 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -74,6 +74,7 @@ public: INLINE bool operator < (const To *other) const; INLINE bool operator < (const PointerToBase &other) const; #endif // CPPPARSER + INLINE size_t get_hash() const; PUBLISHED: INLINE bool is_null() const; diff --git a/panda/src/express/typeHandle.I b/panda/src/express/typeHandle.I index 4c876ee45a..8484a09b78 100644 --- a/panda/src/express/typeHandle.I +++ b/panda/src/express/typeHandle.I @@ -117,6 +117,16 @@ compare_to(const TypeHandle &other) const { return _index - other._index; } +//////////////////////////////////////////////////////////////////// +// Function: TypeHandle::get_hash +// Access: Published +// Description: Returns a hash code suitable for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE size_t TypeHandle:: +get_hash() const { + return (size_t)_index; +} + //////////////////////////////////////////////////////////////////// // Function: TypeHandle::get_name // Access: Published diff --git a/panda/src/express/typeHandle.h b/panda/src/express/typeHandle.h index c04eda7b96..9ba440212a 100644 --- a/panda/src/express/typeHandle.h +++ b/panda/src/express/typeHandle.h @@ -100,6 +100,7 @@ PUBLISHED: INLINE bool operator > (const TypeHandle &other) const; INLINE bool operator >= (const TypeHandle &other) const; INLINE int compare_to(const TypeHandle &other) const; + INLINE size_t get_hash() const; INLINE string get_name(TypedObject *object = (TypedObject *)NULL) const; INLINE bool is_derived_from(TypeHandle parent, diff --git a/panda/src/express/typeRegistry.h b/panda/src/express/typeRegistry.h index a84e73360b..1cc6ca71a1 100644 --- a/panda/src/express/typeRegistry.h +++ b/panda/src/express/typeRegistry.h @@ -100,7 +100,7 @@ private: typedef pvector HandleRegistry; HandleRegistry _handle_registry; - typedef pmap NameRegistry; + typedef phash_map NameRegistry; NameRegistry _name_registry; typedef pvector RootClasses; diff --git a/panda/src/express/unicodeLatinMap.h b/panda/src/express/unicodeLatinMap.h index f1dabc93f5..281310c355 100644 --- a/panda/src/express/unicodeLatinMap.h +++ b/panda/src/express/unicodeLatinMap.h @@ -137,7 +137,7 @@ private: static void init(); static bool _initialized; - typedef pmap ByCharacter; + typedef phash_map > ByCharacter; static ByCharacter _by_character; enum { max_direct_chars = 256 }; static const Entry *_direct_chars[max_direct_chars]; diff --git a/panda/src/express/virtualFileSystem.h b/panda/src/express/virtualFileSystem.h index c6cf0b7784..a7e959113b 100644 --- a/panda/src/express/virtualFileSystem.h +++ b/panda/src/express/virtualFileSystem.h @@ -25,7 +25,6 @@ #include "filename.h" #include "dSearchPath.h" #include "pointerTo.h" -#include "pmap.h" #include "config_express.h" class Multifile; diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index 7f8bfe5a2f..500c688975 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -274,6 +274,8 @@ protected: PTA_ushort _tindex; }; + // A pmap, not a phash_map, to save space because it will probably + // have only one element. typedef pmap TexCoordsByName; TexCoordsByName _texcoords_by_name; diff --git a/panda/src/gobj/materialPool.h b/panda/src/gobj/materialPool.h index 65bf220b3b..af64f08627 100644 --- a/panda/src/gobj/materialPool.h +++ b/panda/src/gobj/materialPool.h @@ -23,7 +23,6 @@ #include "material.h" -#include "indirectCompareTo.h" #include "pointerTo.h" #include "pset.h" @@ -63,7 +62,7 @@ private: static MaterialPool *get_ptr(); static MaterialPool *_global_ptr; - typedef pset< CPT(Material), IndirectCompareTo > Materials; + typedef pset< CPT(Material), indirect_compare_to > Materials; Materials _materials; }; diff --git a/panda/src/gobj/preparedGraphicsObjects.h b/panda/src/gobj/preparedGraphicsObjects.h index 4d5fc34559..e964371528 100644 --- a/panda/src/gobj/preparedGraphicsObjects.h +++ b/panda/src/gobj/preparedGraphicsObjects.h @@ -71,10 +71,10 @@ public: void update(GraphicsStateGuardianBase *gsg); private: - typedef pset Textures; - typedef pset< PT(Texture) > EnqueuedTextures; - typedef pset Geoms; - typedef pset< PT(Geom) > EnqueuedGeoms; + typedef phash_set Textures; + typedef phash_set< PT(Texture) > EnqueuedTextures; + typedef phash_set Geoms; + typedef phash_set< PT(Geom) > EnqueuedGeoms; Mutex _lock; Textures _prepared_textures, _released_textures; diff --git a/panda/src/gobj/texCoordName.h b/panda/src/gobj/texCoordName.h index 481e3d5435..5afbd507a4 100644 --- a/panda/src/gobj/texCoordName.h +++ b/panda/src/gobj/texCoordName.h @@ -49,7 +49,7 @@ PUBLISHED: private: string _name; - typedef pmap TexCoordsByName; + typedef phash_map TexCoordsByName; static TexCoordsByName _texcoords_by_name; static CPT(TexCoordName) _default_name; diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index b85cb674ed..e14364dee5 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -153,7 +153,7 @@ private: // Each PGO conversely keeps a list (a set) of all the Textures that // have been prepared there. When either destructs, it removes // itself from the other's list. - typedef pmap Contexts; + typedef pmap Contexts; Contexts _contexts; // This value represents the intersection of all the dirty flags of diff --git a/panda/src/gobj/texturePool.h b/panda/src/gobj/texturePool.h index 2124f180e0..83a160be63 100644 --- a/panda/src/gobj/texturePool.h +++ b/panda/src/gobj/texturePool.h @@ -78,7 +78,7 @@ private: static TexturePool *get_ptr(); static TexturePool *_global_ptr; - typedef pmap Textures; + typedef phash_map Textures; Textures _textures; string _fake_texture_image; }; diff --git a/panda/src/lerp/lerpfunctor.h b/panda/src/lerp/lerpfunctor.h index 98f6570ea1..9506732faf 100644 --- a/panda/src/lerp/lerpfunctor.h +++ b/panda/src/lerp/lerpfunctor.h @@ -196,7 +196,7 @@ typedef SimpleQueryLerpFunctor LVector4fQueryLerpFunctor; class EXPCL_PANDA MultiLerpFunctor : public LerpFunctor { private: - typedef pset< PT(LerpFunctor) > Functors; + typedef phash_set< PT(LerpFunctor) > Functors; Functors _funcs; public: MultiLerpFunctor(void) {} diff --git a/panda/src/linmath/Sources.pp b/panda/src/linmath/Sources.pp index 6480c60ab8..cf01b3c467 100644 --- a/panda/src/linmath/Sources.pp +++ b/panda/src/linmath/Sources.pp @@ -9,7 +9,7 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx #define SOURCES \ - cmath.I cmath.h compose_matrix.h compose_matrix_src.I \ + compose_matrix.h compose_matrix_src.I \ compose_matrix_src.cxx compose_matrix_src.h config_linmath.h \ coordinateSystem.h dbl2fltnames.h dblnames.h deg_2_rad.h \ flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I \ @@ -33,7 +33,7 @@ lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.cxx \ lvector2_src.h lvector3.h lvector3_src.I lvector3_src.cxx \ lvector3_src.h lvector4.h lvector4_src.I lvector4_src.cxx \ - lvector4_src.h mathNumbers.h nearly_zero.h pta_Colorf.h \ + lvector4_src.h mathNumbers.h pta_Colorf.h \ pta_Normalf.h pta_TexCoordf.h pta_Vertexf.h vector_Colorf.h \ vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h \ vector_TexCoordf.h vector_Vertexf.h @@ -50,7 +50,7 @@ vector_LVecBase3f.cxx vector_Normalf.cxx vector_Vertexf.cxx \ #define INSTALL_HEADERS \ - cmath.I cmath.h compose_matrix.h compose_matrix_src.I \ + compose_matrix.h compose_matrix_src.I \ compose_matrix_src.h config_linmath.h coordinateSystem.h \ dbl2fltnames.h dblnames.h deg_2_rad.h \ flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I \ @@ -68,7 +68,7 @@ lvecBase3_src.I lvecBase3_src.h lvecBase4.h lvecBase4_src.I \ lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.h \ lvector3.h lvector3_src.I lvector3_src.h lvector4.h lvector4_src.I \ - lvector4_src.h mathNumbers.h nearly_zero.h pta_Colorf.h \ + lvector4_src.h mathNumbers.h pta_Colorf.h \ pta_Normalf.h pta_TexCoordf.h pta_Vertexf.h vector_Colorf.h \ vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h \ vector_TexCoordf.h vector_Vertexf.h diff --git a/panda/src/linmath/lmatrix3_src.I b/panda/src/linmath/lmatrix3_src.I index 56565bf37d..2d5c0e429c 100644 --- a/panda/src/linmath/lmatrix3_src.I +++ b/panda/src/linmath/lmatrix3_src.I @@ -399,6 +399,60 @@ compare_to(const FLOATNAME(LMatrix3) &other) const { return compare_to(other, NEARLY_ZERO(FLOATTYPE)); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix3):: +get_hash() const { + return add_hash(0); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix3):: +get_hash(FLOATTYPE threshold) const { + return add_hash(0, threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix3):: +add_hash(size_t hash) const { + return add_hash(hash, NEARLY_ZERO(FLOATTYPE)); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix3):: +add_hash(size_t hash, FLOATTYPE threshold) const { + float_hash fhasher(threshold); + + hash = fhasher.add_hash(hash, _m.m._00); + hash = fhasher.add_hash(hash, _m.m._01); + hash = fhasher.add_hash(hash, _m.m._02); + + hash = fhasher.add_hash(hash, _m.m._10); + hash = fhasher.add_hash(hash, _m.m._11); + hash = fhasher.add_hash(hash, _m.m._12); + + hash = fhasher.add_hash(hash, _m.m._20); + hash = fhasher.add_hash(hash, _m.m._21); + hash = fhasher.add_hash(hash, _m.m._22); + + return hash; +} + #define VECTOR3_MATRIX3_PRODUCT(v_res, v, mat) \ v_res._v.v._0 = v._v.v._0*mat._m.m._00 + v._v.v._1*mat._m.m._10 + v._v.v._2*mat._m.m._20; \ v_res._v.v._1 = v._v.v._0*mat._m.m._01 + v._v.v._1*mat._m.m._11 + v._v.v._2*mat._m.m._21; \ diff --git a/panda/src/linmath/lmatrix3_src.h b/panda/src/linmath/lmatrix3_src.h index 786f25ba88..69a35c87bc 100644 --- a/panda/src/linmath/lmatrix3_src.h +++ b/panda/src/linmath/lmatrix3_src.h @@ -82,6 +82,10 @@ PUBLISHED: INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix3) &other) const; int compare_to(const FLOATNAME(LMatrix3) &other, FLOATTYPE threshold) const; + INLINE_LINMATH size_t get_hash() const; + INLINE_LINMATH size_t get_hash(FLOATTYPE threshold) const; + INLINE_LINMATH size_t add_hash(size_t hash) const; + INLINE_LINMATH size_t add_hash(size_t hash, FLOATTYPE threshold) const; INLINE_LINMATH FLOATNAME(LVecBase3) xform(const FLOATNAME(LVecBase3) &v) const; diff --git a/panda/src/linmath/lmatrix4_src.I b/panda/src/linmath/lmatrix4_src.I index 03f76622c5..4968ffd8c8 100644 --- a/panda/src/linmath/lmatrix4_src.I +++ b/panda/src/linmath/lmatrix4_src.I @@ -551,6 +551,68 @@ compare_to(const FLOATNAME(LMatrix4) &other) const { return compare_to(other, NEARLY_ZERO(FLOATTYPE)); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix4):: +get_hash() const { + return add_hash(0); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix4):: +get_hash(FLOATTYPE threshold) const { + return add_hash(0, threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix4):: +add_hash(size_t hash) const { + return add_hash(hash, NEARLY_ZERO(FLOATTYPE)); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LMatrix4):: +add_hash(size_t hash, FLOATTYPE threshold) const { + float_hash fhasher(threshold); + + hash = fhasher.add_hash(hash, _m.m._00); + hash = fhasher.add_hash(hash, _m.m._01); + hash = fhasher.add_hash(hash, _m.m._02); + hash = fhasher.add_hash(hash, _m.m._03); + + hash = fhasher.add_hash(hash, _m.m._10); + hash = fhasher.add_hash(hash, _m.m._11); + hash = fhasher.add_hash(hash, _m.m._12); + hash = fhasher.add_hash(hash, _m.m._13); + + hash = fhasher.add_hash(hash, _m.m._20); + hash = fhasher.add_hash(hash, _m.m._21); + hash = fhasher.add_hash(hash, _m.m._22); + hash = fhasher.add_hash(hash, _m.m._23); + + hash = fhasher.add_hash(hash, _m.m._30); + hash = fhasher.add_hash(hash, _m.m._31); + hash = fhasher.add_hash(hash, _m.m._32); + hash = fhasher.add_hash(hash, _m.m._33); + + return hash; +} + #define VECTOR4_MATRIX4_PRODUCT(v_res, v, mat) \ v_res._v.v._0 = v._v.v._0*mat._m.m._00 + v._v.v._1*mat._m.m._10 + v._v.v._2*mat._m.m._20 + v._v.v._3*mat._m.m._30; \ v_res._v.v._1 = v._v.v._0*mat._m.m._01 + v._v.v._1*mat._m.m._11 + v._v.v._2*mat._m.m._21 + v._v.v._3*mat._m.m._31; \ diff --git a/panda/src/linmath/lmatrix4_src.h b/panda/src/linmath/lmatrix4_src.h index fb4e901cf8..021113c42f 100644 --- a/panda/src/linmath/lmatrix4_src.h +++ b/panda/src/linmath/lmatrix4_src.h @@ -91,6 +91,10 @@ PUBLISHED: INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix4) &other) const; int compare_to(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) const; + INLINE_LINMATH size_t get_hash() const; + INLINE_LINMATH size_t get_hash(FLOATTYPE threshold) const; + INLINE_LINMATH size_t add_hash(size_t hash) const; + INLINE_LINMATH size_t add_hash(size_t hash, FLOATTYPE threshold) const; INLINE_LINMATH FLOATNAME(LVecBase4) xform(const FLOATNAME(LVecBase4) &v) const; diff --git a/panda/src/linmath/luse.h b/panda/src/linmath/luse.h index a5a56bdd4c..28c1737a3a 100644 --- a/panda/src/linmath/luse.h +++ b/panda/src/linmath/luse.h @@ -64,6 +64,7 @@ #include "pandabase.h" +#include "stl_compares.h" #include "lvec2_ops.h" #include "lvec3_ops.h" #include "lvec4_ops.h" diff --git a/panda/src/linmath/lvecBase2_src.I b/panda/src/linmath/lvecBase2_src.I index bf81504f49..a6d5ded1c5 100644 --- a/panda/src/linmath/lvecBase2_src.I +++ b/panda/src/linmath/lvecBase2_src.I @@ -415,6 +415,49 @@ compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE threshold) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase2::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase2):: +get_hash() const { + return add_hash(0); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase2::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase2):: +get_hash(FLOATTYPE threshold) const { + return add_hash(0, threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase2::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase2):: +add_hash(size_t hash) const { + return add_hash(hash, NEARLY_ZERO(FLOATTYPE)); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase2::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase2):: +add_hash(size_t hash, FLOATTYPE threshold) const { + float_hash fhasher(threshold); + hash = fhasher.add_hash(hash, _v.v._0); + hash = fhasher.add_hash(hash, _v.v._1); + return hash; +} + //////////////////////////////////////////////////////////////////// // Function: LVecBase2::unary - // Access: Public diff --git a/panda/src/linmath/lvecBase2_src.h b/panda/src/linmath/lvecBase2_src.h index 1cf644945c..a9bc87386a 100644 --- a/panda/src/linmath/lvecBase2_src.h +++ b/panda/src/linmath/lvecBase2_src.h @@ -86,7 +86,10 @@ PUBLISHED: INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase2) &other) const; INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE threshold) const; - + INLINE_LINMATH size_t get_hash() const; + INLINE_LINMATH size_t get_hash(FLOATTYPE threshold) const; + INLINE_LINMATH size_t add_hash(size_t hash) const; + INLINE_LINMATH size_t add_hash(size_t hash, FLOATTYPE threshold) const; INLINE_LINMATH FLOATNAME(LVecBase2) operator - () const; diff --git a/panda/src/linmath/lvecBase3_src.I b/panda/src/linmath/lvecBase3_src.I index 9c5d35ebfc..7fbc694d3b 100644 --- a/panda/src/linmath/lvecBase3_src.I +++ b/panda/src/linmath/lvecBase3_src.I @@ -523,6 +523,50 @@ compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE threshold) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase3::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase3):: +get_hash() const { + return add_hash(0); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase3::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase3):: +get_hash(FLOATTYPE threshold) const { + return add_hash(0, threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase3::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase3):: +add_hash(size_t hash) const { + return add_hash(hash, NEARLY_ZERO(FLOATTYPE)); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase3::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase3):: +add_hash(size_t hash, FLOATTYPE threshold) const { + float_hash fhasher(threshold); + hash = fhasher.add_hash(hash, _v.v._0); + hash = fhasher.add_hash(hash, _v.v._1); + hash = fhasher.add_hash(hash, _v.v._2); + return hash; +} + //////////////////////////////////////////////////////////////////// // Function: LVecBase3::unary - // Access: Public diff --git a/panda/src/linmath/lvecBase3_src.h b/panda/src/linmath/lvecBase3_src.h index 1e4791f772..062f7f501c 100644 --- a/panda/src/linmath/lvecBase3_src.h +++ b/panda/src/linmath/lvecBase3_src.h @@ -90,6 +90,10 @@ PUBLISHED: INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase3) &other) const; INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE threshold) const; + INLINE_LINMATH size_t get_hash() const; + INLINE_LINMATH size_t get_hash(FLOATTYPE threshold) const; + INLINE_LINMATH size_t add_hash(size_t hash) const; + INLINE_LINMATH size_t add_hash(size_t hash, FLOATTYPE threshold) const; INLINE_LINMATH FLOATNAME(LVecBase3) operator - () const; diff --git a/panda/src/linmath/lvecBase4_src.I b/panda/src/linmath/lvecBase4_src.I index 32fedbbd53..8fa98b5c87 100644 --- a/panda/src/linmath/lvecBase4_src.I +++ b/panda/src/linmath/lvecBase4_src.I @@ -515,6 +515,51 @@ compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE threshold) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase4::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase4):: +get_hash() const { + return add_hash(0); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase4::get_hash +// Access: Public +// Description: Returns a suitable hash for phash_map. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase4):: +get_hash(FLOATTYPE threshold) const { + return add_hash(0, threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase4::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase4):: +add_hash(size_t hash) const { + return add_hash(hash, NEARLY_ZERO(FLOATTYPE)); +} + +//////////////////////////////////////////////////////////////////// +// Function: LVecBase4::add_hash +// Access: Public +// Description: Adds the vector into the running hash. +//////////////////////////////////////////////////////////////////// +INLINE_LINMATH size_t FLOATNAME(LVecBase4):: +add_hash(size_t hash, FLOATTYPE threshold) const { + float_hash fhasher(threshold); + hash = fhasher.add_hash(hash, _v.v._0); + hash = fhasher.add_hash(hash, _v.v._1); + hash = fhasher.add_hash(hash, _v.v._2); + hash = fhasher.add_hash(hash, _v.v._3); + return hash; +} + //////////////////////////////////////////////////////////////////// // Function: LVecBase4::unary - // Access: Public diff --git a/panda/src/linmath/lvecBase4_src.h b/panda/src/linmath/lvecBase4_src.h index 7ea7b63e00..fdd15f170a 100644 --- a/panda/src/linmath/lvecBase4_src.h +++ b/panda/src/linmath/lvecBase4_src.h @@ -91,6 +91,10 @@ PUBLISHED: INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase4) &other) const; INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE threshold) const; + INLINE_LINMATH size_t get_hash() const; + INLINE_LINMATH size_t get_hash(FLOATTYPE threshold) const; + INLINE_LINMATH size_t add_hash(size_t hash) const; + INLINE_LINMATH size_t add_hash(size_t hash, FLOATTYPE threshold) const; INLINE_LINMATH FLOATNAME(LVecBase4) operator - () const; diff --git a/panda/src/net/connectionManager.h b/panda/src/net/connectionManager.h index 534fdd6cdf..348e45bd71 100644 --- a/panda/src/net/connectionManager.h +++ b/panda/src/net/connectionManager.h @@ -76,9 +76,9 @@ protected: void add_writer(ConnectionWriter *writer); void remove_writer(ConnectionWriter *writer); - typedef pset< PT(Connection) > Connections; - typedef pset Readers; - typedef pset Writers; + typedef phash_set< PT(Connection) > Connections; + typedef phash_set Readers; + typedef phash_set Writers; Connections _connections; Readers _readers; Writers _writers; diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index 8c01dc980a..779868a211 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -74,7 +74,7 @@ private: typedef pvector< PT(CullBin) > Bins; Bins _bins; - typedef pset CullResults; + typedef phash_set CullResults; static CullResults _cull_results; }; diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 77918ab7a2..1c3b3680b0 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -716,7 +716,7 @@ private: CollideMask and_mask, CollideMask or_mask, TypeHandle node_type); - typedef pset Textures; + typedef phash_set Textures; Texture *r_find_texture(PandaNode *node, const RenderState *state, const GlobPattern &glob) const; void r_find_all_textures(PandaNode *node, const RenderState *state, @@ -725,7 +725,7 @@ private: void r_find_all_textures(PandaNode *node, TextureStage *stage, Textures &textures) const; - typedef pset TextureStages; + typedef phash_set TextureStages; TextureStage *r_find_texture_stage(PandaNode *node, const RenderState *state, const GlobPattern &glob) const; void r_find_all_texture_stages(PandaNode *node, const RenderState *state, diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index 4c7fd36f2d..f7277661f2 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -280,11 +280,11 @@ private: // requested a NodePath for. We don't keep reference counts; when // each NodePathComponent destructs, it removes itself from this // set. - typedef pset Paths; + typedef phash_set Paths; // This is used to maintain a table of keyed data on each node, for // the user's purposes. - typedef pmap TagData; + typedef phash_map TagData; // This is the data that must be cycled between pipeline stages. diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index 0be3d77335..58437bd86d 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -22,7 +22,6 @@ #include "pandabase.h" #include "typedWritableReferenceCount.h" -#include "indirectCompareTo.h" #include "pointerTo.h" #include "pset.h" @@ -105,7 +104,7 @@ protected: bool _always_reissue; private: - typedef pset > Attribs; + typedef pset > Attribs; static Attribs *_attribs; Attribs::iterator _saved_entry; diff --git a/panda/src/pgraph/renderEffect.h b/panda/src/pgraph/renderEffect.h index d59657f7ad..73e91585d5 100644 --- a/panda/src/pgraph/renderEffect.h +++ b/panda/src/pgraph/renderEffect.h @@ -25,7 +25,6 @@ #include "renderState.h" #include "typedWritableReferenceCount.h" -#include "indirectCompareTo.h" #include "pointerTo.h" #include "pset.h" #include "luse.h" @@ -92,7 +91,7 @@ protected: virtual int compare_to_impl(const RenderEffect *other) const; private: - typedef pset > Effects; + typedef pset > Effects; static Effects *_effects; Effects::iterator _saved_entry; diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h index 791dde786f..22f97012b3 100644 --- a/panda/src/pgraph/renderEffects.h +++ b/panda/src/pgraph/renderEffects.h @@ -27,7 +27,6 @@ #include "renderEffect.h" #include "typedWritableReferenceCount.h" #include "pointerTo.h" -#include "indirectLess.h" #include "ordered_vector.h" class CullTraverser; @@ -110,7 +109,7 @@ private: void determine_cull_callback(); private: - typedef pset > States; + typedef pset > States; static States *_states; static CPT(RenderEffects) _empty_state; diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 7b2b19f1ce..7cae8f4ba0 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -24,7 +24,6 @@ #include "renderAttrib.h" #include "typedWritableReferenceCount.h" #include "pointerTo.h" -#include "indirectLess.h" #include "ordered_vector.h" class GraphicsStateGuardianBase; @@ -152,7 +151,7 @@ private: INLINE bool is_destructing() const; private: - typedef pset > States; + typedef pset > States; static States *_states; static CPT(RenderState) _empty_state; @@ -180,7 +179,7 @@ private: // is not reference counted within this map; instead we store a // companion pointer in the other object, and remove the references // explicitly when either object destructs. - typedef pmap CompositionCache; + typedef phash_map CompositionCache; CompositionCache _composition_cache; CompositionCache _invert_composition_cache; diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index 55d398f487..c1019bf20b 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -265,6 +265,55 @@ operator < (const TransformState &other) const { return (this < &other); } +//////////////////////////////////////////////////////////////////// +// Function: TransformState::get_hash() +// Access: Published +// Description: Computes a suitable hash value for phash_map. +//////////////////////////////////////////////////////////////////// +size_t TransformState:: +get_hash() const { + size_t hash = 0; + int_hash ihasher; + float_hash fhasher; + pointer_hash phasher; + + static const int significant_flags = + (F_is_invalid | F_is_identity | F_components_given | F_hpr_given); + + int flags = (_flags & significant_flags); + hash = ihasher.add_hash(hash, flags); + + if ((_flags & (F_is_invalid | F_is_identity)) == 0) { + // Only bother to put the rest of the stuff in the hash if the + // transform is not invalid or empty. + + if ((_flags & (F_components_given | F_hpr_given | F_quat_given)) == + (F_components_given | F_hpr_given | F_quat_given)) { + // If the transform was specified componentwise, hash it + // componentwise. + hash = _pos.add_hash(hash); + if ((_flags & F_hpr_given) != 0) { + hash = _hpr.add_hash(hash); + + } else if ((_flags & F_quat_given) != 0) { + hash = _quat.add_hash(hash); + } + + hash = _scale.add_hash(hash); + hash = _shear.add_hash(hash); + + } else { + // Otherwise, hash the pointer only--any two different + // matrix-based TransformStates are considered to be different, + // even if their matrices have the same values. + + hash = phasher.add_hash(hash, this); + } + } + + return hash; +} + //////////////////////////////////////////////////////////////////// // Function: TransformState::make_identity // Access: Published, Static diff --git a/panda/src/pgraph/transformState.h b/panda/src/pgraph/transformState.h index 94e62a6c81..1c49acce86 100644 --- a/panda/src/pgraph/transformState.h +++ b/panda/src/pgraph/transformState.h @@ -23,7 +23,6 @@ #include "typedWritableReferenceCount.h" #include "pointerTo.h" -#include "indirectLess.h" #include "luse.h" #include "pset.h" #include "event.h" @@ -66,6 +65,7 @@ public: PUBLISHED: bool operator < (const TransformState &other) const; + size_t get_hash() const; static CPT(TransformState) make_identity(); static CPT(TransformState) make_invalid(); @@ -159,7 +159,7 @@ private: CompositionCycleDesc &cycle_desc); private: - typedef pset > States; + typedef phash_set > States; static States *_states; static CPT(TransformState) _identity_state; @@ -187,7 +187,7 @@ private: // is not reference counted within this map; instead we store a // companion pointer in the other object, and remove the references // explicitly when either object destructs. - typedef pmap CompositionCache; + typedef phash_map CompositionCache; CompositionCache _composition_cache; CompositionCache _invert_composition_cache; diff --git a/panda/src/pstatclient/pStatClient.h b/panda/src/pstatclient/pStatClient.h index 54448b6981..fb122074d8 100644 --- a/panda/src/pstatclient/pStatClient.h +++ b/panda/src/pstatclient/pStatClient.h @@ -125,6 +125,7 @@ private: // Stats collecting stuff ClockObject _clock; + // Not a phash_map, so the threads remain sorted by name. typedef pmap ThingsByName; ThingsByName _threads_by_name; diff --git a/panda/src/putil/bamReader.h b/panda/src/putil/bamReader.h index d12c682357..e9d78d5cf8 100644 --- a/panda/src/putil/bamReader.h +++ b/panda/src/putil/bamReader.h @@ -163,7 +163,7 @@ private: // This maps the type index numbers encountered within the Bam file // to actual TypeHandles. - typedef pmap IndexMap; + typedef phash_map IndexMap; IndexMap _index_map; // This maps the object ID numbers encountered within the Bam file @@ -173,7 +173,7 @@ private: TypedWritable *_ptr; ChangeThisFunc _change_this; }; - typedef pmap CreatedObjs; + typedef phash_map CreatedObjs; CreatedObjs _created_objs; // This is the iterator into the above map for the object we are // currently reading in p_read_object(). It is carefully maintained @@ -188,11 +188,11 @@ private: // completed, along with the object ID's of the pointers they need, // in the order in which read_pointer() was called, so that we may // call the appropriate complete_pointers() later. - typedef pmap ObjectPointers; + typedef phash_map ObjectPointers; ObjectPointers _object_pointers; // Ditto, for the PiplineCycler objects. - typedef pmap CyclerPointers; + typedef phash_map CyclerPointers; CyclerPointers _cycler_pointers; // This is the number of extra objects that must still be read (and @@ -202,12 +202,12 @@ private: // This is the set of all objects that registered themselves for // finalization. - typedef pset Finalize; + typedef phash_set Finalize; Finalize _finalize_list; // These are used by get_pta() and register_pta() to unify multiple // references to the same PointerToArray. - typedef pmap PTAMap; + typedef phash_map PTAMap; PTAMap _pta_map; int _pta_id; @@ -215,11 +215,11 @@ private: // on-the-fly to satisfy bam requirements. We keep track of this // just so we can suppress warning messages from attempts to create // objects of these types. - typedef pset NewTypes; + typedef phash_set NewTypes; static NewTypes _new_types; // This is used in support of set_aux_data() and get_aux_data(). - typedef pmap AuxData; + typedef phash_map AuxData; AuxData _aux_data; int _file_major, _file_minor; diff --git a/panda/src/putil/bamWriter.h b/panda/src/putil/bamWriter.h index 920934dec0..4f078e283a 100644 --- a/panda/src/putil/bamWriter.h +++ b/panda/src/putil/bamWriter.h @@ -101,7 +101,7 @@ private: int enqueue_object(const TypedWritable *object); // This is the set of all TypeHandles already written. - pset _types_written; + pset _types_written; // This keeps track of all of the objects we have written out // already (or are about to write out), and associates a unique @@ -113,7 +113,7 @@ private: StoreState(int object_id) : _object_id(object_id), _written(false) {} }; - typedef pmap StateMap; + typedef phash_map StateMap; StateMap _state_map; // This is the next object ID that will be assigned to a new object. @@ -133,7 +133,7 @@ private: // These are used by register_pta() to unify multiple references to // the same PointerToArray. - typedef pmap PTAMap; + typedef phash_map PTAMap; PTAMap _pta_map; int _next_pta_id; bool _long_pta_id; diff --git a/panda/src/putil/buttonRegistry.h b/panda/src/putil/buttonRegistry.h index 692cd3dcc5..8664b0fd3c 100644 --- a/panda/src/putil/buttonRegistry.h +++ b/panda/src/putil/buttonRegistry.h @@ -25,7 +25,6 @@ #include "pvector.h" #include "pmap.h" -#include //////////////////////////////////////////////////////////////////// // Class : ButtonRegistry @@ -72,7 +71,7 @@ private: typedef pvector HandleRegistry; HandleRegistry _handle_registry; - typedef pmap NameRegistry; + typedef phash_map NameRegistry; NameRegistry _name_registry; static ButtonRegistry *_global_pointer; diff --git a/panda/src/putil/globalPointerRegistry.h b/panda/src/putil/globalPointerRegistry.h index 83d2fe19c4..594ac87983 100644 --- a/panda/src/putil/globalPointerRegistry.h +++ b/panda/src/putil/globalPointerRegistry.h @@ -79,7 +79,7 @@ private: static GlobalPointerRegistry *_global_ptr; private: - typedef pmap Pointers; + typedef phash_map Pointers; Pointers _pointers; }; diff --git a/panda/src/putil/nameUniquifier.h b/panda/src/putil/nameUniquifier.h index fde7420cf8..d488dd51d4 100644 --- a/panda/src/putil/nameUniquifier.h +++ b/panda/src/putil/nameUniquifier.h @@ -44,7 +44,7 @@ public: private: string add_name_body(const string &name, const string &prefix); - typedef pset Names; + typedef pset Names; Names _names; string _separator; string _empty; diff --git a/panda/src/testbed/Sources.pp b/panda/src/testbed/Sources.pp index ab5e3b37f1..27f54e5615 100644 --- a/panda/src/testbed/Sources.pp +++ b/panda/src/testbed/Sources.pp @@ -41,3 +41,8 @@ #define TARGET test_texmem #define SOURCES test_texmem.cxx #end test_bin_target + +#begin test_bin_target + #define TARGET test_map + #define SOURCES test_map.cxx +#end test_bin_target diff --git a/panda/src/testbed/test_map.cxx b/panda/src/testbed/test_map.cxx new file mode 100644 index 0000000000..a8a8273aaa --- /dev/null +++ b/panda/src/testbed/test_map.cxx @@ -0,0 +1,171 @@ +// Filename: test_map.cxx +// Created by: drose (29Sep04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "pandabase.h" +#include "pmap.h" +#include "memoryUsage.h" +#include "clockObject.h" + +class Alpha { +public: + Alpha(const string &str) : _str(str) { } + + size_t get_hash() const { + size_t hash = 0; + string::const_iterator si; + for (si = _str.begin(); si != _str.end(); ++si) { + hash = (hash * 31) + (size_t)(*si); + } + return hash; + } + + bool operator < (const Alpha &other) const { + return strcmp(_str.c_str(), other._str.c_str()) < 0; + } + + string _str; +}; + +ostream &operator << (ostream &out, const Alpha &alpha) { + return out << alpha._str; +} + +class Beta : public Alpha { +public: + Beta(const string &str) : Alpha(str) { } + + size_t get_hash() const { + return ~_str[0]; + } +}; + + +static const char * const sample_strings[] = { + "apple", + "apricot", + "banana", + "blueberry", + "grape", + "grapefruit", + "guava", + "honeydew", + "lemon", + "lime", + "mango", + "orange", + "peach", + "pear", + "pineapple", + "plum", + "raspberry", + "strawberry", + "watermelon", +}; +static const size_t num_sample_strings = sizeof(sample_strings) / sizeof(const char *); + +void +insert_fruit() { + // typedef pmap MapType; + // typedef pmap MapType; + // typedef phash_map MapType; + typedef phash_map MapType; + + MapType m; + + for (size_t i = 0; i < num_sample_strings; i++) { + string str = sample_strings[i]; + bool inserted = m.insert(MapType::value_type(str, str)).second; + if (!inserted) { + cerr << "Could not insert " << str << "\n"; + } + } + + cout << "Map contains:\n"; + MapType::iterator mi; + for (mi = m.begin(); mi != m.end(); ++mi) { + cout << " " << (*mi).first << "\n"; + } +} + +void +test_performance() { + typedef Alpha KeyType; + + typedef phash_map MapType; + //typedef pmap MapType; + + MemoryUsage::is_tracking(); + ClockObject *clock = ClockObject::get_global_clock(); + + static const int key_len = 10; + static const int sample_mask = 0xffff; + static const int sample_size = sample_mask + 1; + static const int initial_population = 1000; + static const int num_cycles = 10000; + static const int num_reps = 3; + + vector samples; + samples.reserve(sample_size); + for (int s = 0; s < sample_size; s++) { + string key; + for (int k = 0; k < key_len; k++) { + key += string(1, (char)((rand() & 0x3f) + '@')); + } + samples.push_back(key); + } + + MemoryUsage::freeze(); + MapType *m = new MapType; + if (MemoryUsage::has_cpp_size()) { + cerr << "Empty map uses " << MemoryUsage::get_current_cpp_size() + << " bytes.\n"; + } + + for (int p = 0; p < initial_population; p++) { + m->insert(MapType::value_type(samples[rand() & sample_mask], 0)); + } + if (MemoryUsage::has_cpp_size()) { + cerr << "map with " << m->size() + << " elements uses " << MemoryUsage::get_current_cpp_size() + << " bytes.\n"; + } + + for (int r = 0; r < num_reps; r++) { + double now = clock->get_real_time(); + for (int c = 0; c < num_cycles; c++) { + const KeyType &element = samples[rand() & sample_mask]; + bool inserted = m->insert(MapType::value_type(element, 0)).second; + if (inserted) { + m->erase(element); + } + } + double elapsed = clock->get_real_time() - now; + cerr << "After " << num_cycles << " cycles in " << elapsed * 1000.0 + << " ms, map has " << m->size() + << " elements and uses " << MemoryUsage::get_current_cpp_size() + << " bytes.\n"; + } +} + +int +main(int argc, char *argv[]) { + // insert_fruit(); + test_performance(); + + return 0; +}