src/libs/hash_lib.c
void hash_table_rehash(Hash_Table* table, int new_buckets) {
  Hash_Table_Entry** new_entries;
  Hash_Table_Entry** flat_entries;
  Hash_Table_Entry** old_entries = table->entries;
  uns                old_buckets = table->buckets;
  Hash_Table_Entry*  temp;
  uns                ii, jj;

  ASSERT(0, new_buckets >= 0);
  if(new_buckets == 0) {  // use next prime
    new_buckets = table->buckets;
    for(ii = 0; ii < NUM_HASH_TABLE_PRIMES - 1; ii++)
      if(hash_table_primes[ii] == old_buckets) {
        new_buckets = hash_table_primes[ii + 1];
        break;
      }
  }
  if(new_buckets == old_buckets)
    return;

  // flatten hash table into an array of entries
  flat_entries = (Hash_Table_Entry**)malloc(table->count *
                                            sizeof(Hash_Table_Entry*));
  for(ii = 0, jj = 0; ii < old_buckets; ii++)
    for(temp = old_entries[ii]; temp; temp = temp->next)
      flat_entries[jj++] = temp;
  ASSERT(0, jj == table->count);

  // replace old with new and free the old entry array
  new_entries = (Hash_Table_Entry**)calloc(new_buckets,
                                           sizeof(Hash_Table_Entry*));
  ASSERT(0, new_entries);
  ASSERT(0, new_buckets > 0 && new_buckets < 100000);
  table->buckets = new_buckets;
  table->entries = new_entries;
  free(old_entries);

  // insert each element
  for(ii = 0; ii < table->count; ii++) {
    Hash_Table_Entry* temp  = flat_entries[ii];
    uns               index = HASH_INDEX(table, temp->key);
    temp->next              = table->entries[index];
    table->entries[index]   = temp;
  }

  free(flat_entries);
}
/**************************************************************************************/
// hash_table_rehash: expand or contract the hash table
// WARNING: this hasn't really been tested
expand or contract the hash table
WARNING: this hasn't really been tested
expand or contract the hash table WARNING : this hasn ' t really been tested
void hash_table_rehash(Hash_Table* table, int new_buckets) {
  Hash_Table_Entry** new_entries;
  Hash_Table_Entry** flat_entries;
  Hash_Table_Entry** old_entries = table->entries;
  uns                old_buckets = table->buckets;
  Hash_Table_Entry*  temp;
  uns                ii, jj;
  ASSERT(0, new_buckets >= 0);
  if(new_buckets == 0) {  
    new_buckets = table->buckets;
    for(ii = 0; ii < NUM_HASH_TABLE_PRIMES - 1; ii++)
      if(hash_table_primes[ii] == old_buckets) {
        new_buckets = hash_table_primes[ii + 1];
        break;
      }
  }
  if(new_buckets == old_buckets)
    return;
  flat_entries = (Hash_Table_Entry**)malloc(table->count *
                                            sizeof(Hash_Table_Entry*));
  for(ii = 0, jj = 0; ii < old_buckets; ii++)
    for(temp = old_entries[ii]; temp; temp = temp->next)
      flat_entries[jj++] = temp;
  ASSERT(0, jj == table->count);
  new_entries = (Hash_Table_Entry**)calloc(new_buckets,
                                           sizeof(Hash_Table_Entry*));
  ASSERT(0, new_entries);
  ASSERT(0, new_buckets > 0 && new_buckets < 100000);
  table->buckets = new_buckets;
  table->entries = new_entries;
  free(old_entries);
  for(ii = 0; ii < table->count; ii++) {
    Hash_Table_Entry* temp  = flat_entries[ii];
    uns               index = HASH_INDEX(table, temp->key);
    temp->next              = table->entries[index];
    table->entries[index]   = temp;
  }
  free(flat_entries);
}
void hash_table_rehash ( Hash_Table * table , int new_buckets ) { Hash_Table_Entry * * new_entries ; Hash_Table_Entry * * flat_entries ; Hash_Table_Entry * * old_entries = table -> entries ; uns old_buckets = table -> buckets ; Hash_Table_Entry * temp ; uns ii , jj ; ASSERT ( 0 , new_buckets >= 0 ) ; if ( new_buckets == 0 ) { new_buckets = table -> buckets ; for ( ii = 0 ; ii < NUM_HASH_TABLE_PRIMES - 1 ; ii ++ ) if ( hash_table_primes [ ii ] == old_buckets ) { new_buckets = hash_table_primes [ ii + 1 ] ; break ; } } if ( new_buckets == old_buckets ) return ; flat_entries = ( Hash_Table_Entry * * ) malloc ( table -> count * sizeof ( Hash_Table_Entry * ) ) ; for ( ii = 0 , jj = 0 ; ii < old_buckets ; ii ++ ) for ( temp = old_entries [ ii ] ; temp ; temp = temp -> next ) flat_entries [ jj ++ ] = temp ; ASSERT ( 0 , jj == table -> count ) ; new_entries = ( Hash_Table_Entry * * ) calloc ( new_buckets , sizeof ( Hash_Table_Entry * ) ) ; ASSERT ( 0 , new_entries ) ; ASSERT ( 0 , new_buckets > 0 && new_buckets < 100000 ) ; table -> buckets = new_buckets ; table -> entries = new_entries ; free ( old_entries ) ; for ( ii = 0 ; ii < table -> count ; ii ++ ) { Hash_Table_Entry * temp = flat_entries [ ii ] ; uns index = HASH_INDEX ( table , temp -> key ) ; temp -> next = table -> entries [ index ] ; table -> entries [ index ] = temp ; } free ( flat_entries ) ; }
hash_table_rehash: expand or contract the hash table
WARNING: this hasn't really been tested
hash_table_rehash : expand or contract the hash table WARNING : this hasn ' t really been tested
// use next prime // flatten hash table into an array of entries // replace old with new and free the old entry array // insert each element