#include <string.h>
#include <stdlib.h>
#include "TextureHash.h"

TextureHash::TextureHash(void)
{
	id_count = 0;
    int size = sizeof(hashtable)*TABLE_SIZE;
#if defined(__SPU__) || ! defined(HAS_POSIX_MEMALIGN)
        table =  (hashtable*)malloc(size);
#else
        posix_memalign((void**)&table, 16, size);
#endif

    for (int i = 0; i < TABLE_SIZE; i++) {
        table[i].tx_id = -1;
        table[i].key = NULL;
    }
}

TextureHash::~TextureHash(void)
{
    free(table);
}

int
TextureHash::hash_function(const char *key)
{
    //float value = 0.0;
    int value = 0;

    for (int i = 0; key[i]; i++) {
        value += key[i]*(i+1)*17+1;
    }

    return value%TABLE_SIZE;
}

int
TextureHash::hash_regist(const char* key, int &id)
{
  int hash = hash_function(key);
  for (int i = 0; ; i++) {
    if (table[hash].tx_id == -1) {
      table[hash].key   = (char*)key;
      id = id_count++;
      return 0;
      
    } else if (strcmp(key, table[hash].key) == 0
	       && table[hash].tx_id != -1){
      id = table[hash].tx_id;
      return 1;
    }
    hash = ((37*hash)^(11*i)) % TABLE_SIZE;
  }  
}

int
TextureHash::sg_hash_regist(const char* key, int &id)
{
    int hash = hash_function(key);

    for (int i = 0; ; i++) {
        if (table[hash].tx_id == -1) {
            table[hash].key   = (char*)key;
	    table[hash].tx_id = id;
            return 0;

        } else if (strcmp(key, table[hash].key) == 0
                   && table[hash].tx_id != -1){
            return table[hash].tx_id;
        }
        hash = ((37*hash)^(11*i)) % TABLE_SIZE;
    }
}

int
TextureHash::get_sgid(const char* key)
{

    int hash = hash_function(key);
    for (int i = 0; ; i++) {
        if (table[hash].tx_id == -1) {
            return -1;

        } else if (strcmp(key, table[hash].key) == 0
                   && table[hash].tx_id != -1){
            return table[hash].tx_id;
        }
        hash = ((37*hash)^(11*i)) % TABLE_SIZE;
    }
}
