// Not PJs code, but very useful and used everywhere */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vtr_util.h"
#include "vtr_memory.h"
#include "string_cache.h"

unsigned long
string_hash(STRING_CACHE * sc,
	    const char *string);
void
generate_sc_hash(STRING_CACHE * sc);

unsigned long
string_hash(STRING_CACHE * sc,
	    const char *string)
{
    long a, i, mod, mul;

    a = 0;
    mod = sc->mod;
    mul = sc->mul;
    for(i = 0; string[i]; i++)
	a = (a * mul + (unsigned char)string[i]) % mod;
    return a;
}

void
generate_sc_hash(STRING_CACHE * sc)
{
    long i;
    long hash;

    if(sc->string_hash != NULL)
		vtr::free(sc->string_hash);
    if(sc->next_string != NULL)
		vtr::free(sc->next_string);
    sc->string_hash_size = sc->size * 2 + 11;
    sc->string_hash = (long *)sc_do_alloc(sc->string_hash_size, sizeof(long));
    sc->next_string = (long *)sc_do_alloc(sc->size, sizeof(long));
    memset(sc->string_hash, 0xff, sc->string_hash_size * sizeof(long));
    memset(sc->next_string, 0xff, sc->size * sizeof(long));
    for(i = 0; i < sc->free; i++)
	{
	    hash = string_hash(sc, sc->string[i]) % sc->string_hash_size;
	    sc->next_string[i] = sc->string_hash[hash];
	    sc->string_hash[hash] = i;
	}
}


STRING_CACHE *
sc_new_string_cache(void)
{
    STRING_CACHE *sc;

    sc = (STRING_CACHE *)sc_do_alloc(1, sizeof(STRING_CACHE));
    sc->size = 100;
    sc->string_hash_size = 0;
    sc->string_hash = NULL;
    sc->next_string = NULL;
    sc->free = 0;
    sc->string = (char **)sc_do_alloc(sc->size, sizeof(char *));
    sc->data = (void **)sc_do_alloc(sc->size, sizeof(void *));
    sc->mod = 834535547;
    sc->mul = 247999;
    generate_sc_hash(sc);
    return sc;
}

long
sc_lookup_string(STRING_CACHE * sc,
	      const char *string)
{
    long i, hash;

    if(sc == NULL) {
        return -1;
    }
    else {
    hash = string_hash(sc, string) % sc->string_hash_size;
    i = sc->string_hash[hash];
    while(i >= 0)
	{
	    if(!strcmp(sc->string[i], string))
		return i;
	    i = sc->next_string[i];
	}
    return -1;
    }
}

bool
sc_remove_string(STRING_CACHE * sc,
	      const char *string)
{
    long i, hash;

    if(sc != NULL) {
        hash = string_hash(sc, string) % sc->string_hash_size;
        i = sc->string_hash[hash];
        while(i >= 0)
        {
            if(!strcmp(sc->string[i], string))
            {
                vtr::free(sc->string[i]);
                if(sc->data[i] != NULL)
                {
            	    vtr::free(sc->data[i]);
                    sc->data = NULL;
                }
                sc->string[i] = vtr::strdup("REMOVED_NAME_FROM_SC_CACHE");
                return true;
            }
            i = sc->next_string[i];
        }
    }
    
    return false;

}

long
sc_add_string(STRING_CACHE * sc,
	   const char *string)
{
    long i;
    long hash;
    void *a;

    i = sc_lookup_string(sc, string);
    if(i >= 0)
		return i;
    if(sc->free >= sc->size)
	{
	    sc->size = sc->size * 2 + 10;

	    a = sc_do_alloc(sc->size, sizeof(char *));
	    if(sc->free > 0)
		memcpy(a, sc->string, sc->free * sizeof(char *));
	    vtr::free(sc->string);
	    sc->string = (char **)a;

	    a = sc_do_alloc(sc->size, sizeof(void *));
	    if(sc->free > 0)
		memcpy(a, sc->data, sc->free * sizeof(void *));
	    vtr::free(sc->data);
	    sc->data = (void **)a;

	    generate_sc_hash(sc);
	}
    i = sc->free;
    sc->free++;
    sc->string[i] = vtr::strdup(string);
    sc->data[i] = NULL;
    hash = string_hash(sc, string) % sc->string_hash_size;
    sc->next_string[i] = sc->string_hash[hash];
    sc->string_hash[hash] = i;
    return i;
}

int
sc_valid_id(STRING_CACHE * sc,
	 long string_id)
{
    if(string_id < 0)
	return 0;
    if(string_id >= sc->free)
	return 0;
    return 1;
}

void *
sc_do_alloc(long a,
	 long b)
{
    void *r;

    if(a < 1)
	a = 1;
    if(b < 1)
	b = 1;
    r = vtr::calloc(a, b);
    while(r == NULL)
	{
	    fprintf(stderr,
		    "Failed to allocated %ld chunks of %ld bytes (%ld bytes total)\n",
		    a, b, a * b);
	    r = vtr::calloc(a, b);
	}
    return r;
}

STRING_CACHE * sc_free_string_cache(STRING_CACHE * sc)
{
    if(sc != NULL)
    {
        if (sc->string != NULL)
        {
            for(long i = 0; i < sc->free; i++)
            {
                if (sc->string[i] != NULL)
                {
                    vtr::free(sc->string[i]);
                }
                sc->string[i] = NULL;
            }
            vtr::free(sc->string);
        }
        sc->string = NULL;

        if(sc->data != NULL)
        {
            vtr::free(sc->data);
        }
        sc->data = NULL;

        if(sc->string_hash != NULL)
        {
            vtr::free(sc->string_hash);
        }
        sc->string_hash = NULL;

        if(sc->next_string != NULL)
        {
            vtr::free(sc->next_string);
        }
        sc->next_string = NULL;

        vtr::free(sc);
    }
    sc = NULL;

    return sc;
}

void sc_merge_string_cache(STRING_CACHE **source_ref, STRING_CACHE *destination)
{
    STRING_CACHE *source = (*source_ref);
    for(int source_spot = 0; source_spot < source->free; source_spot++)
    {
        long destination_spot = sc_add_string(destination, source->string[source_spot]);
        destination->data[destination_spot] = source->data[source_spot];

        source->data[source_spot] = NULL;
    }

    /* now cleanup */
    sc_free_string_cache(source);
    (*source_ref) = NULL;
}
