Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

test_hash_table.c

This test program shows how to use the hash table's API.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "chtbl.h"


/* ---------------------------------------------------------------- */
/* Element stored into the hash table                               */
/* ---------------------------------------------------------------- */

struct user_data {
                    char *string; /* allocated                        */
                    int  size;    /* number of characters in 'string' */
                 };

/* ---------------------------------------------------------------- */
/* Function used to hash the input key                              */
/*                                                                  */
/*                     ##### WARNING !!!! #####                     */
/*                                                                  */
/* This function *MUST* return a positive value, otherwize you will */
/* generate a segmentation fault!                                   */
/* ---------------------------------------------------------------- */

int hash_function (const void *key)
{
  struct user_data *data;
  int              index, i;

  data = (struct user_data*)key;
  index = 0;
  
  for (i=0; i<data->size; i++) { index *= (int)(data->string[i]); }

  if (index < 0) { index *= - 1; }

  return index; 
}

/* ---------------------------------------------------------------- */
/* Function used to free all memory allocated for the user defined  */
/* data.                                                            */
/* ---------------------------------------------------------------- */

void free_user_data (void *d)
{
  struct user_data *data;

  data = (struct user_data*)d;
  free (data->string);
  free (data);

  return;
}

/* ---------------------------------------------------------------- */
/* Function used to compare user defined data                       */
/* Must return 1 if d1 == d2                                        */
/* Must return 0 if d1 != d2                                        */
/* ---------------------------------------------------------------- */

int compare_user_data (const void *d1, const void *d2)
{
  struct user_data *data1, *data2;

  data1 = (struct user_data*)d1;
  data2 = (struct user_data*)d2;

  return !strcmp(data1->string, data2->string);
}

/* ---------------------------------------------------------------- */
/* Main entry point                                                 */
/* ---------------------------------------------------------------- */

int main (int argc, char *argv[])
{
  CHTbl             htab;
  char              buffer[32];
  int               number_of_linked_list, number_of_arguments, i, cr;
  struct user_data  *data, sdata;
  


  /* -------------------------------------------------------------- */
  /* Check command line arguments                                   */
  /* -------------------------------------------------------------- */

  if (argc != 3)
  {
    fprintf (stderr, "\nUsage: hash_table.test <number of linked list> <total number of elements>\n");
    return 1;
  }

  number_of_linked_list = atoi(argv[1]);
  number_of_arguments   = atoi(argv[2]);

  /* -------------------------------------------------------------- */
  /* Initialize the hash thable                                     */
  /* -------------------------------------------------------------- */

  if (
       chtbl_init (
                    &htab,
                    number_of_linked_list,
                    hash_function,
                    compare_user_data,
                    free_user_data
                  ) == -1
     )
  {
    fprintf (stderr, "\nhash_table.test: Initialization failed (Can not allocate memory)\n");
    return 1;
  }

  /* -------------------------------------------------------------- */
  /* Load hash table with elements                                  */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Insert elements in the hash table                  #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<number_of_arguments; i++)
  {
    /* ------------------------------------------------------------ */
    /* Allocate memory for data structure                           */
    /* ------------------------------------------------------------ */

    data = (struct user_data*)malloc(sizeof(struct user_data));
    if (data == NULL)
    {
      fprintf (stderr, "\nhash_table.test: Can not allocate memory\n");
      return 1;
    }

    sprintf (buffer, "%d", i);
    data->string = (char*)malloc((strlen(buffer)+1)*sizeof(char));
    if (data->string == NULL)
    {
      fprintf (stderr, "\nhash_table.test: Can not allocate memory\n");
      return 1;
    }

    strcpy (data->string, buffer);
    data->size = strlen(data->string);

    /* ------------------------------------------------------------ */
    /* Now, put the data into the hash table                        */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nInserting \"%s\"", data->string);

    cr = chtbl_insert (&htab, (void*)data);

    switch (cr)
    {
      case -1: {
                 fprintf (stderr, "\nhash_table.test: Insertion failed (Can not allocate memory)\n");
                 return 1;
               }; break;

      case 1:  {
                 fprintf (stdout, "\nData was already in the hash table");
               }; break;
    }
  }

  /* -------------------------------------------------------------- */
  /* Now, walk through the hash table                               */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Print the content of the hash table                #");
  fprintf (stdout, "\n######################################################\n\n");

  data = (struct user_data*) chtbl_next(&htab, REWIND_HASH);

  i = 0;
  while (data != NULL)
  {
    fprintf (stdout, "%d: %s (%d)\n", i, data->string, data->size);
    data = (struct user_data*) chtbl_next(&htab, CURRENT_HASH);
    i++;
  }
 
  fprintf (stdout, "\n"); 

  /* -------------------------------------------------------------- */
  /* Search for elements                                            */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Search for elements                                #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<40; i++)
  {
    /* ------------------------------------------------------------ */
    /* Initialize the data to look for                              */
    /* Please note that we could have written:                      */
    /*                                                              */
    /*        sdata.string = buffer                                 */
    /*                                                              */
    /* => No dynamic allocation (so no need to free memory).        */
    /* ------------------------------------------------------------ */

    sprintf (buffer, "%d", i);
    sdata.string = (char*)malloc((strlen(buffer)+1)*sizeof(char));
    if (sdata.string == NULL)
    {
      fprintf (stderr, "\nhash_table.test: Can not allocate memory\n");
      return 1;
    }

    strcpy (sdata.string, buffer);
    sdata.size = strlen (sdata.string);

    /* ------------------------------------------------------------ */
    /* Lookup the hash table                                        */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nLooking for [%s] ...", sdata.string);

    data = &sdata;
    cr = chtbl_lookup (&htab, (void**)&data);

    if (cr == 0)
    {
       fprintf (stdout, "Element found [%s, %d]", data->string, data->size);
    }
    else
    {
       fprintf (stdout, "Element NOT found");
    }

    /* ------------------------------------------------------------ */
    /* Free allocated memory                                        */
    /* Please note this could have been avoided by writting         */
    /*                                                              */
    /*        sdata.string = buffer                                 */
    /* ------------------------------------------------------------ */

    free (sdata.string);
  }

  /* -------------------------------------------------------------- */
  /* Remove elements from the hash table                            */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Remove elements                                    #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<40; i++)
  {
    /* ------------------------------------------------------------ */
    /* Initialize the data to look for                              */
    /* ------------------------------------------------------------ */

    sprintf (buffer, "%d", i);
    sdata.string = buffer;
    data = &sdata;

    /* ------------------------------------------------------------ */
    /* Remove the element from the hash table                       */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nRemoving element [%s] ...", sdata.string);

    cr = chtbl_remove (&htab, (void**)&data);
    if (cr == -1)
    {
       fprintf (stdout, " The element was not in the hash table");
    }
    else
    {
       fprintf (stdout, " Element removed");

       /* --------------------------------------------------------- */
       /* WARNING                                                   */
       /* =======                                                   */
       /*                                                           */
       /* Keep in mind that it is the user's reponsability to free  */
       /* the memory allocated for the element's data.              */
       /* --------------------------------------------------------- */

       free_user_data (data);
    }
  }

  /* -------------------------------------------------------------- */
  /* Now make sure that the elements has been removed               */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Lookup removed elements                            #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<40; i++)
  {
    /* ------------------------------------------------------------ */
    /* Initialize the data to look for                              */
    /* ------------------------------------------------------------ */

    sprintf (buffer, "%d", i);
    sdata.string = buffer;
    data = &sdata;

    /* ------------------------------------------------------------ */
    /* Lookup the hash table                                        */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nLooking for [%s] ...", sdata.string);

    data = &sdata;
    cr = chtbl_lookup (&htab, (void**)&data);

    if (cr == 0)
    {
       fprintf (stdout, "Element found [%s, %d]", data->string, data->size);
    }
    else
    {
       fprintf (stdout, "Element NOT found");
    }
  }

  /* -------------------------------------------------------------- */
  /* Insert few data for exhaustive research in all the hash table  */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Insert elements in the hash table                  #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<5; i++)
  {
    /* ------------------------------------------------------------ */
    /* Allocate memory for data structure                           */
    /* ------------------------------------------------------------ */

    data = (struct user_data*)malloc(sizeof(struct user_data));
    if (data == NULL)
    {
      fprintf (stderr, "\nhash_table.test: Can not allocate memory\n");
      return 1;
    }

    sprintf (buffer, "%d", i);
    data->string = (char*)malloc((strlen(buffer)+1)*sizeof(char));
    if (data->string == NULL)
    {
      fprintf (stderr, "\nhash_table.test: Can not allocate memory\n");
      return 1;
    }

    strcpy (data->string, buffer);
    data->size = strlen(data->string);

    /* ------------------------------------------------------------ */
    /* Now, put the data into the hash table                        */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nInserting \"%s\"", data->string);

    cr = chtbl_insert (&htab, (void*)data);

    switch (cr)
    {
      case -1: {
                 fprintf (stderr, "\nhash_table.test: Insertion faile (Can not allocate memory)\n");
                 return 1;
               }; break;

      case 1:  {
                 fprintf (stdout, "\nData was already in the hash table");
               }; break;
    }
  }

  /* -------------------------------------------------------------- */
  /* Lookup up all the hash table to find the data                  */
  /* -------------------------------------------------------------- */

  fprintf (stdout, "\n");
  fprintf (stdout, "\n######################################################");
  fprintf (stdout, "\n# Looking up ALL the hash table to find dat          #");
  fprintf (stdout, "\n######################################################\n\n");

  for (i=0; i<number_of_arguments; i++)
  {
    sprintf (buffer, "%d", i);
    sdata.string = buffer;
    data = &sdata;

    /* ------------------------------------------------------------ */
    /* Lookup the hash table                                        */
    /* ------------------------------------------------------------ */

    fprintf (stdout, "\nLooking for [%s] in ALL hash table ...", sdata.string);

    if (chtbl_find(&htab, (void*)&data) == 0)
    {
      /* ---------------------------------------------------------- */
      /* Data found in hash table                                   */
      /* ---------------------------------------------------------- */

      fprintf (stdout, " FOUND [%s, %d]", data->string, data->size);
    }
    else
    {
      /* ---------------------------------------------------------- */
      /* Data not found                                             */
      /* ---------------------------------------------------------- */

      fprintf (stdout, " NOT FOUND [%s, %d]", data->string, data->size);
    }
  }

  /* -------------------------------------------------------------- */
  /* Free all memory allocated for the hash table and exit          */
  /* -------------------------------------------------------------- */

  chtbl_destroy (&htab);

  return 0;
}

Generated on Thu Apr 3 16:23:40 2003 for Common_C_libraries by doxygen1.3-rc1