/* 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 <arch/types.h>
#include <assert.h>
#include <hash.h>
#include <hashtable.h>
#include <kmalloc.h>
#include <ros/common.h>
#include <slab.h>
#include <stdio.h>
#include <string.h>

/*
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,
					 NULL, 0, 0, NULL);
}

/* Common hash/equals functions.  Don't call these directly. */
size_t __generic_hash(void *k)
{
	return hash_long((unsigned long)k, BITS_PER_LONG);
}

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;
}

/*****************************************************************************/
/* returns value associated with key */
void *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;
}

/*****************************************************************************/
/* returns value associated with key */
void *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;
}

/*****************************************************************************/
/* returns zero if not found */
ssize_t 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 *, void *),
                   void *opaque)
{
	if (hashtable_count(hash)) {
		struct hashtable_itr *iter = hashtable_iterator(hash);
		do {
			void *item = hashtable_iterator_value(iter);
			func(item, opaque);
		} 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 *, void *),
                          void *opaque)
{
	if (hashtable_count(hash)) {
		struct hashtable_itr *iter = hashtable_iterator(hash);
		do {
			void *item = hashtable_iterator_value(iter);
			func(item, opaque);
		} 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.
 */
