/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk>
 * 
 * Modified 2009 by Barret Rhoden <brho@cs.berkeley.edu>
 * Changes include:
 *   - No longer frees keys or values.  It's up to the client to do that.
 *   - Uses the slab allocator for hash entry allocation.
 *   - Merges the iterator code with the main hash table code, mostly to avoid
 *   externing the hentry cache. */

#include <ros/common.h>
#include <hashtable.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <slab.h>
#include <kmalloc.h>

// File was not annotated and caused ivy based compilation to fail
// Someone should really annotate it.
#ifdef __DEPUTY__
#pragma nodeputy
#endif

#ifdef __SHARC__
#pragma nosharc
#endif

/*
Credit for primes table: Aaron Krowne
 http://br.endernet.org/~akrowne/
 http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
*/
static const unsigned int primes[] = {
53, 97, 193, 389,
769, 1543, 3079, 6151,
12289, 24593, 49157, 98317,
196613, 393241, 786433, 1572869,
3145739, 6291469, 12582917, 25165843,
50331653, 100663319, 201326611, 402653189,
805306457, 1610612741
};
const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
#define APPLY_MAX_LOAD_FACTOR(size) \
    ((size * 13)/20)
//const float max_load_factor = 0.65;

struct kmem_cache *hentry_cache;

/* Call this once on bootup, after initializing the slab allocator.  */
void hashtable_init(void)
{
	hentry_cache = kmem_cache_create("hash_entry", sizeof(struct hash_entry),
	                                 __alignof__(struct hash_entry), 0, 0, 0);
}

/* Common hash/equals functions.  Don't call these directly. */
size_t __generic_hash(void *k)
{
	/* 0x9e370001UL used by Linux (32 bit)
	 * (prime approx to the golden ratio to the max integer, IAW Knuth)
	 */
	return (size_t)k * 0x9e370001UL;	
}

ssize_t __generic_eq(void *k1, void *k2)
{
	return k1 == k2;
}

/*****************************************************************************/
hashtable_t *
create_hashtable(size_t minsize,
                 size_t (*hashf) (void*),
                 ssize_t (*eqf) (void*,void*))
{
    hashtable_t *h;
    size_t pindex, size = primes[0];
    /* Check requested hashtable isn't too large */
    if (minsize > (1u << 30)) return NULL;
    /* Enforce size as prime */
    for (pindex=0; pindex < prime_table_length; pindex++) {
        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
    }
    h = (hashtable_t *)kmalloc(sizeof(hashtable_t), 0);
    if (NULL == h) return NULL; /*oom*/
    h->table = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * size, 0);
    if (NULL == h->table) { kfree(h); return NULL; } /*oom*/
    memset(h->table, 0, size * sizeof(hash_entry_t *));
    h->tablelength  = size;
    h->primeindex   = pindex;
    h->entrycount   = 0;
    h->hashfn       = hashf;
    h->eqfn         = eqf;
    h->loadlimit    = APPLY_MAX_LOAD_FACTOR(size);
    return h;
}

/*****************************************************************************/
static size_t
hash(hashtable_t *h, void *k)
{
    /* Aim to protect against poor hash functions by adding logic here
     * - logic taken from java 1.4 hashtable source */
    size_t i = h->hashfn(k);
    i += ~(i << 9);
    i ^=  ((i >> 14) | (i << 18)); /* >>> */
    i +=  (i << 4);
    i ^=  ((i >> 10) | (i << 22)); /* >>> */
    return i;
}

/*****************************************************************************/
static ssize_t
hashtable_expand(hashtable_t *h)
{
    /* Double the size of the table to accomodate more entries */
    hash_entry_t **newtable;
    hash_entry_t *e;
    hash_entry_t **pE;
    size_t newsize, i, index;
    /* Check we're not hitting max capacity */
    if (h->primeindex == (prime_table_length - 1)) return 0;
    newsize = primes[++(h->primeindex)];

    newtable = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * newsize, 0);
    if (NULL != newtable)
    {
        memset(newtable, 0, newsize * sizeof(hash_entry_t*));
        /* This algorithm is not 'stable'. ie. it reverses the list
         * when it transfers entries between the tables */
        for (i = 0; i < h->tablelength; i++) {
            while (NULL != (e = h->table[i])) {
                h->table[i] = e->next;
                index = indexFor(newsize,e->h);
                e->next = newtable[index];
                newtable[index] = e;
            }
        }
        kfree(h->table);
        h->table = newtable;
    }
    /* Plan B: realloc instead */
    else 
    {
        newtable = (hash_entry_t**)
                   krealloc(h->table, newsize*sizeof(hash_entry_t*), 0);
        if (NULL == newtable) { (h->primeindex)--; return 0; }
        h->table = newtable;
        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
        for (i = 0; i < h->tablelength; i++) {
            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
                index = indexFor(newsize,e->h);
                if (index == i)
                {
                    pE = &(e->next);
                }
                else
                {
                    *pE = e->next;
                    e->next = newtable[index];
                    newtable[index] = e;
                }
            }
        }
    }
    h->tablelength = newsize;
    h->loadlimit   = APPLY_MAX_LOAD_FACTOR(newsize);
    return -1;
}

/*****************************************************************************/
size_t
hashtable_count(hashtable_t *h)
{
    return h->entrycount;
}

/*****************************************************************************/
ssize_t
hashtable_insert(hashtable_t *h, void *k, void *v)
{
    /* This method allows duplicate keys - but they shouldn't be used */
    size_t index;
    hash_entry_t *e;
    if (++(h->entrycount) > h->loadlimit)
    {
        /* Ignore the return value. If expand fails, we should
         * still try cramming just this value into the existing table
         * -- we may not have memory for a larger table, but one more
         * element may be ok. Next time we insert, we'll try expanding again.*/
        hashtable_expand(h);
    }
    e = (hash_entry_t *)kmem_cache_alloc(hentry_cache, 0);
    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
    e->h = hash(h,k);
    index = indexFor(h->tablelength,e->h);
    e->k = k;
    e->v = v;
    e->next = h->table[index];
    h->table[index] = e;
    return -1;
}

/*****************************************************************************/
void * /* returns value associated with key */
hashtable_search(hashtable_t *h, void *k)
{
    hash_entry_t *e;
    size_t hashvalue, index;
    hashvalue = hash(h,k);
    index = indexFor(h->tablelength,hashvalue);
    e = h->table[index];
    while (NULL != e)
    {
        /* Check hash value to short circuit heavier comparison */
        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
        e = e->next;
    }
    return NULL;
}

/*****************************************************************************/
void * /* returns value associated with key */
hashtable_remove(hashtable_t *h, void *k)
{
    /* TODO: consider compacting the table when the load factor drops enough,
     *       or provide a 'compact' method. */

    hash_entry_t *e;
    hash_entry_t **pE;
    void *v;
    size_t hashvalue, index;

    hashvalue = hash(h,k);
    index = indexFor(h->tablelength,hash(h,k));
    pE = &(h->table[index]);
    e = *pE;
    while (NULL != e)
    {
        /* Check hash value to short circuit heavier comparison */
        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
        {
            *pE = e->next;
            h->entrycount--;
            v = e->v;
			kmem_cache_free(hentry_cache, e);
            return v;
        }
        pE = &(e->next);
        e = e->next;
    }
    return NULL;
}

/*****************************************************************************/
/* destroy */
void
hashtable_destroy(hashtable_t *h)
{
	if (hashtable_count(h))
		warn("Destroying a non-empty hashtable, clean up after yourself!\n");

    size_t i;
    hash_entry_t *e, *f;
    hash_entry_t **table = h->table;
	for (i = 0; i < h->tablelength; i++) {
		e = table[i];
		while (NULL != e) {
			f = e;
			e = e->next;
			kmem_cache_free(hentry_cache, f);
		}
	}
    kfree(h->table);
    kfree(h);
}

/*****************************************************************************/
/* hashtable_iterator    - iterator constructor, be sure to kfree this when
 * you're done.
 *
 * If the htable isn't empty, e and index will refer to the first entry. */

hashtable_itr_t *
hashtable_iterator(hashtable_t *h)
{
    size_t i, tablelength;
    hashtable_itr_t *itr = (hashtable_itr_t *)
        kmalloc(sizeof(hashtable_itr_t), 0);
    if (NULL == itr) return NULL;
    itr->h = h;
    itr->e = NULL;
    itr->parent = NULL;
    tablelength = h->tablelength;
    itr->index = tablelength;
    if (0 == h->entrycount) return itr;

    for (i = 0; i < tablelength; i++)
    {
        if (NULL != h->table[i])
        {
            itr->e = h->table[i];
            itr->index = i;
            break;
        }
    }
    return itr;
}

/*****************************************************************************/
/* key      - return the key of the (key,value) pair at the current position */
/* value    - return the value of the (key,value) pair at the current position */

void *
hashtable_iterator_key(hashtable_itr_t *i)
{ return i->e->k; }

void *
hashtable_iterator_value(hashtable_itr_t *i)
{ return i->e->v; }

/*****************************************************************************/
/* advance - advance the iterator to the next element
 *           returns zero if advanced to end of table */

ssize_t
hashtable_iterator_advance(hashtable_itr_t *itr)
{
    size_t j,tablelength;
    hash_entry_t **table;
    hash_entry_t *next;
    if (NULL == itr->e) return 0; /* stupidity check */

    next = itr->e->next;
    if (NULL != next)
    {
        itr->parent = itr->e;
        itr->e = next;
        return -1;
    }
    tablelength = itr->h->tablelength;
    itr->parent = NULL;
    if (tablelength <= (j = ++(itr->index)))
    {
        itr->e = NULL;
        return 0;
    }
    table = itr->h->table;
    while (NULL == (next = table[j]))
    {
        if (++j >= tablelength)
        {
            itr->index = tablelength;
            itr->e = NULL;
            return 0;
        }
    }
    itr->index = j;
    itr->e = next;
    return -1;
}

/*****************************************************************************/
/* remove - remove the entry at the current iterator position
 *          and advance the iterator, if there is a successive
 *          element.
 *          If you want the value, read it before you remove:
 *          beware memory leaks if you don't.
 *          Returns zero if end of iteration. */

ssize_t
hashtable_iterator_remove(hashtable_itr_t *itr)
{
    hash_entry_t *remember_e, *remember_parent;
    ssize_t ret;

    /* Do the removal */
    if (NULL == (itr->parent))
    {
        /* element is head of a chain */
        itr->h->table[itr->index] = itr->e->next;
    } else {
        /* element is mid-chain */
        itr->parent->next = itr->e->next;
    }
    /* itr->e is now outside the hashtable */
    remember_e = itr->e;
    itr->h->entrycount--;

    /* Advance the iterator, correcting the parent */
    remember_parent = itr->parent;
    ret = hashtable_iterator_advance(itr);
    if (itr->parent == remember_e) { itr->parent = remember_parent; }
	kmem_cache_free(hentry_cache, remember_e);
    return ret;
}

/*****************************************************************************/
ssize_t /* returns zero if not found */
hashtable_iterator_search(hashtable_itr_t *itr,
                          hashtable_t *h, void *k)
{
    hash_entry_t *e, *parent;
    size_t hashvalue, index;

    hashvalue = hash(h,k);
    index = indexFor(h->tablelength,hashvalue);

    e = h->table[index];
    parent = NULL;
    while (NULL != e)
    {
        /* Check hash value to short circuit heavier comparison */
        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
        {
            itr->index = index;
            itr->e = e;
            itr->parent = parent;
            itr->h = h;
            return -1;
        }
        parent = e;
        e = e->next;
    }
    return 0;
}

/* Runs func on each member of the hash table */
void hash_for_each(struct hashtable *hash, void func(void*))
{
	if (hashtable_count(hash)) {
		struct hashtable_itr *iter = hashtable_iterator(hash);
		do {
			void *item = hashtable_iterator_value(iter);
			func(item);
		} while (hashtable_iterator_advance(iter));
		kfree(iter);
	}
}

/* Runs func on each member of the hash table, removing the item after
 * processing it.  Make sure func frees the item, o/w you'll leak. */
void hash_for_each_remove(struct hashtable *hash, void func(void*))
{
	if (hashtable_count(hash)) {
		struct hashtable_itr *iter = hashtable_iterator(hash);
		do {
			void *item = hashtable_iterator_value(iter);
			func(item);
		} while (hashtable_iterator_remove(iter));
		kfree(iter);
	}
}

/*
 * Copyright (c) 2002, 2004, Christopher Clark
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * * Neither the name of the original author; nor the names of any contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
