XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_lib, xbt,
"Libraries provide the same functionalities than hash tables");
-xbt_mallocator_t lib_mallocator = NULL;
-
/*####[ Private prototypes ]#################################################*/
static void *lib_mallocator_new_f(void);
static void lib_mallocator_free_f(void *dict);
/*####[ Code ]###############################################################*/
-void xbt_lib_preinit(void)
+unsigned int xbt_lib_size(xbt_lib_t lib)
{
- if (lib_mallocator != NULL) {
- xbt_mallocator_free(lib_mallocator);
- }
-
- lib_mallocator = xbt_mallocator_new(256,
- lib_mallocator_new_f,
- lib_mallocator_free_f,
- lib_mallocator_reset_f);
-}
-
-void xbt_lib_postexit(void)
-{
- if (lib_mallocator != NULL) {
- xbt_mallocator_free(lib_mallocator);
- lib_mallocator = NULL;
- }
+ return (lib ? (unsigned int) lib->count : (unsigned int) 0);
}
static xbt_libelm_t xbt_libelm_new(const char *key,
xbt_lib_t xbt_lib_new(void)
{
xbt_lib_t lib;
- lib = xbt_mallocator_get(lib_mallocator);
+ lib = xbt_new0(s_xbt_lib_t, 1);
lib->table_size = 127;
lib->table = xbt_new0(xbt_libelm_t, lib->table_size + 1);
lib->count = 0;
xbt_libelm_t current, previous;
int table_size;
xbt_libelm_t *table;
+ xbt_lib_t l = *lib;
- // if ( *dict ) xbt_dict_dump_sizes(*dict);
-
- if (lib != NULL && *lib != NULL) {
- table_size = (*lib)->table_size;
- table = (*lib)->table;
+ if (l) {
+ table_size = l->table_size;
+ table = l->table;
- for (i = 0; (*lib)->count && i <= table_size; i++) {
+ for (i = 0; l->count && i <= table_size; i++) {
current = table[i];
while (current != NULL) {
previous = current;
current = current->next;
xbt_free(previous->key);
- for(j=0; j< (*lib)->levels; j++)
+ for(j=0; j< l->levels; j++)
if((&(previous->content))[j])
- (*lib)->free_f[j]( (&(previous->content))[j]);
+ l->free_f[j]( (&(previous->content))[j]);
xbt_free(previous);
- (*lib)->count--;
+ l->count--;
}
}
xbt_free(table);
- xbt_free((*lib)->free_f);
- xbt_mallocator_release(lib_mallocator, *lib);
- *lib = NULL;
+ xbt_free(l->free_f);
+ xbt_free(l);
+ l = NULL;
}
}
void xbt_lib_set(xbt_lib_t lib, const char *name, int level, void *obj)
{
- XBT_INFO("xbt_lib_set key '%s' with object '%p'",name,obj);
+ XBT_DEBUG("xbt_lib_set key '%s' with object '%p'",name,obj);
xbt_lib_set_ext(lib, name, strlen(name),level, obj);
}
void xbt_lib_reset(xbt_lib_t *lib)
{
- XBT_INFO("xbt_lib_reset");
+ XBT_DEBUG("xbt_lib_reset");
int i,j;
xbt_libelm_t current, next;
xbt_lib_t l = *lib;
int levels = l->levels;
- if(!(*lib)) xbt_die("Lib is NULL!");
+ if(!l) xbt_die("Lib is NULL!");
if (l->count == 0)
return;
}
else
{/* there is already an element with the same key: overwrite it */
- XBT_INFO("Replace %.*s by %.*s under key %.*s",
+ XBT_DEBUG("Replace %.*s by %.*s under key %.*s",
key_len, (char *) (&(current->content))[level],
key_len, (char *) data, key_len, (char *) key);
if (current->content != NULL) {
static void xbt_lib_rehash(xbt_lib_t lib)
{
- xbt_die("xbt_lib_rehash not yet implemented!");
+ const int oldsize = lib->table_size + 1;
+ register int newsize = oldsize * 2;
+ register int i;
+ register xbt_libelm_t *currcell;
+ register xbt_libelm_t *twincell;
+ register xbt_libelm_t bucklet;
+ register xbt_libelm_t *pprev;
+
+ currcell =
+ (xbt_libelm_t *) xbt_realloc((char *) lib->table,
+ newsize * (sizeof(xbt_libelm_t) + sizeof(void*)*(lib->levels - 1)));
+ memset(&currcell[oldsize], 0, oldsize * (sizeof(xbt_libelm_t) + sizeof(void*)*(lib->levels - 1))); /* zero second half */
+ lib->table_size = --newsize;
+ lib->table = currcell;
+ XBT_DEBUG("REHASH (%d->%d)", oldsize, newsize);
+
+ for (i = 0; i < oldsize; i++, currcell++) {
+ if (!*currcell) /* empty cell */
+ continue;
+ twincell = currcell + oldsize;
+ for (pprev = currcell, bucklet = *currcell; bucklet; bucklet = *pprev) {
+ /* Since we use "& size" instead of "%size" and since the size was doubled,
+ each bucklet of this cell must either :
+ - stay in cell i (ie, currcell)
+ - go to the cell i+oldsize (ie, twincell) */
+ if ((bucklet->hash_code & newsize) != i) { /* Move to b */
+ *pprev = bucklet->next;
+ bucklet->next = *twincell;
+ if (!*twincell)
+ lib->fill++;
+ *twincell = bucklet;
+ continue;
+ } else {
+ pprev = &bucklet->next;
+ }
+
+ }
+
+ if (!*currcell) /* everything moved */
+ lib->fill--;
+ }
+
}
void xbt_lib_cursor_first(const xbt_lib_t lib,
static void xbt_lib_cursor_free(xbt_lib_cursor_t * cursor)
{
- if (*cursor) {
- xbt_free(*cursor);
- *cursor = NULL;
- }
+ xbt_free(*cursor);
+ *cursor = NULL;
}
void xbt_lib_cursor_step(xbt_lib_cursor_t cursor)