Hash table

#include <libetpan/libetpan.h>

typedef struct chash chash;

typedef struct chashcell chashiter;

typedef struct {
  char * data;
  int len;
} chashdatum;
      

chash is a hash table. chashiter is a pointer to an element of the hash table. chashdatum is an element to be placed in the hash table as a key or a value. It consists in data and a corresponding length.

chash_new and chash_free

#define CHASH_COPYNONE    0
#define CHASH_COPYKEY     1
#define CHASH_COPYVALUE   2
#define CHASH_COPYALL     (CHASH_COPYKEY | CHASH_COPYVALUE)

chash * chash_new(int size, int flags);

void chash_free(chash * hash);
        

chash_new() returns a new empty hash table or NULL if this failed. size is the initial size of the table used for implementation. flags can be a combinaison of CHASH_COPYKEY and CHASH_COPYVALUE. CHASH_COPYKEY enables copy of key, so that the initial value used for chash_set()

chash_free() releases memory used by the hash table.

chash_set and chash_get

int chash_set(chash * hash,
    chashdatum * key, chashdatum * value, chashdatum * oldvalue);

int chash_get(chash * hash,
    chashdatum * key, chashdatum * result);
        

chash_set() adds a new element into the hash table. If a previous element had the same key, it is returns into oldvalue if oldvalue is different of NULL. Medium complexity is O(1).

returns -1 if it fails, 0 on success.

chash_get()returns the corresponding value of the given key. If there is no corresponding value, -1 is returned. 0 on success. Medium complexity is O(1).

Example 2-9. chash insert and lookup

int main(void)
{
  chash * hash;
  int r;
  chashdatum key;
  chashdatum value;
  char * str1 = "my-data";
  char * str2 = "my-data";

  hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);

  key.data = "foo";
  key.len = strlen("foo");  
  value.data = str1;
  value.data = strlen(str1) + 1;
  /* + 1 is needed to get the terminal zero in the returned string */
  r = chash_set(hash, &key, &value, NULL);
  if (r < 0)
    goto free_hash;

  key.data = "bar";
  key.len = strlen("bar");  
  value.data = str2;
  value.data = strlen(str2) + 1;
  if (r < 0)
    goto free_hash;
  
  key.data = "foo";
  key.len = strlen("foo");  
  r = chash_get(hash, &key, &value);
  if (r < 0) {
    printf("element not found\n");
  }
  else {
    char * str;

    str = value.data;
    printf("found : %s", str);
  }
  
  chash_free(hash);

  exit(EXIT_SUCCESS);

 free_hash:
  chash_free(hash);
 err:
  exit(EXIT_FAILURE);
}
          

chash_delete

int chash_delete(chash * hash,
    chashdatum * key, chashdatum * oldvalue);
        

deletes the key/value pair given the corresponding key. The value is returned in old_value. If there is no corresponding value, -1 is returned. 0 on success. Medium complexity is O(1).

Example 2-10. key deletion in a chash

int main(void)
{
  chash * hash;
  int r;
  chashdatum key;
  chashdatum value;
  char * str1 = "my-data";
  char * str2 = "my-data";

  hash = build_hash();
  
  key.data = "foo";
  key.len = strlen("foo");  
  chash_delete(hash, &key, &value);

  /* it will never be possible to lookup "foo" */
  key.data = "foo";
  key.len = strlen("foo");
  r = chash_get(hash, &key, &value);
  if (r < 0) {
    printf("element not found\n");
  }
  else {
    char * str;

    str = value.data;
    printf("found : %s", str);
  }
  
  chash_free(hash);

  exit(EXIT_SUCCESS);

 free_hash:
  chash_free(hash);
 err:
  exit(EXIT_FAILURE);
}
          

chash_resize

int chash_resize(chash * hash, int size);
        

chash_resize() changes the size of the table used for implementation of the hash table. returns 0 on success, -1 on failure.

running through the chash

chashiter * chash_begin(chash * hash);

chashiter * chash_next(chash * hash, chashiter * iter);

void chash_key(chashiter * iter, chashdatum * result);

void chash_value(chashiter iter, chashdatum * result);
        

chash_begin() returns a pointer to the first element of the hash table. Returns NULL if there is no elements in the hash table. Complexity is O(n).

chash_next() returns a pointer to the next element of the hash table. Returns NULL if there is no next element. Complexity is O(n) but n calls to chash_next() also has a complexity of O(n).

chash_key() returns the key of the given element of the hash table.

chash_value returns the value of the given element of the hash table.

Example 2-11. running through a chash

int main(void)
{
  chash * hash;
  int r;
  chashiter * iter;

  hash = build_hash();

  /* this will display all the values stored in the hash */
  for(iter = chash_begin(hash) ; iter != NULL ; iter =
    chash_next(hash, iter)) {
    chashdatum key;
    chashdatum value;
    char * str;

    chash_value(iter, &value);
    str = value.data;
    printf("%s\n", str);
  }

  chash_free(hash);
}
          

chash_size and chash_count

int chash_size(chash * hash);

int chash_count(chash * hash);
        

chash_size() returns the size of the table used for implementation of the hash table. Complexity is O(1).

chash_count() returns the number of elements in the hash table. Complexity is O(1).