blob: 8c2d7194d8d6bbb9481827bac97646948534c89a [file] [log] [blame]
/*****************************************************************************\
* 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);
}