Index: trunk/psLib/src/sysUtils/psHash.c
===================================================================
--- trunk/psLib/src/sysUtils/psHash.c	(revision 1041)
+++ trunk/psLib/src/sysUtils/psHash.c	(revision 1073)
@@ -10,6 +10,6 @@
  *  @author George Gusciora, MHPCC
  *   
- *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-10 00:09:55 $
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-23 23:00:15 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -18,4 +18,5 @@
 #include <stdio.h>
 #include <string.h>
+#include <stdbool.h>
 #include "psHash.h"
 #include "psMemory.h"
@@ -24,4 +25,9 @@
 #include "psAbort.h"
 
+static psHashBucket *hashBucketAlloc(const char *key,void *data,psHashBucket *next);
+static void hashBucketFree(psHashBucket *bucket);
+static void *doHashWork(psHash* table, const char* key, void* data, bool remove
+                           );
+static void hashFree(psHash *table);
 
 /******************************************************************************
@@ -87,4 +93,5 @@
     // Allocate memory for the new hash bucket.
     psHashBucket *bucket = psAlloc(sizeof(psHashBucket));
+    p_psMemSetDeallocator(bucket,(psFreeFcn)hashBucketFree);
 
     // Initialize the bucket.
@@ -105,20 +112,14 @@
 
 /******************************************************************************
-hashBucketFree(bucket, itemFree): This procedure deallocates the specified
-hash bucket.  If "itemFree" is NULL, then we simply free the data with the
-standard psFree() function.  If "itemFree" is not NULL, then it must be a
-function pointer which takes the hash bucket as a parameter, and frees the
-data in that hash bucket.
+hashBucketFree(bucket): This procedure deallocates the specified
+hash bucket.  
 Inputs:
     bucket: the hash bucket to be freed.
-    itemFree: a function pointer, possibly NULL.
 Return:
     NONE
  *****************************************************************************/
-static void hashBucketFree(psHashBucket *bucket,   // bucket to free
-                           void (*itemFree)(void *item)) // how to free data;
-{
-    if (bucket == NULL)
-    {
+static void hashBucketFree(psHashBucket *bucket)
+{
+    if (bucket == NULL) {
         return;
     }
@@ -126,21 +127,9 @@
     // A bucket is actually a linked list of buckets.  We recursively step
     // through that linked list, free each bucket.
-    if (bucket->next != NULL)
-    {
-        hashBucketFree(bucket, itemFree);
-    }
+    psFree(bucket->next);
 
     psFree(bucket->key);
-    psMemDecrRefCounter(bucket->data);
-
-    if (itemFree != NULL)
-    {
-        itemFree(bucket->data);
-    } else
-    {
-        psFree(bucket->data);
-    }
-
-    psFree(bucket);
+
+    psFree(bucket->data);
 }
 
@@ -159,4 +148,5 @@
     // Create the new hash table.
     psHash *table = psAlloc(sizeof(psHash));
+    p_psMemSetDeallocator(table,(psFreeFcn)hashFree);
 
     // Allocate memory for the buckets.
@@ -185,10 +175,8 @@
 Inputs:
     table: a hash table
-    itemFree: a function pointer, possibly NULL.
 Return:
     NONE
  *****************************************************************************/
-void psHashFree(psHash *table,  // hash table to be freed
-                void (*itemFree)(void *item)) // how to free hashed data; or NULL
+static void hashFree(psHash *table)
 {
     psHashBucket *tmp = NULL;           // Used to step through linked list.
@@ -196,6 +184,5 @@
     int i = 0;                          // Loop index variable.
 
-    if (table == NULL)
-    {
+    if (table == NULL) {
         return;
     }
@@ -204,6 +191,5 @@
     // NULL, then free the bucket via a function call to hashBucketFree();
 
-    for (i = 0; i < table->nbucket; i++)
-    {
+    for (i = 0; i < table->nbucket; i++) {
         // A bucket is composed of a linked list of buckets.  We use the
         // "tmp" and "ptr" pointers to step through that list and free each
@@ -214,5 +200,5 @@
             while (ptr != NULL) {
                 tmp = ptr->next;
-                hashBucketFree(ptr, itemFree);
+                psFree(ptr);
                 ptr = tmp;
             }
@@ -222,15 +208,13 @@
     // Free the bucket structure, then the hash table.
     psFree(table->buckets);
-    psFree(table);
-}
-
-/******************************************************************************
-doHashWork(table, key, data, remove, itemFree): This is an internal
+}
+
+/******************************************************************************
+doHashWork(table, key, data, remove): This is an internal
 procedure which does the bulk of the work in using the hash table.  Depending
 upon the input parameters, it will either insert a new key/data into the hash
 table, retrieve the data for a specified key, or remove a key/data item.  If
-we try to insert a key that already exists in the hash table, then we call
-the user-supplied function itemfree (or psFree if that is NULL), to free the
-existing data/key item.
+we try to insert a key that already exists in the hash table, then we deallocate
+the existing data/key item.
 Inputs:
     table: a hash table
@@ -238,5 +222,4 @@
     data: the data to insert, if not NULL
     remove: set to non-zero if the key/data should be removed from the table.
-    itemFree: function pointer
 Return:
     NONE
@@ -246,10 +229,6 @@
 there is little common code between those functions.
   *****************************************************************************/
-static void *doHashWork(psHash     *table,   // table to insert in
-                        const char *key,     // key to use
-                        void       *data,    // data to insert, or (if NULL) retrieve/remove
-                        int remove
-                            ,          // remove the item from the list?
-                            void (*itemFree)(void *item)) // how to free hashed data
+static void *doHashWork(psHash *table, const char *key, void *data, bool remove
+                           )
 {
     long int hash = 1;                  // This will contain an integer value
@@ -313,10 +292,9 @@
                     }
 
-                    psFree(ptr->key);
                     psFree(ptr);
 
                     // By definition, the data associated with that key
                     // must be returned, not freed.
-                    return psMemDecrRefCounter(data);
+                    return data;
                 }
                 optr = ptr;
@@ -354,9 +332,5 @@
                 // the new data was not inserted into the hash table.
 
-                if (itemFree == NULL) {
-                    psFree(psMemDecrRefCounter(ptr->data));
-                } else {
-                    itemFree(psMemDecrRefCounter(ptr->data));
-                }
+                psFree(ptr->data);
 
                 ptr->data = psMemIncrRefCounter(data);
@@ -385,8 +359,5 @@
     NONE
  *****************************************************************************/
-void *psHashInsert(psHash *table,   // table to insert in
-                   const char *key, // key to use
-                   void *data,      // data to insert
-                   void (*itemFree)(void *item)) // how to free hashed data;
+void *psHashInsert(psHash *table, const char *key, void *data)
 {
     if (table == NULL) {
@@ -400,5 +371,5 @@
     }
 
-    return doHashWork(table, key, data, 0, itemFree);
+    return doHashWork(table, key, data, 0);
 }
 
@@ -425,5 +396,5 @@
 
 
-    return doHashWork(table, key, NULL, 0, NULL);
+    return doHashWork(table, key, NULL, 0);
 }
 
@@ -438,7 +409,5 @@
     The data that was associated with that key.
  *****************************************************************************/
-void *psHashRemove(psHash *table,   // table to lookup key in
-                   const char *key, // key to lookup
-                   void (*itemFree)(void *item)) // how to free hashed data;
+void *psHashRemove(psHash *table, const char *key)
 {
     if (table == NULL) {
@@ -449,4 +418,4 @@
     }
 
-    return doHashWork(table, key, NULL, 1, itemFree);
-}
+    return doHashWork(table, key, NULL, 1);
+}
Index: trunk/psLib/src/sysUtils/psHash.d
===================================================================
--- trunk/psLib/src/sysUtils/psHash.d	(revision 1041)
+++ trunk/psLib/src/sysUtils/psHash.d	(revision 1073)
@@ -1,3 +1,3 @@
 psHash.o psHash.d : psHash.c psHash.h ../collections/psList.h \
-  ../collections/psVector.h ../collections/psType.h \
-  ../sysUtils/psMemory.h psString.h psTrace.h psAbort.h
+  ../collections/psVector.h ../collections/psType.h psMemory.h psString.h \
+  psTrace.h psAbort.h
Index: trunk/psLib/src/sysUtils/psHash.h
===================================================================
--- trunk/psLib/src/sysUtils/psHash.h	(revision 1041)
+++ trunk/psLib/src/sysUtils/psHash.h	(revision 1073)
@@ -10,6 +10,6 @@
  *  @author George Gusciora, MHPCC
  *   
- *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-12 05:50:01 $
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-23 23:00:15 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -45,25 +45,18 @@
                    );
 
-/// Free hash buckets from table.
-void psHashFree(psHash *table,               ///< hash table to be freed
-                void (*itemFree)(void *item) ///< how to free hashed data; or NULL
-               );
-
 /// Insert entry into table.
 void *psHashInsert(psHash *table,               ///< table to insert in
                    const char *key,             ///< key to use
-                   void *data,                  ///< data to insert
-                   void (*itemFree)(void *item) ///< how to free hashed data; or NULL
+                   void *data                   ///< data to insert
                   );
 
 /// Lookup key in table.
-void *psHashLookup(psHash *table, ///< table to lookup key in
-                   const char *key ///< key to lookup
+void *psHashLookup(psHash *table,      ///< table to lookup key in
+                   const char *key     ///< key to lookup
                   );
 
 /// Remove key from table.
-void *psHashRemove(psHash *table, ///< table to lookup key in
-                   const char *key, ///< key to lookup
-                   void (*itemFree)(void *item) ///< how to free hashed data; or NULL
+void *psHashRemove(psHash *table,      ///< table to lookup key in
+                   const char *key     ///< key to lookup
                   );
 
Index: trunk/psLib/src/sysUtils/psMemory.c
===================================================================
--- trunk/psLib/src/sysUtils/psMemory.c	(revision 1041)
+++ trunk/psLib/src/sysUtils/psMemory.c	(revision 1073)
@@ -8,6 +8,6 @@
  *  @author Robert Lupton, Princeton University
  *
- *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-04 23:46:48 $
+ *  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-23 23:00:15 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -30,6 +30,6 @@
 static int checkMemBlock(const psMemBlock *m, const char* funcName);
 static psMemBlock *lastMemBlockAllocated = NULL;
-pthread_mutex_t   memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t   memIdMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
 
 /**
@@ -96,5 +96,5 @@
 psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
 
-psMemoryId psMemAllocateCallbackSetID(psMemoryId id) // set p_psMemAllocateID to id
+psMemoryId psMemAllocateCallbackSetID(psMemoryId id)
 {
     psMemoryId old = p_psMemAllocateID;
@@ -104,5 +104,5 @@
 }
 
-psMemoryId psMemFreeCallbackSetID(psMemoryId id)  // set p_psMemFreeID to id
+psMemoryId psMemFreeCallbackSetID(psMemoryId id)
 {
     psMemoryId old = p_psMemFreeID;
@@ -184,7 +184,5 @@
 #define ALIGNED(P) ((void *)((long)(P) & ~03) == (P))
 
-static int
-checkMemBlock(const psMemBlock *m,
-              const char* funcName)
+static int checkMemBlock(const psMemBlock *m, const char* funcName)
 {
     // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
@@ -260,4 +258,5 @@
 
     ptr->file = file;
+    ptr->freeFcn = NULL;
     *(unsigned int*)&ptr->lineno = lineno;
     ptr->startblock = P_PS_MEMMAGIC;
@@ -346,7 +345,8 @@
     if (checkMemBlock(ptr, __func__) != 0) {
         memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it
-    }
-
-    psMemDecrRefCounter(vptr);          // this handles the free, if required.
+        return;
+    }
+
+    (void)psMemDecrRefCounter(vptr);   // this handles the free, if required.
 }
 
@@ -354,8 +354,5 @@
  * Check for memory leaks. Not production quality code
  */
-int psMemCheckLeaks(
-    psMemoryId id0,                     // don't list blocks with id < id0
-    psMemBlock ***arr,                  // pointer to array of pointers to leaked blocks, or NULL
-    FILE *fd)                           // print list of leaks to fd (or NULL)
+int psMemCheckLeaks(psMemoryId id0,psMemBlock ***arr,FILE *fd)
 {
     int nleak = 0;
@@ -365,6 +362,5 @@
     pthread_mutex_lock(&memBlockListMutex);
 
-    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
-    {
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
             nleak++;
@@ -382,6 +378,5 @@
     pthread_mutex_unlock(&memBlockListMutex);
 
-    if (nleak == 0 || arr == NULL)
-    {
+    if (nleak == 0 || arr == NULL) {
         return nleak;
     }
@@ -390,6 +385,5 @@
     pthread_mutex_lock(&memBlockListMutex);
 
-    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock)
-    {
+    for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
             (*arr)[j++] = iter;
@@ -408,11 +402,11 @@
  * Reference counting APIs
  */
-psReferenceCount psMemGetRefCounter(void *vptr) // return refCounter
+// return refCounter
+psReferenceCount psMemGetRefCounter(void *vptr)
 {
     psMemBlock *ptr;
     unsigned int refCount;
 
-    if (vptr == NULL)
-    {
+    if (vptr == NULL) {
         return 0;
     }
@@ -420,6 +414,5 @@
     ptr = ((psMemBlock *)vptr) - 1;
 
-    if (checkMemBlock(ptr, __func__) != 0)
-    {
+    if (checkMemBlock(ptr, __func__) != 0) {
         memProblemCallback(ptr, __func__, __LINE__);
     }
@@ -431,11 +424,10 @@
     return refCount;
 }
-
-void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
+// increment and return refCounter
+void *psMemIncrRefCounter(void *vptr)
 {
     psMemBlock *ptr;
 
-    if (vptr == NULL)
-    {
+    if (vptr == NULL) {
         return vptr;
     }
@@ -443,6 +435,5 @@
     ptr = ((psMemBlock *)vptr) - 1;
 
-    if (checkMemBlock(ptr, __func__))
-    {
+    if (checkMemBlock(ptr, __func__)) {
         memProblemCallback(ptr, __func__, __LINE__);
     }
@@ -455,8 +446,8 @@
 }
 
-void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
-{
-    if (vptr == NULL)
-    {
+// decrement and return refCounter
+void *psMemDecrRefCounter(void *vptr)
+{
+    if (vptr == NULL) {
         return NULL;
     }
@@ -467,12 +458,10 @@
     pthread_mutex_lock(&ptr->refCounterMutex);
 
-    if (ptr->refCounter > 1)
-    {
+    if (ptr->refCounter > 1) {
         /// XXX - Probably should have another mutex here.
         ptr->refCounter--;          // multiple references, just decrement the count.
         pthread_mutex_unlock(&ptr->refCounterMutex);
 
-    } else
-    {
+    } else {
         pthread_mutex_unlock(&ptr->refCounterMutex);
 
@@ -482,4 +471,8 @@
         }
 
+        if (ptr->freeFcn != NULL) {
+            ptr->freeFcn(vptr);
+        }
+
         pthread_mutex_lock(&memBlockListMutex);
 
@@ -507,15 +500,23 @@
 }
 
-void p_psCustomFree(psFreeFcn fcn, void* ptr)
-{
-
-    if (fcn == NULL) {
+void p_psMemSetDeallocator(void* vptr, psFreeFcn freeFcn)
+{
+    if (vptr == NULL) {
         return;
-    } else {
-        if (fcn == PS_FREE) {
-            psFree(ptr);
-        } else {
-            fcn(ptr);
-        }
-    }
-}
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+    ptr->freeFcn = freeFcn;
+
+}
+psFreeFcn p_psMemGetDeallocator(void* vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
+
+    return ptr->freeFcn;
+}
Index: trunk/psLib/src/sysUtils/psMemory.h
===================================================================
--- trunk/psLib/src/sysUtils/psMemory.h	(revision 1041)
+++ trunk/psLib/src/sysUtils/psMemory.h	(revision 1073)
@@ -14,6 +14,6 @@
  *  @ingroup MemoryManagement
  *
- *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-10 02:09:57 $
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-06-23 23:00:15 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -50,4 +50,7 @@
 /// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
 typedef unsigned long psReferenceCount;
+
+/// typedef for deallocator.
+typedef void (*psFreeFcn)(void* ptr);
 
 /** Book-keeping data for storage allocator.
@@ -58,14 +61,15 @@
 typedef struct psMemBlock
 {
-    const void* startblock;             ///< initialised to p_psMEMMAGIC
-    struct psMemBlock* previousBlock;   ///< previous block in allocation list
-    struct psMemBlock* nextBlock;       ///< next block allocation list
-    size_t  userMemorySize;             ///< the size of the user-portion of the memory block
-    const psMemoryId id;                ///< a unique ID for this allocation
-    const char* file;                   ///< set from __FILE__ in e.g. p_psAlloc
-    const int lineno;                   ///< set from __LINE__ in e.g. p_psAlloc
-    pthread_mutex_t   refCounterMutex;  ///< mutex to ensure exclusive access to reference counter
-    psReferenceCount refCounter;        ///< how many times pointer is referenced
-    const void* endblock;               ///< initialised to p_psMEMMAGIC
+    const void* startblock;            ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;  ///< previous block in allocation list
+    struct psMemBlock* nextBlock;      ///< next block allocation list
+    psFreeFcn freeFcn;                 ///< deallocator.  If NULL, use generic deallocation.
+    size_t  userMemorySize;            ///< the size of the user-portion of the memory block
+    const psMemoryId id;               ///< a unique ID for this allocation
+    const char* file;                  ///< set from __FILE__ in e.g. p_psAlloc
+    const int lineno;                  ///< set from __LINE__ in e.g. p_psAlloc
+    pthread_mutex_t   refCounterMutex; ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;       ///< how many times pointer is referenced
+    const void* endblock;              ///< initialised to p_psMEMMAGIC
 }
 psMemBlock;
@@ -114,10 +118,8 @@
 );
 
-typedef void (*psFreeFcn)(void* ptr);
-
 /** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
  *
  *  @return void* pointer to the allocated buffer. This will not be NULL.
- *  @see psFree
+ *  @see psFree 
  */
 #ifdef DOXYGEN
@@ -131,4 +133,8 @@
     int lineno                      ///< Line number of call
 );
+
+void p_psMemSetDeallocator(void* ptr, psFreeFcn freeFcn);
+psFreeFcn p_psMemGetDeallocator(void* ptr);
+
 /// Memory allocation. psAlloc sends file and line number to p_psAlloc.
 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
@@ -282,12 +288,7 @@
 );
 
-#define PS_FREE     (void*)1
-
 //@} End of Memory Management Functions
 
-
 #ifndef DOXYGEN
-
-void p_psCustomFree(psFreeFcn fcn,void* ptr);
 
 /*
