Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add library (xbt_lib) to simgrid.
authornavarrop <navarrop@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 24 Mar 2011 10:34:59 +0000 (10:34 +0000)
committernavarrop <navarrop@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 24 Mar 2011 10:34:59 +0000 (10:34 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@9822 48e7efb5-ca39-0410-a469-dd3cf9ba447f

buildtools/Cmake/DefinePackages.cmake
include/xbt/lib.h [new file with mode: 0644]
src/xbt/lib.c [new file with mode: 0644]
teshsuite/simdag/platforms/CMakeLists.txt

index 21b0a1c..e443309 100644 (file)
@@ -166,6 +166,7 @@ set(XBT_SRC
        src/xbt/setset.c
        src/xbt/parmap.c
        src/xbt/xbt_replay_trace_reader.c
+       src/xbt/lib.c
 )
 
 if(HAVE_MMAP)
diff --git a/include/xbt/lib.h b/include/xbt/lib.h
new file mode 100644 (file)
index 0000000..476532b
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _XBT_LIB_H
+#define _XBT_LIB_H
+
+#define MAX_FILL_PERCENT 80
+
+SG_BEGIN_DECL()
+
+typedef struct xbt_lib_ *xbt_lib_t;
+typedef struct xbt_libelm_ *xbt_libelm_t;
+typedef struct xbt_lib_cursor_ *xbt_lib_cursor_t;
+typedef struct xbt_lib_cursor_ s_xbt_lib_cursor_t;
+
+struct xbt_lib_cursor_ {
+  xbt_libelm_t current;
+  int line;
+  xbt_lib_t lib;
+};
+
+typedef struct xbt_libelm_ {
+  char *key;
+  // key_len ???
+  int key_len;
+  unsigned int hash_code;
+  xbt_libelm_t next;
+  void *content;
+} s_xbt_libelm_t;
+
+typedef struct xbt_lib_ {
+  int table_size;
+  int count;
+  int fill;
+  int levels;
+  void_f_pvoid_t *free_f; // This is actually a table
+  xbt_libelm_t *table;    // This is actually a table
+} s_xbt_lib_t;
+
+
+/*####[ Prototypes ]#################################################*/
+ //lib.c
+XBT_PUBLIC(void) xbt_lib_preinit(void);
+XBT_PUBLIC(void) xbt_lib_postexit(void);
+XBT_PUBLIC(xbt_lib_t) xbt_lib_new(void);
+XBT_PUBLIC(void) xbt_lib_free(xbt_lib_t * lib);
+XBT_PUBLIC(int) xbt_lib_add_level(xbt_lib_t lib, void_f_pvoid_t free_f); // Une fois qu'on a inséré un objet, on ne peut plus ajouter de niveau
+XBT_PUBLIC(void) xbt_lib_set(xbt_lib_t lib, const char *name, int level, void *obj);
+XBT_PUBLIC(void *) xbt_lib_get_or_null(xbt_lib_t lib, const char *name, int level);
+XBT_PUBLIC(int) xbt_lib_length(xbt_lib_t lib);
+XBT_PUBLIC(void) xbt_lib_reset(xbt_lib_t *lib);
+XBT_PUBLIC(void) xbt_lib_cursor_step(xbt_lib_cursor_t cursor);
+XBT_PUBLIC(int) xbt_lib_cursor_get_or_free(xbt_lib_cursor_t * cursor, char **key, void **data);
+XBT_PUBLIC(void) xbt_lib_cursor_first(const xbt_lib_t lib, xbt_lib_cursor_t * cursor);
+
+/** @def xbt_lib_foreach
+    @hideinitializer */
+#  define xbt_lib_foreach(lib,cursor,key,data)                       \
+  for (cursor=NULL, xbt_lib_cursor_first((lib),&(cursor)) ;        \
+       xbt_lib_cursor_get_or_free(&(cursor),(char**)&(key),(void**)(&data));\
+       xbt_lib_cursor_step(cursor) )
+
+SG_END_DECL()
+#endif                          /* _XBT_LIB_H */
diff --git a/src/xbt/lib.c b/src/xbt/lib.c
new file mode 100644 (file)
index 0000000..902d5ff
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * lib.c
+ *
+ *  Created on: 16 mars 2011
+ *      Author: navarrop
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "xbt/misc.h"           /* SG_BEGIN_DECL */
+#include "xbt/mallocator.h"
+#include "xbt/ex.h"
+#include "xbt/log.h"
+#include "xbt_modinter.h"
+#include "xbt/lib.h"
+
+#define DJB2_HASH_FUNCTION
+//#define FNV_HASH_FUNCTION
+
+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);
+static void lib_mallocator_reset_f(void *dict);
+
+static void xbt_lib_set_ext(xbt_lib_t lib,const char *key,
+                            int key_len, int level, void *data);
+
+static unsigned int xbt_lib_hash_ext(const char *str,
+                                                 int str_len);
+static unsigned int xbt_lib_hash(const char *str);
+static void xbt_lib_rehash(xbt_lib_t lib);
+
+
+static xbt_lib_cursor_t xbt_lib_cursor_new(const xbt_lib_t lib);
+static void xbt_lib_cursor_rewind(xbt_lib_cursor_t cursor);
+static void xbt_lib_cursor_free(xbt_lib_cursor_t * cursor);
+
+/*####[ Code ]###############################################################*/
+
+void xbt_lib_preinit(void)
+{
+  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;
+  }
+}
+
+static xbt_libelm_t xbt_libelm_new(const char *key,
+                              int key_len,
+                              unsigned int hash_code,
+                              void *content,int level, int level_numbers)
+{
+  xbt_libelm_t element = xbt_malloc0(sizeof (s_xbt_libelm_t) + sizeof(void *)*(level_numbers-1));
+
+  element->key = xbt_new(char, key_len + 1);
+  memcpy((void *) element->key, (void *) key, key_len);
+  element->key[key_len] = '\0';
+
+  element->key_len = key_len;
+  element->hash_code = hash_code;
+
+  (&(element->content))[level] = content;
+  element->next = NULL;
+
+  return element;
+}
+
+xbt_lib_t xbt_lib_new(void)
+{
+  xbt_lib_t lib;
+  lib = xbt_mallocator_get(lib_mallocator);
+  lib->table_size = 127;
+  lib->table = xbt_new0(xbt_libelm_t, lib->table_size + 1);
+  lib->count = 0;
+  lib->fill = 0;
+  lib->levels = 0;
+  lib->free_f = NULL;
+
+  return lib;
+}
+
+void xbt_lib_free(xbt_lib_t * lib)
+{
+  int i,j;
+  xbt_libelm_t current, previous;
+  int table_size;
+  xbt_libelm_t *table;
+
+  //  if ( *dict )  xbt_dict_dump_sizes(*dict);
+
+  if (lib != NULL && *lib != NULL) {
+    table_size = (*lib)->table_size;
+    table = (*lib)->table;
+
+    for (i = 0; (*lib)->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++)
+                         if((&(previous->content))[j])
+                                 (*lib)->free_f[j]( (&(previous->content))[j]);
+               xbt_free(previous);
+                       (*lib)->count--;
+      }
+    }
+    xbt_free(table);
+    xbt_free((*lib)->free_f);
+    xbt_mallocator_release(lib_mallocator, *lib);
+    *lib = NULL;
+  }
+}
+
+int xbt_lib_add_level(xbt_lib_t lib, void_f_pvoid_t free_f)
+{
+       XBT_DEBUG("xbt_lib_add_level");
+
+       lib->free_f = realloc(lib->free_f,sizeof(void_f_pvoid_t)*(lib->levels+1));
+       lib->free_f[lib->levels]=free_f;
+       return lib->levels++;
+}
+
+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_lib_set_ext(lib, name, strlen(name),level, obj);
+}
+
+void *xbt_lib_get_or_null(xbt_lib_t lib, const char *key, int level)
+{
+       unsigned int hash_code = xbt_lib_hash(key);
+       xbt_libelm_t current;
+
+       if(!lib) xbt_die("Lib is NULL!");
+
+       current = lib->table[hash_code & lib->table_size];
+       while (current != NULL &&
+                (hash_code != current->hash_code || strcmp(key, current->key)))
+       current = current->next;
+
+       if (current == NULL)
+       return NULL;
+
+       return (&(current->content))[level];
+}
+
+static void *lib_mallocator_new_f(void)
+{
+  return xbt_new(s_xbt_lib_t, 1);
+}
+
+static void lib_mallocator_free_f(void *lib)
+{
+  xbt_free(lib);
+}
+
+static void lib_mallocator_reset_f(void *lib)
+{
+  /* nothing to do because all fields are
+   * initialized in xbt_dict_new
+   */
+}
+
+void xbt_lib_reset(xbt_lib_t *lib)
+{
+       XBT_INFO("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->count == 0)
+    return;
+
+  for (i = 0; i <= l->table_size; i++) {
+    current = l->table[i];
+    while (current) {
+       next = current->next;
+       xbt_free(current->key);
+       for(j=0; j< levels; j++)
+               if((&(current->content))[j] && (l->free_f[j]))
+                       l->free_f[j]((&(current->content))[j]);
+       xbt_free(current);
+       current = next;
+    }
+    l->table[i] = NULL;
+  }
+  xbt_free(l->free_f);
+  l->count = 0;
+  l->fill = 0;
+  l->levels = 0;
+  l->free_f = NULL;
+}
+
+int xbt_lib_length(xbt_lib_t lib)
+{
+  if(!lib) xbt_die("Lib is NULL!");
+  return lib->count;
+}
+
+static void xbt_lib_set_ext(xbt_lib_t lib,
+                            const char *key,
+                            int key_len,
+                            int level,
+                            void *data)
+{
+
+  unsigned int hash_code = xbt_lib_hash_ext(key, key_len);
+
+  xbt_libelm_t current, previous = NULL;
+  if(!lib) xbt_die("Lib is NULL!");
+
+  XBT_DEBUG("ADD '%.*s' hash = '%d', size = '%d', & = '%d' to level : %d",
+                 key_len,
+                 key,
+                 hash_code,
+          lib->table_size,
+          hash_code & lib->table_size,
+          level);
+
+  current = lib->table[hash_code & lib->table_size];
+  while (current != NULL &&
+         (hash_code != current->hash_code || key_len != current->key_len
+          || memcmp(key, current->key, key_len))) {
+    previous = current;
+    current = current->next;
+  }
+
+  if (current == NULL) {/* this key doesn't exist yet */
+               current = xbt_libelm_new(key, key_len, hash_code, data,level,lib->levels);
+               lib->count++;
+               if (previous == NULL) {
+               lib->table[hash_code & lib->table_size] = current;
+               lib->fill++;
+               if ((lib->fill * 100) / (lib->table_size + 1) > MAX_FILL_PERCENT)
+                 xbt_lib_rehash(lib);
+               } else {
+               previous->next = current;
+               }
+  }
+  else
+         if( (&(current->content))[level] == NULL )/* this key exist but level is empty */
+         {
+                 (&(current->content))[level] = data;
+         }
+         else
+         {/* there is already an element with the same key: overwrite it */
+                       XBT_INFO("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) {
+                         free((&(current->content))[level]);
+                       }
+                       (&(current->content))[level] = data;
+         }
+}
+
+/**
+ * Returns the hash code of a string.
+ */
+static unsigned int xbt_lib_hash_ext(const char *str,
+                                                 int str_len)
+{
+
+
+#ifdef DJB2_HASH_FUNCTION
+  /* fast implementation of djb2 algorithm */
+  int c;
+  register unsigned int hash = 5381;
+
+  while (str_len--) {
+    c = *str++;
+    hash = ((hash << 5) + hash) + c;    /* hash * 33 + c */
+  }
+# elif defined(FNV_HASH_FUNCTION)
+  register unsigned int hash = 0x811c9dc5;
+  unsigned char *bp = (unsigned char *) str;    /* start of buffer */
+  unsigned char *be = bp + str_len;     /* beyond end of buffer */
+
+  while (bp < be) {
+    /* multiply by the 32 bit FNV magic prime mod 2^32 */
+    hash +=
+        (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) +
+        (hash << 24);
+
+    /* xor the bottom with the current octet */
+    hash ^= (unsigned int) *bp++;
+  }
+
+# else
+  register unsigned int hash = 0;
+
+  while (str_len--) {
+    hash += (*str) * (*str);
+    str++;
+  }
+#endif
+
+  return hash;
+}
+
+static unsigned int xbt_lib_hash(const char *str)
+{
+#ifdef DJB2_HASH_FUNCTION
+  /* fast implementation of djb2 algorithm */
+  int c;
+  register unsigned int hash = 5381;
+
+  while ((c = *str++)) {
+    hash = ((hash << 5) + hash) + c;    /* hash * 33 + c */
+  }
+
+# elif defined(FNV_HASH_FUNCTION)
+  register unsigned int hash = 0x811c9dc5;
+
+  while (*str) {
+    /* multiply by the 32 bit FNV magic prime mod 2^32 */
+    hash +=
+        (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) +
+        (hash << 24);
+
+    /* xor the bottom with the current byte */
+    hash ^= (unsigned int) *str++;
+  }
+
+# else
+  register unsigned int hash = 0;
+
+  while (*str) {
+    hash += (*str) * (*str);
+    str++;
+  }
+#endif
+  return hash;
+}
+
+static void xbt_lib_rehash(xbt_lib_t lib)
+{
+       xbt_die("xbt_lib_rehash not yet implemented!");
+}
+
+void xbt_lib_cursor_first(const xbt_lib_t lib,
+                                      xbt_lib_cursor_t * cursor)
+{
+  XBT_DEBUG("xbt_lib_cursor_first");
+  if (!*cursor) {
+    XBT_DEBUG("Create the cursor on first use");
+    *cursor = xbt_lib_cursor_new(lib);
+  } else {
+    xbt_lib_cursor_rewind(*cursor);
+  }
+  if (lib != NULL && (*cursor)->current == NULL) {
+    xbt_lib_cursor_step(*cursor);      /* find the first element */
+  }
+}
+
+static xbt_lib_cursor_t xbt_lib_cursor_new(const xbt_lib_t lib)
+{
+  xbt_lib_cursor_t res = NULL;
+
+  res = xbt_new(s_xbt_lib_cursor_t, 1);
+  res->lib = lib;
+
+  xbt_lib_cursor_rewind(res);
+
+  return res;
+}
+
+static void xbt_lib_cursor_rewind(xbt_lib_cursor_t cursor)
+{
+  XBT_DEBUG("xbt_lib_cursor_rewind");
+  xbt_assert(cursor);
+
+  cursor->line = 0;
+  if (cursor->lib != NULL) {
+    cursor->current = cursor->lib->table[0];
+  } else {
+    cursor->current = NULL;
+  }
+}
+
+int xbt_lib_cursor_get_or_free(xbt_lib_cursor_t * cursor,
+                                           char **key, void **data)
+{
+
+  xbt_libelm_t current;
+
+  XBT_DEBUG("xbt_lib_get_or_free");
+
+  if (!cursor || !(*cursor))
+    return FALSE;
+
+  current = (*cursor)->current;
+  if (current == NULL) {        /* no data left */
+    xbt_lib_cursor_free(cursor);
+    return FALSE;
+  }
+
+  *key = current->key;
+  *data = &(current->content);
+  return TRUE;
+}
+
+static void xbt_lib_cursor_free(xbt_lib_cursor_t * cursor)
+{
+  if (*cursor) {
+    xbt_free(*cursor);
+    *cursor = NULL;
+  }
+}
+
+void xbt_lib_cursor_step(xbt_lib_cursor_t cursor)
+{
+  xbt_libelm_t current;
+  int line;
+
+  XBT_DEBUG("xbt_lib_cursor_step");
+  xbt_assert(cursor);
+
+  current = cursor->current;
+  line = cursor->line;
+
+  if (cursor->lib != NULL) {
+
+    if (current != NULL) {
+      XBT_DEBUG("current is not null, take the next element");
+      current = current->next;
+      XBT_DEBUG("next element: %p", current);
+    }
+
+    while (current == NULL && ++line <= cursor->lib->table_size) {
+      XBT_DEBUG("current is NULL, take the next line");
+      current = cursor->lib->table[line];
+      XBT_DEBUG("element in the next line: %p", current);
+    }
+    XBT_DEBUG("search finished, current = %p, line = %d", current, line);
+
+    cursor->current = current;
+    cursor->line = line;
+  }
+}
index 4e960d0..b00afa2 100644 (file)
@@ -5,15 +5,18 @@ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
 add_executable(basic_parsing_test basic_parsing_test.c)
 add_executable(is_router_test is_router_test.c)
 add_executable(flatifier flatifier.c)
+add_executable(new_flatifier new_flatifier.c)
 
 ### Add definitions for compile
 if(NOT WIN32)
 target_link_libraries(basic_parsing_test simgrid m pthread )
 target_link_libraries(is_router_test simgrid m pthread )
 target_link_libraries(flatifier simgrid m pthread )
+target_link_libraries(new_flatifier simgrid m pthread )
 else(NOT WIN32)
 target_link_libraries(basic_parsing_test simgrid)
 target_link_libraries(is_router_test simgrid)
 target_link_libraries(flatifier simgrid)
+target_link_libraries(new_flatifier simgrid)
 endif(NOT WIN32)