/*****************************************************************************\
 *  xtree.c - functions used for hash table manament
 *****************************************************************************
 *  Copyright (C) 2012 CEA/DAM/DIF
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "src/common/uthash.h"
#include "src/common/xhash.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#if 0
/* undefine default allocators */
#undef uthash_malloc
#undef uthash_free

/* re-define them using slurm's ones */
#define uthash_malloc(sz) xmalloc(sz)
#define uthash_free(ptr, sz) xfree(ptr)
#endif

/*
 * FIXME:
 * A pre-malloced array of xhash_item_t could be associated to
 * the xhash_table in order to speed up the xhash_add function.
 * The default array size could be something like 10% of the
 * provided table_size (hash table are commonly defined larger
 * than necessary to avoid shared keys and usage of linked list)
 */

typedef struct xhash_item_st {
	void*		item;    /* user item                               */
	UT_hash_handle	hh;      /* make this structure hashable by uthash  */
} xhash_item_t;

struct xhash_st {
	uint32_t		count;    /* user items count                */
	xhash_freefunc_t	freefunc; /* function used to free items     */
	xhash_item_t*		ht;       /* hash table                      */
	xhash_idfunc_t		identify; /* function returning a unique str
					     key */
};

xhash_t *xhash_init(xhash_idfunc_t idfunc, xhash_freefunc_t freefunc)
{
	xhash_t* table = NULL;
	if (!idfunc)
		return NULL;
	table = xmalloc(sizeof(xhash_t));
	table->ht = NULL; /* required by uthash */
	table->count = 0;
	table->identify = idfunc;
	table->freefunc = freefunc;
	return table;
}

static xhash_item_t* xhash_find(xhash_t* table, const char* key, uint32_t len)
{
	xhash_item_t* hash_item = NULL;

	if (!table || !key)
		return NULL;
	HASH_FIND(hh, table->ht, key, len, hash_item);
	return hash_item;
}

void* xhash_get(xhash_t* table, const char* key, uint32_t key_len)
{
	xhash_item_t* item = xhash_find(table, key, key_len);
	if (!item)
		return NULL;
	return item->item;
}

void* xhash_get_str(xhash_t* table, const char* key)
{
	return xhash_get(table, key, strlen(key));
}

void* xhash_add(xhash_t* table, void* item)
{
	xhash_item_t* hash_item = NULL;
	const char *key = NULL;
	uint32_t keylen = 0;

	if (!table || !item)
		return NULL;
	hash_item = xmalloc(sizeof(xhash_item_t));
	hash_item->item    = item;
	table->identify(item, &key, &keylen);
	HASH_ADD_KEYPTR(hh, table->ht, key, keylen, hash_item);
	++table->count;
	return hash_item->item;
}

void* xhash_pop(xhash_t* table, const char* key, uint32_t len)
{
	void* item_item;
	xhash_item_t* item = xhash_find(table, key, len);
	if (!item)
		return NULL;
	item_item = item->item;
	HASH_DELETE(hh, table->ht, item);
	xfree(item);
	--table->count;
	return item_item;
}

void* xhash_pop_str(xhash_t* table, const char* key)
{
	return xhash_pop(table, key, strlen(key));
}

void xhash_delete(xhash_t* table, const char* key, uint32_t len)
{
	if (!table || !key || !len)
		return;
	void* item_item = xhash_pop(table, key, len);
	if (table->freefunc)
		table->freefunc(item_item);
}

void xhash_delete_str(xhash_t* table, const char* key)
{
	return xhash_delete(table, key, strlen(key));
}

uint32_t xhash_count(xhash_t* table)
{
	if (!table)
		return 0;
	return table->count;
}

void xhash_walk(xhash_t* table,
		void (*callback)(void* item, void* arg),
		void* arg)
{
	xhash_item_t* current_item = NULL;
	xhash_item_t* tmp = NULL;
	if (!table || !callback)
		return;
	HASH_ITER(hh, table->ht, current_item, tmp) {
		  callback(current_item->item, arg);
	}
}

void xhash_clear(xhash_t* table)
{
	xhash_item_t* current_item = NULL;
	xhash_item_t* tmp = NULL;

	if (!table)
		return;
	HASH_ITER(hh, table->ht, current_item, tmp) {
		  HASH_DEL(table->ht, current_item);
		  if (table->freefunc)
			  table->freefunc(current_item->item);
		  xfree(current_item);
	}

	table->count = 0;
}

void xhash_free_ptr(xhash_t** table)
{
	if (!table || !*table)
		return;
	xhash_clear(*table);
	xfree(*table);
}
