Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[surf] Remove sg_cabinet_cb
[simgrid.git] / src / xbt / lib.c
1 /* lib - a generic library, variation over dictionary                    */
2
3 /* Copyright (c) 2011, 2013-2015. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include <xbt/sysdep.h>
10 #include <xbt/log.h>
11 #include <xbt/lib.h>
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_lib, xbt,
14                                 "A dict with keys of type (name, level)");
15
16 xbt_lib_t xbt_lib_new(void)
17 {
18   xbt_lib_t lib;
19   lib = xbt_new(s_xbt_lib_t, 1);
20   lib->dict = xbt_dict_new_homogeneous(xbt_free_f);
21   lib->levels = 0;
22   lib->free_f = NULL;
23   return lib;
24 }
25
26 void xbt_lib_free(xbt_lib_t *plib)
27 {
28   xbt_lib_t lib = *plib;
29   if (lib) {
30     xbt_dict_cursor_t cursor;
31     char *key;
32     void **elts;
33     xbt_dict_foreach (lib->dict, cursor, key, elts) {
34       int i;
35       for (i = 0 ; i < lib->levels ; i++)
36         if (elts[i] && lib->free_f[i])
37           lib->free_f[i](elts[i]);
38     }
39     xbt_dict_free(&lib->dict);
40     xbt_free(lib->free_f);
41     xbt_free(lib);
42     *plib = NULL;
43   }
44 }
45
46 int xbt_lib_add_level(xbt_lib_t lib, void_f_pvoid_t free_f)
47 {
48   XBT_DEBUG("xbt_lib_add_level");
49   xbt_assert(xbt_dict_is_empty(lib->dict),
50              "Lib is not empty, cannot add a level");
51   lib->free_f = xbt_realloc(lib->free_f,
52                             sizeof(void_f_pvoid_t) * (lib->levels + 1));
53   lib->free_f[lib->levels] = free_f;
54   return lib->levels++;
55 }
56
57 void xbt_lib_set(xbt_lib_t lib, const char *key, int level, void *obj)
58 {
59   XBT_DEBUG("xbt_lib_set key '%s:%d' with object %p", key, level, obj);
60   void **elts = xbt_dict_get_or_null(lib->dict, key);
61   if (!elts) {
62     elts = xbt_new0(void *, lib->levels);
63     xbt_dict_set(lib->dict, key, elts, NULL);
64   }
65   if (elts[level]) {
66     XBT_DEBUG("Replace %p by %p element under key '%s:%d'",
67               elts[level], obj, key, level);
68     if (lib->free_f[level])
69         lib->free_f[level](elts[level]);
70   }
71   elts[level] = obj;
72 }
73
74 void xbt_lib_unset(xbt_lib_t lib, const char *key, int level, int invoke_callback)
75 {
76   void **elts = xbt_dict_get_or_null(lib->dict, key);
77   if (!elts) {
78      XBT_WARN("no key %s", key);
79      return;
80   }
81
82   void *obj = elts[level];
83   if (!obj) {
84      XBT_WARN("no key %s at level %d", key, level);
85      return;
86   }
87
88   XBT_DEBUG("Remove %p of key %s at level %d", obj, key, level);
89   elts[level] = NULL;
90
91   /* check if there still remains any elements of this key */
92   int empty = 1;
93   int i;
94   for (i = 0; i < lib->levels && empty; i++) {
95      if (elts[i] != NULL)
96        empty = 0;
97   }
98   if (empty) {
99     /* there is no element at any level, so delete the key */
100     xbt_dict_remove(lib->dict, key);
101   }
102
103   if (invoke_callback && lib->free_f[level])
104     lib->free_f[level](obj);
105 }
106
107 void *xbt_lib_get_or_null(xbt_lib_t lib, const char *key, int level)
108 {
109   void **elts = xbt_dict_get_or_null(lib->dict, key);
110   return elts ? elts[level] : NULL;
111 }
112
113 xbt_dictelm_t xbt_lib_get_elm_or_null(xbt_lib_t lib, const char *key)
114 {
115   return xbt_dict_get_elm_or_null(lib->dict, key);
116 }
117
118 void *xbt_lib_get_level(xbt_dictelm_t elm, int level){
119   void **elts = elm->content;
120   return elts ? elts[level] : NULL;
121 }
122
123 void xbt_lib_remove(xbt_lib_t lib, const char *key){
124   xbt_dict_remove(lib->dict, key);
125 }