Patch from Scott McKellar:
authormiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 11 Apr 2008 14:42:31 +0000 (14:42 +0000)
committermiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 11 Apr 2008 14:42:31 +0000 (14:42 +0000)
This patch boosts the performance of an osrfHashIterator a bit, by
reusing the "current" buffer whenever possible instead of freeing and
reallocating it on every iteration.

I wrote a benchmark that repeatedly traverses a 27-item hash table.
The new version is about 10% faster.  This improvement is not as
dramatic as I had hoped for, but it's easy to get, and it won't hurt.

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1305 9efc2488-bf62-4759-914b-345cdb29e865

include/opensrf/osrf_hash.h
src/libopensrf/osrf_hash.c

index cb447dd..b7bc55b 100644 (file)
@@ -15,6 +15,7 @@ typedef struct _osrfHashStruct osrfHash;
 
 struct _osrfHashIteratorStruct {
        char* current;
+       size_t currsize;  // length of "current" buffer
        int currentIdx;
        osrfHash* hash;
        osrfStringArray* keys;
index 163d2ef..091089d 100644 (file)
@@ -227,6 +227,7 @@ osrfHashIterator* osrfNewHashIterator( osrfHash* hash ) {
        itr->hash = hash;
        itr->currentIdx = 0;
        itr->current = NULL;
+       itr->currsize = 0;
        itr->keys = osrfHashKeysInc(hash);
        return itr;
 }
@@ -234,8 +235,24 @@ osrfHashIterator* osrfNewHashIterator( osrfHash* hash ) {
 void* osrfHashIteratorNext( osrfHashIterator* itr ) {
        if(!(itr && itr->hash)) return NULL;
        if( itr->currentIdx >= itr->keys->size ) return NULL;
-       free(itr->current);
-       itr->current = strdup(osrfStringArrayGetString(itr->keys, itr->currentIdx++));
+
+       // Copy the string to iter->current
+       const char * curr = osrfStringArrayGetString(itr->keys, itr->currentIdx++);
+       size_t new_len = strlen(curr);
+       if( new_len >= itr->currsize ) {
+               // We need a bigger buffer
+
+               if(0 == itr->currsize) itr->currsize = 64; //default size
+               do {
+                       itr->currsize *= 2;
+               } while( new_len >= itr->currsize );
+
+               if(itr->current)
+                       free(itr->current);
+               itr->current = safe_malloc(itr->currsize);
+       }
+       strcpy(itr->current, curr);
+       
        char* val = osrfHashGet( itr->hash, itr->current );
        return val;
 }
@@ -248,10 +265,9 @@ void osrfHashIteratorFree( osrfHashIterator* itr ) {
 
 void osrfHashIteratorReset( osrfHashIterator* itr ) {
        if(!itr) return;
-       free(itr->current);
+       itr->current[0] = '\0';
        itr->keys = osrfHashKeysInc(itr->hash);
        itr->currentIdx = 0;
-       itr->current = NULL;
 }