diff PrivateHash.c @ 14:5b89d57e5d10

added .brch__VMS__malloc_brch which has purpose of the brch
author Me@portablequad
date Sat, 11 Feb 2012 17:55:51 -0800
parents 7c4d2bf121a9
children 774396bc53b4
line diff
     1.1 --- a/PrivateHash.c	Thu Feb 09 15:51:22 2012 +0100
     1.2 +++ b/PrivateHash.c	Sat Feb 11 17:55:51 2012 -0800
     1.3 @@ -1,249 +1,242 @@
     1.4 -/*
     1.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
     1.6 - *  Licensed under GNU General Public License version 2
     1.7 - *
     1.8 - *
     1.9 - * Author: seanhalle@yahoo.com
    1.10 - */
    1.11 -
    1.12 -
    1.13 -#include <stdio.h>
    1.14 -#include <string.h>
    1.15 -#include <errno.h>
    1.16 -#include <stdlib.h>
    1.17 -
    1.18 -#include "PrivateHash.h"
    1.19 -#include "../vmalloc.h"
    1.20 -
    1.21 -
    1.22 - HashTable *
    1.23 -makeHashTable( int numHashSlots, FreeEntryContentFnPtr freeFn )
    1.24 - { HashTable * retTable;
    1.25 -   retTable = VMS__malloc( sizeof( HashTable ) );
    1.26 -
    1.27 -   retTable->freeEntryContentFn = freeFn;
    1.28 -   
    1.29 -   retTable->entries    = VMS__malloc( numHashSlots * sizeof(HashEntry *) );
    1.30 -   retTable->numEntries = 0;
    1.31 -   retTable->tableSz    = numHashSlots;
    1.32 -
    1.33 -   nullOutTablesArray( retTable );
    1.34 -
    1.35 -   return retTable;
    1.36 - }
    1.37 -
    1.38 - void
    1.39 -doubleTableSize( HashTable *table )
    1.40 - { int i, oldTableSz, newTableSz;
    1.41 -   HashEntry *entry, *nextEntry, **oldEntries, **newEntries;
    1.42 -
    1.43 -   oldTableSz = table->tableSz;
    1.44 -   oldEntries = table->entries;
    1.45 -
    1.46 -   newTableSz = 2 * oldTableSz + 1;
    1.47 -   newEntries = VMS__malloc( newTableSz * sizeof(HashEntry *) );
    1.48 -
    1.49 -   table->tableSz    = newTableSz;
    1.50 -   table->entries    = newEntries;
    1.51 -   table->numEntries = 0; //about to add them all back!
    1.52 -
    1.53 -      // move all the entries from old to new
    1.54 -   for( i=0; i < oldTableSz; i++ )
    1.55 -    { if( oldEntries[i] != NULL )
    1.56 -       { entry = oldEntries[i];
    1.57 -         while( entry != NULL )
    1.58 -          { nextEntry = entry->next;
    1.59 -            entry->next = NULL;
    1.60 -            putEntryIntoTable( entry, table ); //does not allocate anything
    1.61 -            entry = nextEntry;
    1.62 -          }
    1.63 -       }
    1.64 -    }
    1.65 - }
    1.66 -
    1.67 -void
    1.68 -nullOutTablesArray( HashTable *table )
    1.69 - { int i, tableSz;
    1.70 -   tableSz = table->tableSz;
    1.71 -   HashEntry ** entries = table->entries;
    1.72 -   for( i = 0; i < tableSz; i++ )
    1.73 -      entries[ i ] = NULL;
    1.74 - }
    1.75 -
    1.76 -unsigned int
    1.77 -hashThisKey( char* s, int hashSz )
    1.78 - { unsigned int h = 0;
    1.79 -   unsigned int i;
    1.80 -   hashkey_t* key = (hashkey_t*)s;
    1.81 -
    1.82 -   for(i=0 ; i<sizeof(hashkey_t); i++ )
    1.83 -      h = key->hashable[i] + h*31;
    1.84 -   return h % hashSz;
    1.85 - }
    1.86 -
    1.87 -/*Need this to be separated out, for use in both getParam and putParam
    1.88 - */
    1.89 -HashEntry *
    1.90 -getEntryFromTable( char *key, HashTable * table )
    1.91 - {  unsigned int
    1.92 -   hashIndex = hashThisKey( key, table->tableSz );
    1.93 -    HashEntry*
    1.94 -   hashEntry = table->entries[ hashIndex ];
    1.95 -   for( ; hashEntry != NULL; hashEntry = hashEntry->next )
    1.96 -    {
    1.97 -       if( memcmp( hashEntry->key, key, sizeof(hashkey_t) ) == 0 )
    1.98 -           return hashEntry;
    1.99 -    }
   1.100 -   return NULL;
   1.101 - }
   1.102 -
   1.103 -void *
   1.104 -getValueFromTable( char *key, HashTable * table )
   1.105 - { HashEntry *entry;
   1.106 -   entry = getEntryFromTable( key, table );
   1.107 -   if( entry == NULL ) return NULL;
   1.108 -
   1.109 -   return entry->content;
   1.110 - }
   1.111 -
   1.112 -
   1.113 -/*If key already has a value, clobber the old one and replace it
   1.114 - */
   1.115 - int
   1.116 -addValueIntoTable( char* key, void *content, HashTable *table )
   1.117 - { unsigned int hashIdx;
   1.118 -   HashEntry* hashEntry;
   1.119 -
   1.120 -   hashEntry = getEntryFromTable( key, table );
   1.121 -   if( hashEntry == NULL )
   1.122 -    { hashIdx = hashThisKey( key, table->tableSz );
   1.123 -      hashEntry = (HashEntry*) VMS__malloc( sizeof( HashEntry ) );
   1.124 -            if( hashEntry == NULL )  return 0;
   1.125 -      hashEntry->key = VMS__malloc( sizeof(hashkey_t) );
   1.126 -            if( hashEntry->key == NULL ) return 0;
   1.127 -      memcpy( hashEntry->key, key, sizeof(hashkey_t) );
   1.128 -      hashEntry->next = (table->entries)[hashIdx];
   1.129 -      (table->entries)[hashIdx] = hashEntry;
   1.130 -      table->numEntries += 1;
   1.131 -      if( table->tableSz < table->numEntries ) doubleTableSize( table );
   1.132 -    }
   1.133 -   else
   1.134 -    { (*(table->freeEntryContentFn))( hashEntry->content );
   1.135 -    }
   1.136 -   hashEntry->content = content;
   1.137 -   return 1;
   1.138 - }
   1.139 -
   1.140 - int
   1.141 -putEntryIntoTable( HashEntry *entry, HashTable *table )
   1.142 - { unsigned int hashIdx;
   1.143 -   HashEntry* testEntry;
   1.144 -
   1.145 -   testEntry = getEntryFromTable( entry->key, table );
   1.146 -   if( testEntry == NULL )
   1.147 -    { hashIdx = hashThisKey( entry->key, table->tableSz );
   1.148 -      entry->next = (table->entries)[hashIdx];
   1.149 -      (table->entries)[hashIdx] = entry;
   1.150 -      table->numEntries += 1;
   1.151 -      if( table->tableSz < table->numEntries ) doubleTableSize( table );
   1.152 -    }
   1.153 -   else
   1.154 -    { (*(table->freeEntryContentFn))( testEntry->content );
   1.155 -         //being lazy -- will create bug in code that relies on having ptr to
   1.156 -         // elem given to insert into table!
   1.157 -      testEntry->content = entry->content;
   1.158 -      entry->content = NULL;
   1.159 -      freeHashEntryButNotContent( entry );
   1.160 -    }
   1.161 -   return 1;
   1.162 - }
   1.163 -
   1.164 -/*Better version
   1.165 - */
   1.166 - void
   1.167 -untested_putEntryIntoTable( HashEntry *entry, HashTable * table )
   1.168 - { HashEntry *testEntry, *prevEntry = NULL;
   1.169 -    unsigned int
   1.170 -   hashIndex = hashThisKey( entry->key, table->tableSz );
   1.171 -   
   1.172 -   testEntry = table->entries[ hashIndex ];
   1.173 -   for( ; testEntry != NULL; testEntry = testEntry->next )
   1.174 -    { if( memcmp( testEntry->key, entry->key, sizeof(hashkey_t)) == 0 )
   1.175 -       { if( prevEntry == NULL )
   1.176 -          { table->entries[hashIndex] = entry;
   1.177 -            entry->next = testEntry->next;
   1.178 -          }
   1.179 -         else
   1.180 -          { prevEntry->next = entry;
   1.181 -            entry->next = testEntry->next;
   1.182 -          }
   1.183 -         freeHashEntryUsing( testEntry, table ); //frees content too!
   1.184 -         return;
   1.185 -       }
   1.186 -    }
   1.187 -      //wasn't found, so insert
   1.188 -   entry->next = table->entries[hashIndex];
   1.189 -   table->entries[hashIndex] = entry;
   1.190 - }
   1.191 -
   1.192 -
   1.193 -
   1.194 - bool8
   1.195 -deleteEntryFromTable( char *key, HashTable *table )
   1.196 - { HashEntry  *hashEntry;
   1.197 -   HashEntry **addrOfHashEntryPtr;
   1.198 -   unsigned int hashIndex;
   1.199 -
   1.200 -   hashIndex = hashThisKey( key, table->tableSz );
   1.201 -   addrOfHashEntryPtr = &( table->entries[ hashIndex ] );
   1.202 -   hashEntry = *addrOfHashEntryPtr;
   1.203 -   while( hashEntry != NULL )
   1.204 -    { if( memcmp( hashEntry->key, key, sizeof(hashkey_t) ) == 0 )
   1.205 -       {
   1.206 -         *addrOfHashEntryPtr = hashEntry->next;
   1.207 -         //TODO: Free the contents of entry?
   1.208 -         freeHashEntryButNotContent( hashEntry );
   1.209 -         table->numEntries -= 1;
   1.210 -         return TRUE;
   1.211 -       }
   1.212 -      addrOfHashEntryPtr = &( hashEntry->next );
   1.213 -      hashEntry = *addrOfHashEntryPtr;
   1.214 -    }
   1.215 -   return FALSE;
   1.216 - }
   1.217 - 
   1.218 -void
   1.219 -freeHashTable( HashTable *table )
   1.220 - { int i;
   1.221 -   HashEntry *hashEntry, *temp, **entries;
   1.222 -
   1.223 -   entries = table->entries;
   1.224 -   for( i=0; i < table->tableSz; i++ )
   1.225 -    { if( entries[i] != NULL )
   1.226 -       { hashEntry = entries[i];
   1.227 -         while( hashEntry != NULL )
   1.228 -          {
   1.229 -            temp = hashEntry->next;
   1.230 -            freeHashEntryUsing( hashEntry, table );
   1.231 -            hashEntry = temp;
   1.232 -          }
   1.233 -       }
   1.234 -    }
   1.235 - }
   1.236 -
   1.237 -void
   1.238 -freeHashEntryUsing( HashEntry *entry, HashTable *table )
   1.239 - {
   1.240 -   if( entry->content != NULL )
   1.241 -      (*(table->freeEntryContentFn))( entry->content );
   1.242 -   VMS__free( entry->key ); //was VMS__malloc'd above, so free it
   1.243 -   VMS__free( entry );
   1.244 - }
   1.245 -
   1.246 -void
   1.247 -freeHashEntryButNotContent( HashEntry *entry )
   1.248 - {
   1.249 -   VMS__free( entry->key ); //was VMS__malloc'd above, so free it
   1.250 -   VMS__free( entry );
   1.251 - }
   1.252 -
   1.253 +/*
   1.254 + *  Copyright 2009 OpenSourceStewardshipFoundation.org
   1.255 + *  Licensed under GNU General Public License version 2
   1.256 + *
   1.257 + *
   1.258 + * Author: seanhalle@yahoo.com
   1.259 + */
   1.260 +
   1.261 +#include "PrivateHash.h"
   1.262 +
   1.263 +
   1.264 + HashTable *
   1.265 +makeHashTable( int numHashSlots, FreeEntryContentFnPtr freeFn )
   1.266 + { HashTable * retTable;
   1.267 +   retTable = VMS__malloc( sizeof( HashTable ) );
   1.268 +
   1.269 +   retTable->freeEntryContentFn = freeFn;
   1.270 +   
   1.271 +   retTable->entries    = VMS__malloc( numHashSlots * sizeof(HashEntry *) );
   1.272 +   retTable->numEntries = 0;
   1.273 +   retTable->tableSz    = numHashSlots;
   1.274 +
   1.275 +   nullOutTablesArray( retTable );
   1.276 +
   1.277 +   return retTable;
   1.278 + }
   1.279 +
   1.280 + void
   1.281 +doubleTableSize( HashTable *table )
   1.282 + { int i, oldTableSz, newTableSz;
   1.283 +   HashEntry *entry, *nextEntry, **oldEntries, **newEntries;
   1.284 +
   1.285 +   oldTableSz = table->tableSz;
   1.286 +   oldEntries = table->entries;
   1.287 +
   1.288 +   newTableSz = 2 * oldTableSz + 1;
   1.289 +   newEntries = VMS__malloc( newTableSz * sizeof(HashEntry *) );
   1.290 +
   1.291 +   table->tableSz    = newTableSz;
   1.292 +   table->entries    = newEntries;
   1.293 +   table->numEntries = 0; //about to add them all back!
   1.294 +
   1.295 +      // move all the entries from old to new
   1.296 +   for( i=0; i < oldTableSz; i++ )
   1.297 +    { if( oldEntries[i] != NULL )
   1.298 +       { entry = oldEntries[i];
   1.299 +         while( entry != NULL )
   1.300 +          { nextEntry = entry->next;
   1.301 +            entry->next = NULL;
   1.302 +            putEntryIntoTable( entry, table ); //does not allocate anything
   1.303 +            entry = nextEntry;
   1.304 +          }
   1.305 +       }
   1.306 +    }
   1.307 + }
   1.308 +
   1.309 +void
   1.310 +nullOutTablesArray( HashTable *table )
   1.311 + { int i, tableSz;
   1.312 +   tableSz = table->tableSz;
   1.313 +   HashEntry ** entries = table->entries;
   1.314 +   for( i = 0; i < tableSz; i++ )
   1.315 +      entries[ i ] = NULL;
   1.316 + }
   1.317 +
   1.318 +unsigned int
   1.319 +hashThisKey( char* s, int hashSz )
   1.320 + { unsigned int h = 0;
   1.321 +   unsigned int i;
   1.322 +   hashkey_t* key = (hashkey_t*)s;
   1.323 +
   1.324 +   for(i=0 ; i<sizeof(hashkey_t); i++ )
   1.325 +      h = key->hashable[i] + h*31;
   1.326 +   return h % hashSz;
   1.327 + }
   1.328 +
   1.329 +/*Need this to be separated out, for use in both getParam and putParam
   1.330 + */
   1.331 +HashEntry *
   1.332 +getEntryFromTable( char *key, HashTable * table )
   1.333 + {  unsigned int
   1.334 +   hashIndex = hashThisKey( key, table->tableSz );
   1.335 +    HashEntry*
   1.336 +   hashEntry = table->entries[ hashIndex ];
   1.337 +   for( ; hashEntry != NULL; hashEntry = hashEntry->next )
   1.338 +    {
   1.339 +       if( memcmp( hashEntry->key, key, sizeof(hashkey_t) ) == 0 )
   1.340 +           return hashEntry;
   1.341 +    }
   1.342 +   return NULL;
   1.343 + }
   1.344 +
   1.345 +void *
   1.346 +getValueFromTable( char *key, HashTable * table )
   1.347 + { HashEntry *entry;
   1.348 +   entry = getEntryFromTable( key, table );
   1.349 +   if( entry == NULL ) return NULL;
   1.350 +
   1.351 +   return entry->content;
   1.352 + }
   1.353 +
   1.354 +
   1.355 +/*If key already has a value, clobber the old one and replace it
   1.356 + */
   1.357 + int
   1.358 +addValueIntoTable( char* key, void *content, HashTable *table )
   1.359 + { unsigned int hashIdx;
   1.360 +   HashEntry* hashEntry;
   1.361 +
   1.362 +   hashEntry = getEntryFromTable( key, table );
   1.363 +   if( hashEntry == NULL )
   1.364 +    { hashIdx = hashThisKey( key, table->tableSz );
   1.365 +      hashEntry = (HashEntry*) VMS__malloc( sizeof( HashEntry ) );
   1.366 +            if( hashEntry == NULL )  return 0;
   1.367 +      hashEntry->key = VMS__malloc( sizeof(hashkey_t) );
   1.368 +            if( hashEntry->key == NULL ) return 0;
   1.369 +      memcpy( hashEntry->key, key, sizeof(hashkey_t) );
   1.370 +      hashEntry->next = (table->entries)[hashIdx];
   1.371 +      (table->entries)[hashIdx] = hashEntry;
   1.372 +      table->numEntries += 1;
   1.373 +      if( table->tableSz < table->numEntries ) doubleTableSize( table );
   1.374 +    }
   1.375 +   else
   1.376 +    { (*(table->freeEntryContentFn))( hashEntry->content );
   1.377 +    }
   1.378 +   hashEntry->content = content;
   1.379 +   return 1;
   1.380 + }
   1.381 +
   1.382 + int
   1.383 +putEntryIntoTable( HashEntry *entry, HashTable *table )
   1.384 + { unsigned int hashIdx;
   1.385 +   HashEntry* testEntry;
   1.386 +
   1.387 +   testEntry = getEntryFromTable( entry->key, table );
   1.388 +   if( testEntry == NULL )
   1.389 +    { hashIdx = hashThisKey( entry->key, table->tableSz );
   1.390 +      entry->next = (table->entries)[hashIdx];
   1.391 +      (table->entries)[hashIdx] = entry;
   1.392 +      table->numEntries += 1;
   1.393 +      if( table->tableSz < table->numEntries ) doubleTableSize( table );
   1.394 +    }
   1.395 +   else
   1.396 +    { (*(table->freeEntryContentFn))( testEntry->content );
   1.397 +         //being lazy -- will create bug in code that relies on having ptr to
   1.398 +         // elem given to insert into table!
   1.399 +      testEntry->content = entry->content;
   1.400 +      entry->content = NULL;
   1.401 +      freeHashEntryButNotContent( entry );
   1.402 +    }
   1.403 +   return 1;
   1.404 + }
   1.405 +
   1.406 +/*Better version
   1.407 + */
   1.408 + void
   1.409 +untested_putEntryIntoTable( HashEntry *entry, HashTable * table )
   1.410 + { HashEntry *testEntry, *prevEntry = NULL;
   1.411 +    unsigned int
   1.412 +   hashIndex = hashThisKey( entry->key, table->tableSz );
   1.413 +   
   1.414 +   testEntry = table->entries[ hashIndex ];
   1.415 +   for( ; testEntry != NULL; testEntry = testEntry->next )
   1.416 +    { if( memcmp( testEntry->key, entry->key, sizeof(hashkey_t)) == 0 )
   1.417 +       { if( prevEntry == NULL )
   1.418 +          { table->entries[hashIndex] = entry;
   1.419 +            entry->next = testEntry->next;
   1.420 +          }
   1.421 +         else
   1.422 +          { prevEntry->next = entry;
   1.423 +            entry->next = testEntry->next;
   1.424 +          }
   1.425 +         freeHashEntryUsing( testEntry, table ); //frees content too!
   1.426 +         return;
   1.427 +       }
   1.428 +    }
   1.429 +      //wasn't found, so insert
   1.430 +   entry->next = table->entries[hashIndex];
   1.431 +   table->entries[hashIndex] = entry;
   1.432 + }
   1.433 +
   1.434 +
   1.435 +
   1.436 + bool8
   1.437 +deleteEntryFromTable( char *key, HashTable *table )
   1.438 + { HashEntry  *hashEntry;
   1.439 +   HashEntry **addrOfHashEntryPtr;
   1.440 +   unsigned int hashIndex;
   1.441 +
   1.442 +   hashIndex = hashThisKey( key, table->tableSz );
   1.443 +   addrOfHashEntryPtr = &( table->entries[ hashIndex ] );
   1.444 +   hashEntry = *addrOfHashEntryPtr;
   1.445 +   while( hashEntry != NULL )
   1.446 +    { if( memcmp( hashEntry->key, key, sizeof(hashkey_t) ) == 0 )
   1.447 +       {
   1.448 +         *addrOfHashEntryPtr = hashEntry->next;
   1.449 +         //TODO: Free the contents of entry?
   1.450 +         freeHashEntryButNotContent( hashEntry );
   1.451 +         table->numEntries -= 1;
   1.452 +         return TRUE;
   1.453 +       }
   1.454 +      addrOfHashEntryPtr = &( hashEntry->next );
   1.455 +      hashEntry = *addrOfHashEntryPtr;
   1.456 +    }
   1.457 +   return FALSE;
   1.458 + }
   1.459 + 
   1.460 +void
   1.461 +freeHashTable( HashTable *table )
   1.462 + { int i;
   1.463 +   HashEntry *hashEntry, *temp, **entries;
   1.464 +
   1.465 +   entries = table->entries;
   1.466 +   for( i=0; i < table->tableSz; i++ )
   1.467 +    { if( entries[i] != NULL )
   1.468 +       { hashEntry = entries[i];
   1.469 +         while( hashEntry != NULL )
   1.470 +          {
   1.471 +            temp = hashEntry->next;
   1.472 +            freeHashEntryUsing( hashEntry, table );
   1.473 +            hashEntry = temp;
   1.474 +          }
   1.475 +       }
   1.476 +    }
   1.477 + }
   1.478 +
   1.479 +void
   1.480 +freeHashEntryUsing( HashEntry *entry, HashTable *table )
   1.481 + {
   1.482 +   if( entry->content != NULL )
   1.483 +      (*(table->freeEntryContentFn))( entry->content );
   1.484 +   VMS__free( entry->key ); //was VMS__malloc'd above, so free it
   1.485 +   VMS__free( entry );
   1.486 + }
   1.487 +
   1.488 +void
   1.489 +freeHashEntryButNotContent( HashEntry *entry )
   1.490 + {
   1.491 +   VMS__free( entry->key ); //was VMS__malloc'd above, so free it
   1.492 +   VMS__free( entry );
   1.493 + }
   1.494 +