#include "hashtypes.h"

/********************************************************************************
Intern Function.
   unsigned int tcl_hash(void *v);
   Purpose: Hash for string.
   Limitations: Nothing
   Returns: return the hash code.
*********************************************************************************/
size_t tcl_hash(void *v)
{
  const char* string = (char*)v;
  size_t result = 0;
  int c;

  while (1) {
    c = *string;
    string++;
    if (c == 0) {
      break;
    }
    result += (result<<3) + c;
  }

  //printf("(HASHTABLE) tcl_hash Hash <%u> Key String <%s>\n", result, (char*)v);
  return result;
}

/********************************************************************************
Intern Function.
   unsigned int numeric_hash(void *v);
   Purpose: Hash for numeric.
   Limitations: Nothing
   Returns: return the hash code.
*********************************************************************************/
size_t numeric_hash(void *v)
{
  NUMERICKEYTYPE key1 = *(NUMERICKEYTYPE *) v;
  return key1;
}

size_t petition_hash(void *v)
{
  NUMERICKEYTYPE key1 = *(NUMERICKEYTYPE *) v;
  return (key1/MAX_PETITION_PER_CLIENT);
}

/********************************************************************************
Intern Function.
   int keys_equal_fn (void *key1, void *key2);
   Purpose: Compare two keys.
   Limitations: Nothing
   Returns: if string1 less than string2 return < 0
      else if string1 identical to string2 return 0
      else if string1 greater than string2 return > 0
*********************************************************************************/
int key_string_compare(void *elem1, void *elem2)
{
  return strcmp(elem1, elem2);
}

/********************************************************************************
Intern Function.
   int keys_numeric_equal_fn (void *key1, void *key2);
   Purpose: Compare two keys.
   Limitations: Nothing
   Returns: if key1 less than key2 return < 0
      else if key1 identical to key2 return 0
      else if key1 greater than key2 return > 0
*********************************************************************************/
int keys_numeric_compare (void *elem1, void *elem2)
{
  NUMERICKEYTYPE key1 = *(NUMERICKEYTYPE *) elem1;
  NUMERICKEYTYPE key2 = *(NUMERICKEYTYPE *) elem2;

  if (key1 < key2){
    return -1;
  }else if (key1 == key2){
    return 0;
  }else if (key1 > key2) {
    return 1;
  }
}

void *key_string_copy(void *elem)
{
   char *tmp = malloc(strlen(elem) + 1);
   if(tmp == NULL)
   {
      return NULL;
   }
   return strcpy(tmp, elem);
}

void *key_numeric_copy(void *elem)
{
   NUMERICKEYTYPE *tmp = malloc(sizeof(NUMERICKEYTYPE));
   if(tmp == NULL){
      return NULL;
   }

   *tmp = *(NUMERICKEYTYPE *)elem;
   return tmp;
}

void *value_copy(void *elem)
{
   /* NOT Copy element */
   return elem;
}

void value_destroy_hPetition(void *elem){
  struct itemhPetition *petition = NULL;

  petition = (struct itemhPetition *)elem;
  if (petition->last.response != NULL){
    free(petition->last.response);
    petition->last.response = NULL;
  }

  free(elem);
  elem = NULL;
}

/*void value_destroy(void *elem)
{
   free(elem);
}

void key_destroy(void *elem)
{
   free(elem);
}
*/
