Pārlūkot izejas kodu

phash_map, etc.

David Rose 21 gadi atpakaļ
vecāks
revīzija
dbb24d9cc9
64 mainītis faili ar 1282 papildinājumiem un 115 dzēšanām
  1. 9 0
      dtool/Config.pp
  2. 3 0
      dtool/LocalSetup.pp
  3. 2 2
      dtool/src/dconfig/configTable.h
  4. 6 0
      dtool/src/dtoolbase/Sources.pp
  5. 21 21
      dtool/src/dtoolbase/cmath.I
  6. 23 23
      dtool/src/dtoolbase/cmath.h
  7. 8 2
      dtool/src/dtoolbase/nearly_zero.h
  8. 50 1
      dtool/src/dtoolbase/pmap.h
  9. 50 1
      dtool/src/dtoolbase/pset.h
  10. 194 0
      dtool/src/dtoolbase/stl_compares.I
  11. 221 0
      dtool/src/dtoolbase/stl_compares.h
  12. 1 1
      dtool/src/parser-inc/Sources.pp
  13. 57 0
      dtool/src/parser-inc/hash_map
  14. 55 0
      dtool/src/parser-inc/hash_set
  15. 5 0
      dtool/src/parser-inc/stdcompare.h
  16. 3 3
      panda/src/audiotraits/fmodAudioManager.h
  17. 1 1
      panda/src/downloader/httpChannel.h
  18. 2 1
      panda/src/downloader/httpClient.h
  19. 3 3
      panda/src/downloadertools/multify.cxx
  20. 3 3
      panda/src/event/eventHandler.h
  21. 11 0
      panda/src/express/pointerToBase.I
  22. 1 0
      panda/src/express/pointerToBase.h
  23. 10 0
      panda/src/express/typeHandle.I
  24. 1 0
      panda/src/express/typeHandle.h
  25. 1 1
      panda/src/express/typeRegistry.h
  26. 1 1
      panda/src/express/unicodeLatinMap.h
  27. 0 1
      panda/src/express/virtualFileSystem.h
  28. 2 0
      panda/src/gobj/geom.h
  29. 1 2
      panda/src/gobj/materialPool.h
  30. 4 4
      panda/src/gobj/preparedGraphicsObjects.h
  31. 1 1
      panda/src/gobj/texCoordName.h
  32. 1 1
      panda/src/gobj/texture.h
  33. 1 1
      panda/src/gobj/texturePool.h
  34. 1 1
      panda/src/lerp/lerpfunctor.h
  35. 4 4
      panda/src/linmath/Sources.pp
  36. 54 0
      panda/src/linmath/lmatrix3_src.I
  37. 4 0
      panda/src/linmath/lmatrix3_src.h
  38. 62 0
      panda/src/linmath/lmatrix4_src.I
  39. 4 0
      panda/src/linmath/lmatrix4_src.h
  40. 1 0
      panda/src/linmath/luse.h
  41. 43 0
      panda/src/linmath/lvecBase2_src.I
  42. 4 1
      panda/src/linmath/lvecBase2_src.h
  43. 44 0
      panda/src/linmath/lvecBase3_src.I
  44. 4 0
      panda/src/linmath/lvecBase3_src.h
  45. 45 0
      panda/src/linmath/lvecBase4_src.I
  46. 4 0
      panda/src/linmath/lvecBase4_src.h
  47. 3 3
      panda/src/net/connectionManager.h
  48. 1 1
      panda/src/pgraph/cullResult.h
  49. 2 2
      panda/src/pgraph/nodePath.h
  50. 2 2
      panda/src/pgraph/pandaNode.h
  51. 1 2
      panda/src/pgraph/renderAttrib.h
  52. 1 2
      panda/src/pgraph/renderEffect.h
  53. 1 2
      panda/src/pgraph/renderEffects.h
  54. 2 3
      panda/src/pgraph/renderState.h
  55. 49 0
      panda/src/pgraph/transformState.cxx
  56. 3 3
      panda/src/pgraph/transformState.h
  57. 1 0
      panda/src/pstatclient/pStatClient.h
  58. 8 8
      panda/src/putil/bamReader.h
  59. 3 3
      panda/src/putil/bamWriter.h
  60. 1 2
      panda/src/putil/buttonRegistry.h
  61. 1 1
      panda/src/putil/globalPointerRegistry.h
  62. 1 1
      panda/src/putil/nameUniquifier.h
  63. 5 0
      panda/src/testbed/Sources.pp
  64. 171 0
      panda/src/testbed/test_map.cxx

+ 9 - 0
dtool/Config.pp

@@ -244,6 +244,15 @@
 #define STL_CFLAGS
 #define STL_CFLAGS
 #define STL_LIBS
 #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?
 // Is OpenSSL installed, and where?
 #define SSL_IPATH /usr/local/ssl/include
 #define SSL_IPATH /usr/local/ssl/include
 #define SSL_LPATH /usr/local/ssl/lib
 #define SSL_LPATH /usr/local/ssl/lib

+ 3 - 0
dtool/LocalSetup.pp

@@ -271,6 +271,9 @@ $[cdefine SIMPLE_STRUCT_POINTERS]
 /* Define if we have Dinkumware STL installed.  */
 /* Define if we have Dinkumware STL installed.  */
 $[cdefine HAVE_DINKUM]
 $[cdefine HAVE_DINKUM]
 
 
+/* Define if we have STL hash_map etc. available  */
+$[cdefine HAVE_STL_HASH]
+
 /* Define if we have a gettimeofday() function. */
 /* Define if we have a gettimeofday() function. */
 $[cdefine HAVE_GETTIMEOFDAY]
 $[cdefine HAVE_GETTIMEOFDAY]
 
 

+ 2 - 2
dtool/src/dconfig/configTable.h

@@ -40,8 +40,8 @@ public:
   typedef vector_SymbolEnt    Symbol;
   typedef vector_SymbolEnt    Symbol;
 
 
 private:
 private:
-  typedef pmap<ConfigString, Symbol>      SymbolTable;
-  typedef pmap<ConfigString, SymbolTable> TableMap;
+  typedef phash_map<ConfigString, Symbol, sequence_hash<ConfigString> >      SymbolTable;
+  typedef phash_map<ConfigString, SymbolTable, sequence_hash<ConfigString> > TableMap;
   typedef pvector<GlobPattern> Globs;
   typedef pvector<GlobPattern> Globs;
 
 
   SymbolTable unqualified;
   SymbolTable unqualified;

+ 6 - 0
dtool/src/dtoolbase/Sources.pp

@@ -2,15 +2,21 @@
   #define TARGET dtoolbase
   #define TARGET dtoolbase
   
   
   #define SOURCES \
   #define SOURCES \
+    cmath.I cmath.h \
     dallocator.T dallocator.h \
     dallocator.T dallocator.h \
     dtoolbase.cxx dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \
     dtoolbase.cxx dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \
     fakestringstream.h \
     fakestringstream.h \
+    nearly_zero.h \
+    stl_compares.I stl_compares.h \
     pallocator.T pallocator.h \
     pallocator.T pallocator.h \
     pdeque.h plist.h pmap.h pset.h pvector.h
     pdeque.h plist.h pmap.h pset.h pvector.h
 
 
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \
+    cmath.I cmath.h \
     dallocator.T dallocator.h \
     dallocator.T dallocator.h \
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
+    nearly_zero.h \
+    stl_compares.I stl_compares.h \
     pallocator.T pallocator.h \
     pallocator.T pallocator.h \
     pdeque.h plist.h pmap.h pset.h pvector.h
     pdeque.h plist.h pmap.h pset.h pvector.h
 #end lib_target
 #end lib_target

+ 21 - 21
panda/src/linmath/cmath.I → dtool/src/dtoolbase/cmath.I

@@ -30,23 +30,23 @@
                               __isnan  ( x ) )
                               __isnan  ( x ) )
 #endif
 #endif
 
 
-INLINE_LINMATH float csqrt(float v) {
+INLINE float csqrt(float v) {
   return sqrtf(v);
   return sqrtf(v);
 }
 }
 
 
-INLINE_LINMATH float csin(float v) {
+INLINE float csin(float v) {
   return sinf(v);
   return sinf(v);
 }
 }
 
 
-INLINE_LINMATH float ccos(float v) {
+INLINE float ccos(float v) {
   return cosf(v);
   return cosf(v);
 }
 }
 
 
-INLINE_LINMATH float ctan(float v) {
+INLINE float ctan(float v) {
   return tanf(v);
   return tanf(v);
 }
 }
 
 
-INLINE_LINMATH void
+INLINE void
 sincosf(float v, float *pSinResult, float *pCosResult) {
 sincosf(float v, float *pSinResult, float *pCosResult) {
 
 
 // MS VC defines _M_IX86 for x86.  gcc should define _X86_
 // MS VC defines _M_IX86 for x86.  gcc should define _X86_
@@ -66,7 +66,7 @@ sincosf(float v, float *pSinResult, float *pCosResult) {
 #endif //!_X86_
 #endif //!_X86_
 }
 }
 
 
-INLINE_LINMATH void
+INLINE void
 sincosd(double v, double *pSinResult, double *pCosResult) {
 sincosd(double v, double *pSinResult, double *pCosResult) {
 #if defined(_M_IX86) || defined(_X86_)
 #if defined(_M_IX86) || defined(_X86_)
 //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb
 //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb
@@ -84,23 +84,23 @@ sincosd(double v, double *pSinResult, double *pCosResult) {
 #endif //!_X86_
 #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);
   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);
   sincosd(v,pSinResult,pCosResult);
 }
 }
 
 
-INLINE_LINMATH float cabs(float v) {
+INLINE float cabs(float v) {
   return fabs(v);
   return fabs(v);
 }
 }
 
 
-INLINE_LINMATH float catan(float v) {
+INLINE float catan(float v) {
   return atanf(v);
   return atanf(v);
 }
 }
 
 
-INLINE_LINMATH float catan2(float y, float x) {
+INLINE float catan2(float y, float x) {
   return atan2f(y, x);
   return atan2f(y, x);
 }
 }
 
 
@@ -110,7 +110,7 @@ INLINE_LINMATH float catan2(float y, float x) {
 #define FPU_CONTROLWORD_NEW_SETTING  _CW_DEFAULT
 #define FPU_CONTROLWORD_NEW_SETTING  _CW_DEFAULT
 #endif  
 #endif  
 
 
-INLINE_LINMATH double cfloor(double f) {
+INLINE double cfloor(double f) {
   #ifdef __INTEL_COMPILER
   #ifdef __INTEL_COMPILER
     // intel floor doesnt work right if fpu mode is not double, so make double-prec mode is on
     // 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);
     unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
@@ -123,7 +123,7 @@ INLINE_LINMATH double cfloor(double f) {
   #endif
   #endif
 }
 }
 
 
-INLINE_LINMATH double cceil(double f) {
+INLINE double cceil(double f) {
   #ifdef __INTEL_COMPILER
   #ifdef __INTEL_COMPILER
     // intel ceil doesnt work right if fpu mode is not double, so make double-prec mode is on
     // 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);
     unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
@@ -136,35 +136,35 @@ INLINE_LINMATH double cceil(double f) {
   #endif
   #endif
 }
 }
 
 
-INLINE_LINMATH double csqrt(double v) {
+INLINE double csqrt(double v) {
   return sqrt(v);
   return sqrt(v);
 }
 }
 
 
-INLINE_LINMATH double csin(double v) {
+INLINE double csin(double v) {
   return sin(v);
   return sin(v);
 }
 }
 
 
-INLINE_LINMATH double ccos(double v) {
+INLINE double ccos(double v) {
   return cos(v);
   return cos(v);
 }
 }
 
 
-INLINE_LINMATH double ctan(double v) {
+INLINE double ctan(double v) {
   return tan(v);
   return tan(v);
 }
 }
 
 
-INLINE_LINMATH double cabs(double v) {
+INLINE double cabs(double v) {
   return fabs(v);
   return fabs(v);
 }
 }
 
 
-INLINE_LINMATH double catan(double v) {
+INLINE double catan(double v) {
   return atan(v);
   return atan(v);
 }
 }
 
 
-INLINE_LINMATH double catan2(double y, double x) {
+INLINE double catan2(double y, double x) {
   return atan2(y, x);
   return atan2(y, x);
 }
 }
 
 
-INLINE_LINMATH bool cnan(double v) {
+INLINE bool cnan(double v) {
 #ifndef _WIN32
 #ifndef _WIN32
   return (isnan(v) != 0);
   return (isnan(v) != 0);
 #else
 #else

+ 23 - 23
panda/src/linmath/cmath.h → dtool/src/dtoolbase/cmath.h

@@ -19,7 +19,7 @@
 #ifndef CMATH_H
 #ifndef CMATH_H
 #define CMATH_H
 #define CMATH_H
 
 
-#include "pandabase.h"
+#include "dtoolbase.h"
 
 
 #include <math.h>
 #include <math.h>
 
 
@@ -29,31 +29,31 @@
 // explicitly whether we need to call, for instance, sqrtf() or
 // explicitly whether we need to call, for instance, sqrtf() or
 // sqrt().
 // 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_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 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 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
 // Returns true if the number is nan, false if it's a genuine number
 // or infinity.
 // or infinity.
-INLINE_LINMATH bool cnan(double v);
+INLINE bool cnan(double v);
 
 
 #include "cmath.I"
 #include "cmath.I"
 
 

+ 8 - 2
panda/src/linmath/nearly_zero.h → dtool/src/dtoolbase/nearly_zero.h

@@ -19,16 +19,22 @@
 #ifndef NEARLY_ZERO_H
 #ifndef NEARLY_ZERO_H
 #define NEARLY_ZERO_H
 #define NEARLY_ZERO_H
 
 
+#include "dtoolbase.h"
 
 
 // The following two functions are defined just to make the
 // The following two functions are defined just to make the
 // NEARLY_ZERO() macro work.  They each return a suitable nearly-zero
 // NEARLY_ZERO() macro work.  They each return a suitable nearly-zero
 // value for their corresponding numeric type.
 // 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) {
 get_nearly_zero_value(double) {
   return 1.0e-12;
   return 1.0e-12;
 }
 }
 
 
-INLINE_LINMATH float
+INLINE float
 get_nearly_zero_value(float) {
 get_nearly_zero_value(float) {
   return 1.0e-6f;
   return 1.0e-6f;
 }
 }

+ 50 - 1
dtool/src/dtoolbase/pmap.h

@@ -21,15 +21,28 @@
 
 
 #include "dtoolbase.h"
 #include "dtoolbase.h"
 #include "pallocator.h"
 #include "pallocator.h"
+#include "stl_compares.h"
 
 
 #include <map>
 #include <map>
+#ifdef HAVE_STL_HASH
+#include <hash_map>
+#endif
 
 
 #ifdef NO_STYLE_ALLOCATOR
 #ifdef NO_STYLE_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pmap map
 #define pmap map
 #define pmultimap multimap
 #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
 //       Class : pmap
@@ -61,5 +74,41 @@ public:
   pmultimap(const Compare &comp) : multimap<Key, Value, Compare, pallocator<Value> >(comp) { }
   pmultimap(const Compare &comp) : multimap<Key, Value, Compare, pallocator<Value> >(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 Key, class Value, class Compare = method_hash<Key, less<Key> > >
+class phash_map : public hash_map<Key, Value, Compare, pallocator<Value> > {
+public:
+  phash_map() : hash_map<Key, Value, Compare, pallocator<Value> >() { }
+  phash_map(const phash_map<Key, Value, Compare> &copy) : hash_map<Key, Value, Compare, pallocator<Value> >(copy) { }
+  phash_map(const Compare &comp) : hash_map<Key, Value, Compare, pallocator<Value> >(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 Key, class Value, class Compare = method_hash<Key, less<Key> > >
+class phash_multimap : public hash_multimap<Key, Value, Compare, pallocator<Value> > {
+public:
+  phash_multimap() : hash_multimap<Key, Value, Compare, pallocator<Value> >() { }
+  phash_multimap(const phash_multimap<Key, Value, Compare> &copy) : hash_multimap<Key, Value, Compare, pallocator<Value> >(copy) { }
+  phash_multimap(const Compare &comp) : hash_multimap<Key, Value, Compare, pallocator<Value> >(comp) { }
+};
+
+#else // HAVE_STL_HASH
+#define phash_map pmap
+#define phash_multimap pmultimap
+#endif  // HAVE_STL_HASH
+
 #endif  // NO_STYLE_ALLOCATOR
 #endif  // NO_STYLE_ALLOCATOR
 #endif
 #endif

+ 50 - 1
dtool/src/dtoolbase/pset.h

@@ -21,15 +21,28 @@
 
 
 #include "dtoolbase.h"
 #include "dtoolbase.h"
 #include "pallocator.h"
 #include "pallocator.h"
+#include "stl_compares.h"
 
 
 #include <set>
 #include <set>
+#ifdef HAVE_STL_HASH
+#include <hash_set>
+#endif
 
 
 #ifdef NO_STYLE_ALLOCATOR
 #ifdef NO_STYLE_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pset set
 #define pset set
 #define pmultiset multiset
 #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
 //       Class : pset
@@ -61,5 +74,41 @@ public:
   pmultiset(const Compare &comp) : multiset<Key, Compare, pallocator<Key> >(comp) { }
   pmultiset(const Compare &comp) : multiset<Key, Compare, pallocator<Key> >(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 Key, class Compare = method_hash<Key, less<Key> > >
+class phash_set : public hash_set<Key, Compare, pallocator<Key> > {
+public:
+  phash_set() : hash_set<Key, Compare, pallocator<Key> >() { }
+  phash_set(const phash_set<Key, Compare> &copy) : hash_set<Key, Compare, pallocator<Key> >(copy) { }
+  phash_set(const Compare &comp) : hash_set<Key, Compare, pallocator<Key> >(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 Key, class Compare = method_hash<Key, less<Key> > >
+class phash_multiset : public hash_multiset<Key, Compare, pallocator<Key> > {
+public:
+  phash_multiset() : hash_multiset<Key, Compare, pallocator<Key> >() { }
+  phash_multiset(const phash_multiset<Key, Compare> &copy) : hash_multiset<Key, Compare, pallocator<Key> >(copy) { }
+  phash_multiset(const Compare &comp) : hash_multiset<Key, Compare, pallocator<Key> >(comp) { }
+};
+
+#else // HAVE_STL_HASH
+#define phash_set pset
+#define phash_multiset pmultiset
+#endif  // HAVE_STL_HASH
+
 #endif  // NO_STYLE_ALLOCATOR
 #endif  // NO_STYLE_ALLOCATOR
 #endif
 #endif

+ 194 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+//     Function: floating_point_threshold::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Key>
+INLINE floating_point_threshold<Key>::
+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<class Key>
+INLINE bool floating_point_threshold<Key>::
+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<class Key>
+INLINE bool compare_to<Key>::
+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<class Key>
+INLINE bool indirect_less<Key>::
+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<class Key>
+INLINE bool indirect_compare_to<Key>::
+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<class Key>
+INLINE bool indirect_compare_names<Key>::
+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<class Key, class Compare>
+INLINE size_t integer_hash<Key, Compare>::
+add_hash(size_t hash, const Key &key) {
+  return (hash * 31) + (size_t)key;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: floating_point_hash::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Key>
+INLINE floating_point_hash<Key>::
+floating_point_hash(Key threshold) :
+  _threshold(threshold)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: floating_point_hash::operator ()
+//       Access: Public
+//  Description: Computes a size_t hash from the float.
+////////////////////////////////////////////////////////////////////
+template<class Key>
+INLINE size_t floating_point_hash<Key>::
+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<class Key>
+INLINE bool floating_point_hash<Key>::
+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<class Key>
+INLINE size_t floating_point_hash<Key>::
+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<class Key, class Compare>
+INLINE size_t sequence_hash<Key, Compare>::
+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<class Key, class Compare>
+INLINE size_t sequence_hash<Key, Compare>::
+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<class Key, class Compare>
+INLINE size_t method_hash<Key, Compare>::
+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<class Key, class Compare>
+INLINE size_t indirect_method_hash<Key, Compare>::
+operator () (const Key &key) const {
+  return (*key).get_hash();
+}
+
+#endif  // HAVE_STL_HASH

+ 221 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef STL_COMPARES_H
+#define STL_COMPARES_H
+
+#include "dtoolbase.h"
+#include "cmath.h"
+#include "nearly_zero.h"
+
+#ifdef HAVE_STL_HASH
+#include <hash_map>
+#include <hash_set>
+#endif  // HAVE_STL_HASH
+
+////////////////////////////////////////////////////////////////////
+//       Class : floating_point_threshold
+// Description : Compares two floating point numbers, within threshold
+//               of equivalence.
+////////////////////////////////////////////////////////////////////
+template<class Key>
+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 Key>
+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 Key>
+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 Key>
+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 Key>
+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 Key, class Compare = less<Key> >
+class integer_hash : public hash_compare<Key, 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 Key>
+class floating_point_hash : public hash_compare<Key> {
+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 Key, class Compare = less<Key> >
+class sequence_hash : public hash_compare<Key, Compare> {
+public:
+  INLINE size_t operator () (const Key &key) const;
+  INLINE bool operator () (const Key &a, const Key &b) const {
+    return hash_compare<Key, 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 Key, class Compare = less<Key> >
+class method_hash : public hash_compare<Key, Compare> {
+public:
+  INLINE size_t operator () (const Key &key) const;
+  INLINE bool operator () (const Key &a, const Key &b) const {
+    return hash_compare<Key, 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 Key, class Compare>
+class indirect_method_hash : public hash_compare<Key, Compare> {
+public:
+  INLINE size_t operator () (const Key &key) const;
+  INLINE bool operator () (const Key &a, const Key &b) const {
+    return hash_compare<Key, 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 Key, class Compare = less<Key> >
+class floating_point_hash : public Compare {
+};
+template<class Key, class Compare = less<Key> >
+class integer_hash : public Compare {
+};
+template<class Key, class Compare = less<Key> >
+class sequence_hash : public Compare {
+};
+template<class Key, class Compare = less<Key> >
+class method_hash : public Compare {
+};
+template<class Key, class Compare>
+class indirect_method_hash : public Compare {
+};
+
+#endif  // HAVE_STL_HASH
+
+#include "stl_compares.I"
+
+typedef floating_point_hash<float> float_hash;
+typedef floating_point_hash<double> double_hash;
+typedef integer_hash<const void *> pointer_hash;
+typedef integer_hash<int> int_hash;
+typedef integer_hash<size_t> size_t_hash;
+typedef sequence_hash<string> string_hash;
+typedef sequence_hash<wstring> wstring_hash;
+
+template<class Key>
+class indirect_less_hash : public indirect_method_hash<Key, indirect_less<Key> > {
+};
+
+template<class Key>
+class indirect_compare_to_hash : public indirect_method_hash<Key, indirect_compare_to<Key> > {
+};
+
+template<class Key>
+class indirect_compare_names_hash : public indirect_method_hash<Key, indirect_compare_names<Key> > {
+};
+
+#endif
+
+

+ 1 - 1
dtool/src/parser-inc/Sources.pp

@@ -1,5 +1,5 @@
 #define INSTALL_PARSER_INC \
 #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 \
     pair queue set stack stdcompare.h stdtypedefs.h \
     string vector windows.h zlib.h md5.h files.h hex.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 \
     nurbs.hh stddef.h krb5.h MainHelix.h dllpath.h hxcom.h \

+ 57 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// 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 <stdtypedefs.h>
+#include <stdcompare.h>
+#include <pair>
+
+template<class key, class element, class compare = hash_compare<key, less<key> > >
+class hash_map {
+public:
+  typedef key key_type;
+  typedef element data_type;
+  typedef element mapped_type;
+  typedef pair<const key, element> 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 key, class element, class compare = hash_compare<key, less<key> > >
+class hash_multimap : public hash_map<key, element, compare> {
+};
+
+#endif

+ 55 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// 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 <stdtypedefs.h>
+#include <stdcompare.h>
+
+template<class key, class compare = hash_compare<key, less<key> > >
+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 key, class compare = hash_compare<key, less<key> > >
+class hash_multiset : public hash_set<key, compare> {
+};
+
+#endif

+ 5 - 0
dtool/src/parser-inc/stdcompare.h

@@ -29,5 +29,10 @@ class less {
 public:
 public:
 };
 };
 
 
+template<class key, class comp = less<key> >
+class hash_compare {
+public:
+};
+
 #endif
 #endif
 
 

+ 3 - 3
panda/src/audiotraits/fmodAudioManager.h

@@ -120,15 +120,15 @@ private:
     bool stale; // can this entry be  purged from the cache?
     bool stale; // can this entry be  purged from the cache?
     char *data; // the memory-mapped audio file.
     char *data; // the memory-mapped audio file.
   } SoundCacheEntry;
   } SoundCacheEntry;
-  typedef pmap<string, SoundCacheEntry > SoundMap;
+  typedef phash_map<string, SoundCacheEntry, string_hash> SoundMap;
   SoundMap _sounds;
   SoundMap _sounds;
 
 
-  typedef pset<FmodAudioSound* > AudioSet;
+  typedef phash_set<FmodAudioSound*, pointer_hash> AudioSet;
   // The offspring of this manager:
   // The offspring of this manager:
   AudioSet _soundsOnLoan;
   AudioSet _soundsOnLoan;
   unsigned int _concurrent_sound_limit;
   unsigned int _concurrent_sound_limit;
 
 
-  typedef pset<FmodAudioSound* > SoundsPlaying;
+  typedef phash_set<FmodAudioSound*, pointer_hash> SoundsPlaying;
   // The sounds from this manager that are currently playing
   // The sounds from this manager that are currently playing
   SoundsPlaying _sounds_playing;
   SoundsPlaying _sounds_playing;
 
 

+ 1 - 1
panda/src/downloader/httpChannel.h

@@ -365,7 +365,7 @@ private:
   };
   };
   ResponseType _response_type;
   ResponseType _response_type;
   
   
-
+  // Not a phash_map, to maintain sorted order.
   typedef pmap<string, string> Headers;
   typedef pmap<string, string> Headers;
   Headers _headers;
   Headers _headers;
 
 

+ 2 - 1
panda/src/downloader/httpClient.h

@@ -168,7 +168,7 @@ private:
   typedef pmap<string, string> Usernames;
   typedef pmap<string, string> Usernames;
   Usernames _usernames;
   Usernames _usernames;
 
 
-  typedef pmap<string, PT(HTTPAuthorization) > Realms;
+  typedef pmap<string, PT(HTTPAuthorization)> Realms;
   class Domain {
   class Domain {
   public:
   public:
     Realms _realms;
     Realms _realms;
@@ -176,6 +176,7 @@ private:
   typedef pmap<string, Domain> Domains;
   typedef pmap<string, Domain> Domains;
   Domains _proxy_domains, _www_domains;
   Domains _proxy_domains, _www_domains;
 
 
+  // Not a phash_set, since we want this to be maintained in order.
   typedef pset<HTTPCookie> Cookies;
   typedef pset<HTTPCookie> Cookies;
   Cookies _cookies;
   Cookies _cookies;
 
 

+ 3 - 3
panda/src/downloadertools/multify.cxx

@@ -31,7 +31,7 @@
 bool create = false;           // -c
 bool create = false;           // -c
 bool append = false;           // -r
 bool append = false;           // -r
 bool update = false;           // -u
 bool update = false;           // -u
-bool list = false;             // -t
+bool tlist = false;             // -t
 bool extract = false;          // -x
 bool extract = false;          // -x
 bool verbose = false;          // -v
 bool verbose = false;          // -v
 bool compress = false;         // -z
 bool compress = false;         // -z
@@ -504,7 +504,7 @@ main(int argc, char *argv[]) {
       update = true;
       update = true;
       break;
       break;
     case 't':
     case 't':
-      list = true;
+      tlist = true;
       break;
       break;
     case 'x':
     case 'x':
       extract = true;
       extract = true;
@@ -605,7 +605,7 @@ main(int argc, char *argv[]) {
   argv += (optind - 1);
   argv += (optind - 1);
 
 
   // We should have exactly one of these options.
   // 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";
     cerr << "Exactly one of -c, -r, -u, -t, -x must be specified.\n";
     usage();
     usage();
     return 1;
     return 1;

+ 3 - 3
panda/src/event/eventHandler.h

@@ -72,11 +72,11 @@ public:
 
 
 protected:
 protected:
 
 
-  typedef pset<EventFunction *> Functions;
-  typedef pmap<string, Functions> Hooks;
+  typedef phash_set<EventFunction *, pointer_hash> Functions;
+  typedef phash_map<string, Functions, string_hash> Hooks;
   typedef pair<EventCallbackFunction*, void*> CallbackFunction;
   typedef pair<EventCallbackFunction*, void*> CallbackFunction;
   typedef pset<CallbackFunction> CallbackFunctions;
   typedef pset<CallbackFunction> CallbackFunctions;
-  typedef pmap<string, CallbackFunctions> CallbackHooks;
+  typedef phash_map<string, CallbackFunctions, string_hash> CallbackHooks;
 
 
   Hooks _hooks;
   Hooks _hooks;
   CallbackHooks _cbhooks;
   CallbackHooks _cbhooks;

+ 11 - 0
panda/src/express/pointerToBase.I

@@ -296,6 +296,17 @@ operator < (const PointerToBase<To> &other) const {
 
 
 #endif  // CPPPARSER
 #endif  // CPPPARSER
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToBase::get_hash
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class T>
+INLINE size_t PointerToBase<T>::
+get_hash() const {
+  return (size_t)_void_ptr;
+}
+
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/express/pointerToBase.h

@@ -74,6 +74,7 @@ public:
   INLINE bool operator < (const To *other) const;
   INLINE bool operator < (const To *other) const;
   INLINE bool operator < (const PointerToBase<To> &other) const;
   INLINE bool operator < (const PointerToBase<To> &other) const;
 #endif  // CPPPARSER
 #endif  // CPPPARSER
+  INLINE size_t get_hash() const;
 
 
 PUBLISHED:
 PUBLISHED:
   INLINE bool is_null() const;
   INLINE bool is_null() const;

+ 10 - 0
panda/src/express/typeHandle.I

@@ -117,6 +117,16 @@ compare_to(const TypeHandle &other) const {
   return _index - other._index;
   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
 //     Function: TypeHandle::get_name
 //       Access: Published
 //       Access: Published

+ 1 - 0
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 bool operator >= (const TypeHandle &other) const;
   INLINE bool operator >= (const TypeHandle &other) const;
   INLINE int compare_to(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 string get_name(TypedObject *object = (TypedObject *)NULL) const;
   INLINE bool is_derived_from(TypeHandle parent,
   INLINE bool is_derived_from(TypeHandle parent,

+ 1 - 1
panda/src/express/typeRegistry.h

@@ -100,7 +100,7 @@ private:
   typedef pvector<TypeRegistryNode *> HandleRegistry;
   typedef pvector<TypeRegistryNode *> HandleRegistry;
   HandleRegistry _handle_registry;
   HandleRegistry _handle_registry;
 
 
-  typedef pmap<string, TypeRegistryNode *> NameRegistry;
+  typedef phash_map<string, TypeRegistryNode *, string_hash> NameRegistry;
   NameRegistry _name_registry;
   NameRegistry _name_registry;
 
 
   typedef pvector<TypeRegistryNode *> RootClasses;
   typedef pvector<TypeRegistryNode *> RootClasses;

+ 1 - 1
panda/src/express/unicodeLatinMap.h

@@ -137,7 +137,7 @@ private:
   static void init();
   static void init();
   static bool _initialized;
   static bool _initialized;
 
 
-  typedef pmap<wchar_t, const Entry *> ByCharacter;
+  typedef phash_map<wchar_t, const Entry *, integer_hash<wchar_t> > ByCharacter;
   static ByCharacter _by_character;
   static ByCharacter _by_character;
   enum { max_direct_chars = 256 };
   enum { max_direct_chars = 256 };
   static const Entry *_direct_chars[max_direct_chars];
   static const Entry *_direct_chars[max_direct_chars];

+ 0 - 1
panda/src/express/virtualFileSystem.h

@@ -25,7 +25,6 @@
 #include "filename.h"
 #include "filename.h"
 #include "dSearchPath.h"
 #include "dSearchPath.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "pmap.h"
 #include "config_express.h"
 #include "config_express.h"
 
 
 class Multifile;
 class Multifile;

+ 2 - 0
panda/src/gobj/geom.h

@@ -274,6 +274,8 @@ protected:
     PTA_ushort _tindex;
     PTA_ushort _tindex;
   };
   };
 
 
+  // A pmap, not a phash_map, to save space because it will probably
+  // have only one element.
   typedef pmap<CPT(TexCoordName), TexCoordDef> TexCoordsByName;
   typedef pmap<CPT(TexCoordName), TexCoordDef> TexCoordsByName;
   TexCoordsByName _texcoords_by_name;
   TexCoordsByName _texcoords_by_name;
 
 

+ 1 - 2
panda/src/gobj/materialPool.h

@@ -23,7 +23,6 @@
 
 
 #include "material.h"
 #include "material.h"
 
 
-#include "indirectCompareTo.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 
 
 #include "pset.h"
 #include "pset.h"
@@ -63,7 +62,7 @@ private:
   static MaterialPool *get_ptr();
   static MaterialPool *get_ptr();
 
 
   static MaterialPool *_global_ptr;
   static MaterialPool *_global_ptr;
-  typedef pset< CPT(Material), IndirectCompareTo<Material> > Materials;
+  typedef pset< CPT(Material), indirect_compare_to<const Material *> > Materials;
   Materials _materials;
   Materials _materials;
 };
 };
 
 

+ 4 - 4
panda/src/gobj/preparedGraphicsObjects.h

@@ -71,10 +71,10 @@ public:
   void update(GraphicsStateGuardianBase *gsg);
   void update(GraphicsStateGuardianBase *gsg);
 
 
 private:
 private:
-  typedef pset<TextureContext *> Textures;
-  typedef pset< PT(Texture) > EnqueuedTextures;
-  typedef pset<GeomContext *> Geoms;
-  typedef pset< PT(Geom) > EnqueuedGeoms;
+  typedef phash_set<TextureContext *, pointer_hash> Textures;
+  typedef phash_set< PT(Texture) > EnqueuedTextures;
+  typedef phash_set<GeomContext *, pointer_hash> Geoms;
+  typedef phash_set< PT(Geom) > EnqueuedGeoms;
 
 
   Mutex _lock;
   Mutex _lock;
   Textures _prepared_textures, _released_textures;  
   Textures _prepared_textures, _released_textures;  

+ 1 - 1
panda/src/gobj/texCoordName.h

@@ -49,7 +49,7 @@ PUBLISHED:
 private:
 private:
   string _name;
   string _name;
 
 
-  typedef pmap<string, TexCoordName *> TexCoordsByName;
+  typedef phash_map<string, TexCoordName *, string_hash> TexCoordsByName;
   static TexCoordsByName _texcoords_by_name;
   static TexCoordsByName _texcoords_by_name;
 
 
   static CPT(TexCoordName) _default_name;
   static CPT(TexCoordName) _default_name;

+ 1 - 1
panda/src/gobj/texture.h

@@ -153,7 +153,7 @@ private:
   // Each PGO conversely keeps a list (a set) of all the Textures that
   // Each PGO conversely keeps a list (a set) of all the Textures that
   // have been prepared there.  When either destructs, it removes
   // have been prepared there.  When either destructs, it removes
   // itself from the other's list.
   // itself from the other's list.
-  typedef pmap<PreparedGraphicsObjects *, TextureContext *> Contexts;
+  typedef pmap<PreparedGraphicsObjects *, TextureContext *, pointer_hash> Contexts;
   Contexts _contexts;
   Contexts _contexts;
 
 
   // This value represents the intersection of all the dirty flags of
   // This value represents the intersection of all the dirty flags of

+ 1 - 1
panda/src/gobj/texturePool.h

@@ -78,7 +78,7 @@ private:
   static TexturePool *get_ptr();
   static TexturePool *get_ptr();
 
 
   static TexturePool *_global_ptr;
   static TexturePool *_global_ptr;
-  typedef pmap<string,  PT(Texture) > Textures;
+  typedef phash_map<string,  PT(Texture), string_hash> Textures;
   Textures _textures;
   Textures _textures;
   string _fake_texture_image;
   string _fake_texture_image;
 };
 };

+ 1 - 1
panda/src/lerp/lerpfunctor.h

@@ -196,7 +196,7 @@ typedef SimpleQueryLerpFunctor<LVector4f> LVector4fQueryLerpFunctor;
 
 
 class EXPCL_PANDA MultiLerpFunctor : public LerpFunctor {
 class EXPCL_PANDA MultiLerpFunctor : public LerpFunctor {
 private:
 private:
-  typedef pset< PT(LerpFunctor) > Functors;
+  typedef phash_set< PT(LerpFunctor) > Functors;
   Functors _funcs;
   Functors _funcs;
 public:
 public:
   MultiLerpFunctor(void) {}
   MultiLerpFunctor(void) {}

+ 4 - 4
panda/src/linmath/Sources.pp

@@ -9,7 +9,7 @@
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx    
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx    
 
 
   #define SOURCES \
   #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  \
      compose_matrix_src.cxx compose_matrix_src.h config_linmath.h  \
      coordinateSystem.h dbl2fltnames.h dblnames.h deg_2_rad.h  \
      coordinateSystem.h dbl2fltnames.h dblnames.h deg_2_rad.h  \
      flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I  \
      flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I  \
@@ -33,7 +33,7 @@
      lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.cxx  \
      lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.cxx  \
      lvector2_src.h lvector3.h lvector3_src.I lvector3_src.cxx  \
      lvector2_src.h lvector3.h lvector3_src.I lvector3_src.cxx  \
      lvector3_src.h lvector4.h lvector4_src.I lvector4_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  \
      pta_Normalf.h pta_TexCoordf.h pta_Vertexf.h vector_Colorf.h  \
      vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h  \
      vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h  \
      vector_TexCoordf.h vector_Vertexf.h
      vector_TexCoordf.h vector_Vertexf.h
@@ -50,7 +50,7 @@
      vector_LVecBase3f.cxx vector_Normalf.cxx vector_Vertexf.cxx  \
      vector_LVecBase3f.cxx vector_Normalf.cxx vector_Vertexf.cxx  \
 
 
   #define INSTALL_HEADERS \
   #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 \
     compose_matrix_src.h config_linmath.h coordinateSystem.h \
     dbl2fltnames.h dblnames.h deg_2_rad.h \
     dbl2fltnames.h dblnames.h deg_2_rad.h \
     flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I \
     flt2dblnames.h fltnames.h ioPtaDatagramLinMath.I \
@@ -68,7 +68,7 @@
     lvecBase3_src.I lvecBase3_src.h lvecBase4.h lvecBase4_src.I \
     lvecBase3_src.I lvecBase3_src.h lvecBase4.h lvecBase4_src.I \
     lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.h \
     lvecBase4_src.h lvector2.h lvector2_src.I lvector2_src.h \
     lvector3.h lvector3_src.I lvector3_src.h lvector4.h lvector4_src.I \
     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 \
     pta_Normalf.h pta_TexCoordf.h pta_Vertexf.h vector_Colorf.h \
     vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h \
     vector_LPoint2f.h vector_LVecBase3f.h vector_Normalf.h \
     vector_TexCoordf.h vector_Vertexf.h
     vector_TexCoordf.h vector_Vertexf.h

+ 54 - 0
panda/src/linmath/lmatrix3_src.I

@@ -399,6 +399,60 @@ compare_to(const FLOATNAME(LMatrix3) &other) const {
   return compare_to(other, NEARLY_ZERO(FLOATTYPE));
   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)                                              \
 #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._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;   \
 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;   \

+ 4 - 0
panda/src/linmath/lmatrix3_src.h

@@ -82,6 +82,10 @@ PUBLISHED:
 
 
   INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix3) &other) const;
   INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix3) &other) const;
   int compare_to(const FLOATNAME(LMatrix3) &other, FLOATTYPE threshold) 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)
   INLINE_LINMATH FLOATNAME(LVecBase3)
   xform(const FLOATNAME(LVecBase3) &v) const;
   xform(const FLOATNAME(LVecBase3) &v) const;

+ 62 - 0
panda/src/linmath/lmatrix4_src.I

@@ -551,6 +551,68 @@ compare_to(const FLOATNAME(LMatrix4) &other) const {
   return compare_to(other, NEARLY_ZERO(FLOATTYPE));
   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)       \
 #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._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;   \
 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;   \

+ 4 - 0
panda/src/linmath/lmatrix4_src.h

@@ -91,6 +91,10 @@ PUBLISHED:
 
 
   INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix4) &other) const;
   INLINE_LINMATH int compare_to(const FLOATNAME(LMatrix4) &other) const;
   int compare_to(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) 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)
   INLINE_LINMATH FLOATNAME(LVecBase4)
   xform(const FLOATNAME(LVecBase4) &v) const;
   xform(const FLOATNAME(LVecBase4) &v) const;

+ 1 - 0
panda/src/linmath/luse.h

@@ -64,6 +64,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#include "stl_compares.h"
 #include "lvec2_ops.h"
 #include "lvec2_ops.h"
 #include "lvec3_ops.h"
 #include "lvec3_ops.h"
 #include "lvec4_ops.h"
 #include "lvec4_ops.h"

+ 43 - 0
panda/src/linmath/lvecBase2_src.I

@@ -415,6 +415,49 @@ compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE threshold) const {
   return 0;
   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 -
 //     Function: LVecBase2::unary -
 //       Access: Public
 //       Access: Public

+ 4 - 1
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) const;
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase2) &other,
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase2) &other,
                                 FLOATTYPE threshold) const;
                                 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;
   INLINE_LINMATH FLOATNAME(LVecBase2) operator - () const;
 
 

+ 44 - 0
panda/src/linmath/lvecBase3_src.I

@@ -523,6 +523,50 @@ compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE threshold) const {
   return 0;
   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 -
 //     Function: LVecBase3::unary -
 //       Access: Public
 //       Access: Public

+ 4 - 0
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) const;
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase3) &other,
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase3) &other,
                                 FLOATTYPE threshold) const;
                                 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;
   INLINE_LINMATH FLOATNAME(LVecBase3) operator - () const;
 
 

+ 45 - 0
panda/src/linmath/lvecBase4_src.I

@@ -515,6 +515,51 @@ compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE threshold) const {
   return 0;
   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 -
 //     Function: LVecBase4::unary -
 //       Access: Public
 //       Access: Public

+ 4 - 0
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) const;
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase4) &other,
   INLINE_LINMATH int compare_to(const FLOATNAME(LVecBase4) &other,
                                 FLOATTYPE threshold) const;
                                 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;
   INLINE_LINMATH FLOATNAME(LVecBase4) operator - () const;
 
 

+ 3 - 3
panda/src/net/connectionManager.h

@@ -76,9 +76,9 @@ protected:
   void add_writer(ConnectionWriter *writer);
   void add_writer(ConnectionWriter *writer);
   void remove_writer(ConnectionWriter *writer);
   void remove_writer(ConnectionWriter *writer);
 
 
-  typedef pset< PT(Connection) > Connections;
-  typedef pset<ConnectionReader *> Readers;
-  typedef pset<ConnectionWriter *> Writers;
+  typedef phash_set< PT(Connection) > Connections;
+  typedef phash_set<ConnectionReader *, pointer_hash> Readers;
+  typedef phash_set<ConnectionWriter *, pointer_hash> Writers;
   Connections _connections;
   Connections _connections;
   Readers _readers;
   Readers _readers;
   Writers _writers;
   Writers _writers;

+ 1 - 1
panda/src/pgraph/cullResult.h

@@ -74,7 +74,7 @@ private:
   typedef pvector< PT(CullBin) > Bins;
   typedef pvector< PT(CullBin) > Bins;
   Bins _bins;
   Bins _bins;
 
 
-  typedef pset<CullResult *> CullResults;
+  typedef phash_set<CullResult *, pointer_hash> CullResults;
   static CullResults _cull_results;
   static CullResults _cull_results;
 };
 };
 
 

+ 2 - 2
panda/src/pgraph/nodePath.h

@@ -716,7 +716,7 @@ private:
                           CollideMask and_mask, CollideMask or_mask,
                           CollideMask and_mask, CollideMask or_mask,
                           TypeHandle node_type);
                           TypeHandle node_type);
 
 
-  typedef pset<Texture *> Textures;
+  typedef phash_set<Texture *, pointer_hash> Textures;
   Texture *r_find_texture(PandaNode *node, const RenderState *state,
   Texture *r_find_texture(PandaNode *node, const RenderState *state,
                           const GlobPattern &glob) const;
                           const GlobPattern &glob) const;
   void r_find_all_textures(PandaNode *node, const RenderState *state,
   void r_find_all_textures(PandaNode *node, const RenderState *state,
@@ -725,7 +725,7 @@ private:
   void r_find_all_textures(PandaNode *node, TextureStage *stage,
   void r_find_all_textures(PandaNode *node, TextureStage *stage,
                            Textures &textures) const;
                            Textures &textures) const;
 
 
-  typedef pset<TextureStage *> TextureStages;
+  typedef phash_set<TextureStage *, pointer_hash> TextureStages;
   TextureStage *r_find_texture_stage(PandaNode *node, const RenderState *state,
   TextureStage *r_find_texture_stage(PandaNode *node, const RenderState *state,
                                      const GlobPattern &glob) const;
                                      const GlobPattern &glob) const;
   void r_find_all_texture_stages(PandaNode *node, const RenderState *state,
   void r_find_all_texture_stages(PandaNode *node, const RenderState *state,

+ 2 - 2
panda/src/pgraph/pandaNode.h

@@ -280,11 +280,11 @@ private:
   // requested a NodePath for.  We don't keep reference counts; when
   // requested a NodePath for.  We don't keep reference counts; when
   // each NodePathComponent destructs, it removes itself from this
   // each NodePathComponent destructs, it removes itself from this
   // set.
   // set.
-  typedef pset<NodePathComponent *> Paths;
+  typedef phash_set<NodePathComponent *, pointer_hash> Paths;
 
 
   // This is used to maintain a table of keyed data on each node, for
   // This is used to maintain a table of keyed data on each node, for
   // the user's purposes.
   // the user's purposes.
-  typedef pmap<string, string> TagData;
+  typedef phash_map<string, string, string_hash> TagData;
 
 
   
   
   // This is the data that must be cycled between pipeline stages.
   // This is the data that must be cycled between pipeline stages.

+ 1 - 2
panda/src/pgraph/renderAttrib.h

@@ -22,7 +22,6 @@
 #include "pandabase.h"
 #include "pandabase.h"
 
 
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
-#include "indirectCompareTo.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 #include "pset.h"
 #include "pset.h"
 
 
@@ -105,7 +104,7 @@ protected:
   bool _always_reissue;
   bool _always_reissue;
 
 
 private:
 private:
-  typedef pset<const RenderAttrib *, IndirectCompareTo<RenderAttrib> > Attribs;
+  typedef pset<const RenderAttrib *, indirect_compare_to<const RenderAttrib *> > Attribs;
   static Attribs *_attribs;
   static Attribs *_attribs;
 
 
   Attribs::iterator _saved_entry;
   Attribs::iterator _saved_entry;

+ 1 - 2
panda/src/pgraph/renderEffect.h

@@ -25,7 +25,6 @@
 #include "renderState.h"
 #include "renderState.h"
 
 
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
-#include "indirectCompareTo.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 #include "pset.h"
 #include "pset.h"
 #include "luse.h"
 #include "luse.h"
@@ -92,7 +91,7 @@ protected:
   virtual int compare_to_impl(const RenderEffect *other) const;
   virtual int compare_to_impl(const RenderEffect *other) const;
 
 
 private:
 private:
-  typedef pset<const RenderEffect *, IndirectCompareTo<RenderEffect> > Effects;
+  typedef pset<const RenderEffect *, indirect_compare_to<const RenderEffect *> > Effects;
   static Effects *_effects;
   static Effects *_effects;
 
 
   Effects::iterator _saved_entry;
   Effects::iterator _saved_entry;

+ 1 - 2
panda/src/pgraph/renderEffects.h

@@ -27,7 +27,6 @@
 #include "renderEffect.h"
 #include "renderEffect.h"
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "indirectLess.h"
 #include "ordered_vector.h"
 #include "ordered_vector.h"
 
 
 class CullTraverser;
 class CullTraverser;
@@ -110,7 +109,7 @@ private:
   void determine_cull_callback();
   void determine_cull_callback();
 
 
 private:
 private:
-  typedef pset<const RenderEffects *, IndirectLess<RenderEffects> > States;
+  typedef pset<const RenderEffects *, indirect_less<const RenderEffects *> > States;
   static States *_states;
   static States *_states;
   static CPT(RenderEffects) _empty_state;
   static CPT(RenderEffects) _empty_state;
 
 

+ 2 - 3
panda/src/pgraph/renderState.h

@@ -24,7 +24,6 @@
 #include "renderAttrib.h"
 #include "renderAttrib.h"
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "indirectLess.h"
 #include "ordered_vector.h"
 #include "ordered_vector.h"
 
 
 class GraphicsStateGuardianBase;
 class GraphicsStateGuardianBase;
@@ -152,7 +151,7 @@ private:
   INLINE bool is_destructing() const;
   INLINE bool is_destructing() const;
 
 
 private:
 private:
-  typedef pset<const RenderState *, IndirectLess<RenderState> > States;
+  typedef pset<const RenderState *, indirect_less<const RenderState *> > States;
   static States *_states;
   static States *_states;
   static CPT(RenderState) _empty_state;
   static CPT(RenderState) _empty_state;
 
 
@@ -180,7 +179,7 @@ private:
   // is not reference counted within this map; instead we store a
   // is not reference counted within this map; instead we store a
   // companion pointer in the other object, and remove the references
   // companion pointer in the other object, and remove the references
   // explicitly when either object destructs.
   // explicitly when either object destructs.
-  typedef pmap<const RenderState *, Composition> CompositionCache;
+  typedef phash_map<const RenderState *, Composition, pointer_hash> CompositionCache;
   CompositionCache _composition_cache;
   CompositionCache _composition_cache;
   CompositionCache _invert_composition_cache;
   CompositionCache _invert_composition_cache;
 
 

+ 49 - 0
panda/src/pgraph/transformState.cxx

@@ -265,6 +265,55 @@ operator < (const TransformState &other) const {
   return (this < &other);
   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
 //     Function: TransformState::make_identity
 //       Access: Published, Static
 //       Access: Published, Static

+ 3 - 3
panda/src/pgraph/transformState.h

@@ -23,7 +23,6 @@
 
 
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "indirectLess.h"
 #include "luse.h"
 #include "luse.h"
 #include "pset.h"
 #include "pset.h"
 #include "event.h"
 #include "event.h"
@@ -66,6 +65,7 @@ public:
 
 
 PUBLISHED:
 PUBLISHED:
   bool operator < (const TransformState &other) const;
   bool operator < (const TransformState &other) const;
+  size_t get_hash() const;
 
 
   static CPT(TransformState) make_identity();
   static CPT(TransformState) make_identity();
   static CPT(TransformState) make_invalid();
   static CPT(TransformState) make_invalid();
@@ -159,7 +159,7 @@ private:
                               CompositionCycleDesc &cycle_desc);
                               CompositionCycleDesc &cycle_desc);
 
 
 private:
 private:
-  typedef pset<const TransformState *, IndirectLess<TransformState> > States;
+  typedef phash_set<const TransformState *, indirect_less_hash<const TransformState *> > States;
   static States *_states;
   static States *_states;
   static CPT(TransformState) _identity_state;
   static CPT(TransformState) _identity_state;
 
 
@@ -187,7 +187,7 @@ private:
   // is not reference counted within this map; instead we store a
   // is not reference counted within this map; instead we store a
   // companion pointer in the other object, and remove the references
   // companion pointer in the other object, and remove the references
   // explicitly when either object destructs.
   // explicitly when either object destructs.
-  typedef pmap<const TransformState *, Composition> CompositionCache;
+  typedef phash_map<const TransformState *, Composition, pointer_hash> CompositionCache;
   CompositionCache _composition_cache;
   CompositionCache _composition_cache;
   CompositionCache _invert_composition_cache;
   CompositionCache _invert_composition_cache;
 
 

+ 1 - 0
panda/src/pstatclient/pStatClient.h

@@ -125,6 +125,7 @@ private:
   // Stats collecting stuff
   // Stats collecting stuff
   ClockObject _clock;
   ClockObject _clock;
 
 
+  // Not a phash_map, so the threads remain sorted by name.
   typedef pmap<string, int> ThingsByName;
   typedef pmap<string, int> ThingsByName;
   ThingsByName _threads_by_name;
   ThingsByName _threads_by_name;
 
 

+ 8 - 8
panda/src/putil/bamReader.h

@@ -163,7 +163,7 @@ private:
 
 
   // This maps the type index numbers encountered within the Bam file
   // This maps the type index numbers encountered within the Bam file
   // to actual TypeHandles.
   // to actual TypeHandles.
-  typedef pmap<int, TypeHandle> IndexMap;
+  typedef phash_map<int, TypeHandle, int_hash> IndexMap;
   IndexMap _index_map;
   IndexMap _index_map;
 
 
   // This maps the object ID numbers encountered within the Bam file
   // This maps the object ID numbers encountered within the Bam file
@@ -173,7 +173,7 @@ private:
     TypedWritable *_ptr;
     TypedWritable *_ptr;
     ChangeThisFunc _change_this;
     ChangeThisFunc _change_this;
   };
   };
-  typedef pmap<int, CreatedObj> CreatedObjs;
+  typedef phash_map<int, CreatedObj, int_hash> CreatedObjs;
   CreatedObjs _created_objs;
   CreatedObjs _created_objs;
   // This is the iterator into the above map for the object we are
   // This is the iterator into the above map for the object we are
   // currently reading in p_read_object().  It is carefully maintained
   // 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,
   // 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
   // in the order in which read_pointer() was called, so that we may
   // call the appropriate complete_pointers() later.
   // call the appropriate complete_pointers() later.
-  typedef pmap<int, vector_int> ObjectPointers;
+  typedef phash_map<int, vector_int, int_hash> ObjectPointers;
   ObjectPointers _object_pointers;
   ObjectPointers _object_pointers;
 
 
   // Ditto, for the PiplineCycler objects.
   // Ditto, for the PiplineCycler objects.
-  typedef pmap<PipelineCyclerBase *, vector_int> CyclerPointers;
+  typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers;
   CyclerPointers _cycler_pointers;
   CyclerPointers _cycler_pointers;
 
 
   // This is the number of extra objects that must still be read (and
   // 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
   // This is the set of all objects that registered themselves for
   // finalization.
   // finalization.
-  typedef pset<TypedWritable *> Finalize;
+  typedef phash_set<TypedWritable *, pointer_hash> Finalize;
   Finalize _finalize_list;
   Finalize _finalize_list;
 
 
   // These are used by get_pta() and register_pta() to unify multiple
   // These are used by get_pta() and register_pta() to unify multiple
   // references to the same PointerToArray.
   // references to the same PointerToArray.
-  typedef pmap<int, void *> PTAMap;
+  typedef phash_map<int, void *, int_hash> PTAMap;
   PTAMap _pta_map;
   PTAMap _pta_map;
   int _pta_id;
   int _pta_id;
 
 
@@ -215,11 +215,11 @@ private:
   // on-the-fly to satisfy bam requirements.  We keep track of this
   // on-the-fly to satisfy bam requirements.  We keep track of this
   // just so we can suppress warning messages from attempts to create
   // just so we can suppress warning messages from attempts to create
   // objects of these types.
   // objects of these types.
-  typedef pset<TypeHandle> NewTypes;
+  typedef phash_set<TypeHandle> NewTypes;
   static NewTypes _new_types;
   static NewTypes _new_types;
 
 
   // This is used in support of set_aux_data() and get_aux_data().
   // This is used in support of set_aux_data() and get_aux_data().
-  typedef pmap<string, void *> AuxData;
+  typedef phash_map<string, void *, string_hash> AuxData;
   AuxData _aux_data;
   AuxData _aux_data;
 
 
   int _file_major, _file_minor;
   int _file_major, _file_minor;

+ 3 - 3
panda/src/putil/bamWriter.h

@@ -101,7 +101,7 @@ private:
   int enqueue_object(const TypedWritable *object);
   int enqueue_object(const TypedWritable *object);
 
 
   // This is the set of all TypeHandles already written.
   // This is the set of all TypeHandles already written.
-  pset<int> _types_written;
+  pset<int, int_hash> _types_written;
 
 
   // This keeps track of all of the objects we have written out
   // This keeps track of all of the objects we have written out
   // already (or are about to write out), and associates a unique
   // 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) {}
     StoreState(int object_id) : _object_id(object_id), _written(false) {}
   };
   };
-  typedef pmap<const TypedWritable *, StoreState> StateMap;
+  typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
   StateMap _state_map;
   StateMap _state_map;
 
 
   // This is the next object ID that will be assigned to a new object.
   // 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
   // These are used by register_pta() to unify multiple references to
   // the same PointerToArray.
   // the same PointerToArray.
-  typedef pmap<const void *, int> PTAMap;
+  typedef phash_map<const void *, int, pointer_hash> PTAMap;
   PTAMap _pta_map;
   PTAMap _pta_map;
   int _next_pta_id;
   int _next_pta_id;
   bool _long_pta_id;
   bool _long_pta_id;

+ 1 - 2
panda/src/putil/buttonRegistry.h

@@ -25,7 +25,6 @@
 
 
 #include "pvector.h"
 #include "pvector.h"
 #include "pmap.h"
 #include "pmap.h"
-#include <string>
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : ButtonRegistry
 //       Class : ButtonRegistry
@@ -72,7 +71,7 @@ private:
   typedef pvector<RegistryNode *> HandleRegistry;
   typedef pvector<RegistryNode *> HandleRegistry;
   HandleRegistry _handle_registry;
   HandleRegistry _handle_registry;
 
 
-  typedef pmap<string, RegistryNode *> NameRegistry;
+  typedef phash_map<string, RegistryNode *, string_hash> NameRegistry;
   NameRegistry _name_registry;
   NameRegistry _name_registry;
 
 
   static ButtonRegistry *_global_pointer;
   static ButtonRegistry *_global_pointer;

+ 1 - 1
panda/src/putil/globalPointerRegistry.h

@@ -79,7 +79,7 @@ private:
   static GlobalPointerRegistry *_global_ptr;
   static GlobalPointerRegistry *_global_ptr;
 
 
 private:
 private:
-  typedef pmap<TypeHandle, void *> Pointers;
+  typedef phash_map<TypeHandle, void *> Pointers;
   Pointers _pointers;
   Pointers _pointers;
 };
 };
 
 

+ 1 - 1
panda/src/putil/nameUniquifier.h

@@ -44,7 +44,7 @@ public:
 private:
 private:
   string add_name_body(const string &name, const string &prefix);
   string add_name_body(const string &name, const string &prefix);
 
 
-  typedef pset<string> Names;
+  typedef pset<string, string_hash> Names;
   Names _names;
   Names _names;
   string _separator;
   string _separator;
   string _empty;
   string _empty;

+ 5 - 0
panda/src/testbed/Sources.pp

@@ -41,3 +41,8 @@
   #define TARGET test_texmem
   #define TARGET test_texmem
   #define SOURCES test_texmem.cxx
   #define SOURCES test_texmem.cxx
 #end test_bin_target
 #end test_bin_target
+
+#begin test_bin_target
+  #define TARGET test_map
+  #define SOURCES test_map.cxx
+#end test_bin_target

+ 171 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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<Alpha, string> MapType;
+  //  typedef pmap<Beta, string> MapType;
+  //  typedef phash_map<Alpha, string> MapType;
+  typedef phash_map<Beta, string> 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<KeyType, int> MapType;
+  //typedef pmap<KeyType, int> 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<KeyType> 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;
+}