ARB
struct_man.c
Go to the documentation of this file.
1 // ==============================================================
2 /* */
3 // File : struct_man.c
4 // Purpose :
5 /* */
6 // Institute of Microbiology (Technical University Munich)
7 // http://www.arb-home.de/
8  /* */
9  // ==============================================================
10 
11 
12 #include <aisc.h>
13 #include <struct_man.h>
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 // AISC_MKPT_PROMOTE:struct aisc_hash_node;
20 
21 // ---------------------
22 // hash tables
23 
24 
25 #define CORE
26 #define HASH_SIZE 103123
27 #define TRF_HASH_SIZE 103123
28 
30  char *key;
31  long data;
33 };
34 
35 
36 static aisc_hash_node **aisc_init_hash(int size) {
37  struct aisc_hash_node **tab;
38  tab = (aisc_hash_node **) calloc(sizeof(aisc_hash_node *), size);
39  tab[0] = (aisc_hash_node *) calloc(sizeof(aisc_hash_node), 1);
40  tab[0]->data = size;
41  tab[0]->key = (char *)strdup("len_of_hash_table_(c) oliver_strunk 1.3.93");
42  return tab;
43 }
44 
45 static int aisc_hash(const char *key, int size) {
46  unsigned int i, len, x;
47  len = strlen(key);
48  x = 0;
49  for (i=0; i<len; i++) {
50  x = x<<2 ^ key[i];
51  }
52  x = x%size;
53  return x;
54 }
55 
56 static void aisc_free_key(aisc_hash_node **table, char *key) {
57  if (table && table[0]) {
58  long size = table[0]->data;
59  long i = aisc_hash(key, (int)size);
60 
61  aisc_hash_node *hn, *hhn;
62  for (hn = hhn = table[i]; hn; hn = hn->next) {
63  if (strcmp(key, hn->key)) {
64  hhn = hn;
65  continue;
66  }
67  if (hn != hhn)
68  hhn->next = hn->next;
69  else {
70  table[i] = hhn->next;
71  }
72  free(hn->key);
73  free(hn);
74  break;
75  }
76  }
77 }
78 
79 static void aisc_free_hash(aisc_hash_node **table) {
80  long end = table[0]->data;
81  for (long i=0; i<end; i++) {
82  aisc_hash_node *hn, *hnn;
83  for (hn = table[i]; hn; hn=hnn) {
84  hnn = hn->next;
85  free(hn->key);
86  free(hn);
87  }
88  }
89  free(table);
90 }
91 
92 
93 static void aisc_insert_hash(aisc_hash_node **table, char *key, long data) {
94  long size = table[0]->data;
95  long i = aisc_hash(key, (int)size);
96 
97  aisc_hash_node *hnl = NULp;
98  aisc_hash_node *hn;
99  for (hn=table[i]; hn; hn=hn->next) {
100  hnl = hn;
101  if (strcmp(key, hn->key) == 0) {
102  hn->data = data;
103  return;
104  }
105  }
106  hn = (aisc_hash_node *)calloc(sizeof(aisc_hash_node), 1);
107  hn->key = (char *)strdup(key);
108  hn->data = data;
109  if (hnl) {
110  hnl->next = hn;
111  }
112  else {
113  table[i] = hn;
114  }
115 }
116 
117 long aisc_read_hash(aisc_hash_node **table, const char *key) {
118  if (table && table[0]) {
119  long size = table[0]->data;
120  long i = aisc_hash(key, (int)size);
121  for (aisc_hash_node *hn=table[i]; hn; hn=hn->next) {
122  if (strcmp(key, hn->key) == 0) return hn->data;
123  }
124  }
125  return 0;
126 }
127 
128 // ----------------------
129 // link control
130 
131 const char *aisc_link(dllpublic_ext *father, dllheader_ext *object) {
132  if (!object) {
133  CORE;
134  return "Object is (NULp)";
135  }
136  if (object->mh.parent) {
137  CORE;
138  return "Object already linked";
139  }
140  if (!father) {
141  CORE;
142  return "Parent is (NULp)";
143  }
144  if (father->key != object->mh.key) {
145  CORE;
146  return "Parent key doesn't match Object key";
147  }
148  if (object->mh.ident) {
149  if (strlen(object->mh.ident) <= 0) {
150  CORE;
151  return "Too short ident";
152  }
153  if (father->hash) {
154  if (aisc_read_hash((aisc_hash_node **)father->hash, object->mh.ident)) {
155  CORE;
156  return "Object already in list";
157  }
158  else {
159  aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
160  }
161  }
162  else {
163  father->hash = (long)aisc_init_hash(HASH_SIZE);
164  aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
165  }
166  }
167  object->next = object->previous = NULp;
168  if (!father->first) {
169  father->cnt = 1;
170  father->first = object;
171  father->last = object;
172  }
173  else {
174  father->cnt++;
175  object->previous = father->last;
176  father->last->next = object;
177  father->last = object;
178  }
179  object->mh.parent = father;
180  return NULp;
181 }
182 
183 
184 
185 const char *aisc_unlink(dllheader_ext *object) {
186  dllpublic_ext *father = (dllpublic_ext *)object->mh.parent;
187 
188  if (!father) {
189  CORE;
190  return "Object not linked";
191  }
192  if (father->hash) {
193  aisc_free_key((aisc_hash_node **)father->hash, object->mh.ident);
194  }
195  if (father->cnt <= 0) {
196  CORE;
197  return "Parent count is 0";
198  }
199  if (object->previous) {
200  if (object->previous->next != object) {
201  CORE;
202  return "Fatal Error: Object is a copy, not original";
203  }
204  object->previous->next = object->next;
205  }
206  else {
207  father->first = object->next;
208  }
209  if (object->next) {
210  object->next->previous = object->previous;
211  }
212  else {
213  father->last = object->previous;
214  }
215  object->mh.parent = NULp;
216  object->previous = NULp;
217  object->next = NULp;
218 
219  father->cnt--;
220  if (!father->cnt) {
221  if (father->hash) {
222  aisc_free_hash((aisc_hash_node **)father->hash);
223  father->hash = 0;
224  }
225  }
226  return NULp;
227 }
228 
229 long aisc_find_lib(dllpublic_ext *parent, char *ident) {
230  if (!parent->hash) return 0;
231  if (!ident) return 0;
232  return aisc_read_hash((aisc_hash_node **)parent->hash, ident);
233 }
234 
235 
238  long *dest;
239 };
240 
241 struct trf_struct {
242  struct trf_struct *next;
243  long new_item;
244  long old;
246 };
247 
248 static int trf_hash(long p) {
249  return (p+(p>>8)) & (TRF_HASH_SIZE-1);
250 }
251 
252 static int trf_level = 0;
253 static struct trf_struct **trf_sp = NULp;
254 
255 void trf_create(long old, long new_item) {
256  long i;
257  struct trf_struct *ts;
258  struct trf_dest_struct *tds, *ntds;
259  if (!trf_sp) return;
260  i = trf_hash(old);
261  for (ts = trf_sp[i]; ts; ts = ts->next) {
262  if (ts->old == old) {
263  if (ts->new_item && (ts->new_item != new_item)) {
264  GBK_terminate("ERROR IN trf_create");
265  }
266  else {
267  ts->new_item = new_item;
268  for (tds = ts->dests; tds; tds = ntds) {
269  *tds->dest = new_item;
270  ntds = tds->next;
271  free(tds);
272  }
273  }
274  return;
275  }
276  }
277  ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
278  ts->next = trf_sp[i];
279  trf_sp[i] = ts;
280  ts->new_item = new_item;
281  ts->old = old;
282 }
283 
284 void trf_link(long old, long *dest) {
285  long i;
286  struct trf_struct *ts, *fts;
287  struct trf_dest_struct *tds;
288  if (!trf_sp) return;
289  i = trf_hash(old);
290  fts = NULp;
291  for (ts = trf_sp[i]; ts; ts = ts->next) {
292  if (ts->old == old) { fts = ts; break; }
293  }
294  if (!fts) {
295  ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
296  ts->next = trf_sp[i];
297  trf_sp[i] = ts;
298  ts->old = old;
299  fts = ts;
300  }
301  tds = (struct trf_dest_struct *)calloc(sizeof(struct trf_dest_struct), 1);
302  tds->next = fts->dests;
303  fts->dests = tds;
304  tds->dest = dest;
305 }
306 
307 void trf_begin() {
308  if (trf_level==0) {
309  trf_sp = (struct trf_struct **)calloc(sizeof(struct trf_struct *), TRF_HASH_SIZE);
310  }
311  trf_level ++;
312 }
313 
314 void trf_commit(int errors) {
315  // if errors == 1 then print errors and CORE
316  struct trf_dest_struct *tds, *ntds;
317  struct trf_struct *ts, *nts;
318  trf_level--;
319  if (!trf_level) {
320  for (int i = 0; i < TRF_HASH_SIZE; i++) {
321  for (ts = trf_sp[i]; ts; ts = nts) {
322  if (errors) {
323  if (ts->dests) {
324  GBK_terminate("ERROR IN trf_commit");
325  }
326  }
327  else {
328  for (tds = ts->dests; tds; tds = ntds) {
329  ntds = tds->next;
330  free(tds);
331  }
332  }
333  nts = ts->next;
334  free(ts);
335  }
336  }
337  free(trf_sp);
338  trf_sp = NULp;
339  }
340 }
341 
const char * aisc_unlink(dllheader_ext *object)
Definition: struct_man.c:185
long aisc_find_lib(dllpublic_ext *parent, char *ident)
Definition: struct_man.c:229
static aisc_hash_node ** aisc_init_hash(int size)
Definition: struct_man.c:36
static GB_ERROR tab(GBL_command_arguments *args, bool pretab)
Definition: adlang1.cxx:914
#define HASH_SIZE
Definition: struct_man.c:26
long
Definition: AW_awar.cxx:152
void trf_begin()
Definition: struct_man.c:307
static int trf_hash(long p)
Definition: struct_man.c:248
static int aisc_hash(const char *key, int size)
Definition: struct_man.c:45
struct trf_struct * next
Definition: struct_man.c:242
void trf_create(long old, long new_item)
Definition: struct_man.c:255
void trf_commit(int errors)
Definition: struct_man.c:314
void trf_link(long old, long *dest)
Definition: struct_man.c:284
POS_TREE1 * father
Definition: probe_tree.h:39
struct trf_dest_struct * dests
Definition: struct_man.c:245
static void aisc_insert_hash(aisc_hash_node **table, char *key, long data)
Definition: struct_man.c:93
struct trf_dest_struct * next
Definition: struct_man.c:237
aisc_hash_node * next
Definition: struct_man.c:32
void GBK_terminate(const char *error) __ATTR__NORETURN
Definition: arb_msg.cxx:509
#define TRF_HASH_SIZE
Definition: struct_man.c:27
static void aisc_free_key(aisc_hash_node **table, char *key)
Definition: struct_man.c:56
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
Definition: AW_awar.cxx:163
long aisc_read_hash(aisc_hash_node **table, const char *key)
Definition: struct_man.c:117
static struct trf_struct ** trf_sp
Definition: struct_man.c:253
const char * aisc_link(dllpublic_ext *father, dllheader_ext *object)
Definition: struct_man.c:131
static int trf_level
Definition: struct_man.c:252
long new_item
Definition: struct_man.c:243
#define NULp
Definition: cxxforward.h:116
#define CORE
Definition: struct_man.c:25
static void aisc_free_hash(aisc_hash_node **table)
Definition: struct_man.c:79