source: tags/svn.1.5.4/AISC_COM/C/struct_man.c

Last change on this file was 8313, checked in by westram, 12 years ago
  • removed dead code

(partly reverted by [8316])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
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
29struct aisc_hash_node {
30    char           *key;
31    long            data;
32    aisc_hash_node *next;
33};
34
35
36static 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
45static 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
56static void aisc_free_key(aisc_hash_node **table, char *key) {
57    long            i, size;
58    aisc_hash_node *hn, *hhn;
59
60    if (table && table[0]) {
61        size = table[0]->data;
62        i = aisc_hash(key, (int)size);
63
64        for (hn = hhn = table[i]; hn; hn = hn->next) {
65            if (strcmp(key, hn->key)) {
66                hhn = hn;
67                continue;
68            }
69            if (hn != hhn)
70                hhn->next = hn->next;
71            else {
72                table[i] = hhn->next;
73            }
74            free(hn->key);
75            free(hn);
76            break;
77        }
78    }
79}
80
81static void aisc_free_hash(aisc_hash_node **table)
82{
83    long            i, end;
84    aisc_hash_node *hn, *hnn;
85
86    end = table[0]->data;
87    for (i=0; i<end; i++) {
88        for (hn = table[i]; hn; hn=hnn) {
89            hnn = hn->next;
90            free(hn->key);
91            free(hn);
92        }
93    }
94    free(table);
95}
96
97
98static void aisc_insert_hash(aisc_hash_node **table, char *key, long data)
99{
100    long            i, size;
101    aisc_hash_node *hn, *hnl;
102
103    size = table[0]->data;
104    i = aisc_hash(key, (int)size);
105    hnl = 0;
106    for (hn=table[i]; hn; hn=hn->next) {
107        hnl = hn;
108        if (strcmp(key, hn->key) == 0) {
109            hn->data = data;
110            return;
111        };
112    };
113    hn = (aisc_hash_node *)calloc(sizeof(aisc_hash_node), 1);
114    hn->key = (char *)strdup(key);
115    hn->data = data;
116    if (hnl) {
117        hnl->next = hn;
118    }
119    else {
120        table[i] = hn;
121    }
122}
123
124long aisc_read_hash(aisc_hash_node **table, const char *key) {
125    long            i, size;
126    aisc_hash_node *hn;
127
128    if (table && table[0]) {
129        size = table[0]->data;
130        i = aisc_hash(key, (int)size);
131        for (hn=table[i]; hn; hn=hn->next) {
132            if (strcmp(key, hn->key) == 0) return hn->data;
133        }
134    }
135    return 0;
136}
137
138// ----------------------
139//      link control
140
141const char *aisc_link(dllpublic_ext *father, dllheader_ext *object) {
142    if (!object) {
143        CORE;
144        return "Object is (NULL)";
145    }
146    if (object->mh.parent) {
147        CORE;
148        return "Object already linked";
149    }
150    if (!father) {
151        CORE;
152        return "Parent is (NULL)";
153    }
154    if (father->key != object->mh.key) {
155        CORE;
156        return "Parent key doesn't match Object key";
157    }
158    if (object->mh.ident) {
159        if (strlen(object->mh.ident) <= 0) {
160            CORE;
161            return "Too short ident";
162        }
163        if (father->hash) {
164            if (aisc_read_hash((aisc_hash_node **)father->hash, object->mh.ident)) {
165                CORE;
166                return "Object already in list";
167            }
168            else {
169                aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
170            }
171        }
172        else {
173            father->hash = (long)aisc_init_hash(HASH_SIZE);
174            aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
175        }
176    }
177    object->next = object->previous = NULL;
178    if (!father->first) {
179        father->cnt   = 1;
180        father->first = object;
181        father->last  = object;
182    }
183    else {
184        father->cnt++;
185        object->previous   = father->last;
186        father->last->next = object;
187        father->last       = object;
188    }
189    object->mh.parent = father;
190    return 0;
191}
192
193
194
195const char *aisc_unlink(dllheader_ext *object) {
196    dllpublic_ext *father = (dllpublic_ext *)object->mh.parent;
197
198    if (!father) {
199        CORE;
200        return "Object not linked";
201    }
202    if (father->hash) {
203        aisc_free_key((aisc_hash_node **)father->hash, object->mh.ident);
204    }
205    if (father->cnt <= 0) {
206        CORE;
207        return "Parent count is 0";
208    }
209    if (object->previous) {
210        if (object->previous->next != object) {
211            CORE;
212            return "Fatal Error: Object is a copy, not original";
213        }
214        object->previous->next = object->next;
215    }
216    else {
217        father->first = object->next;
218    }
219    if (object->next) {
220        object->next->previous = object->previous;
221    }
222    else {
223        father->last = object->previous;
224    }
225    object->mh.parent = NULL;
226    object->previous  = NULL;
227    object->next      = NULL;
228
229    father->cnt--;
230    if (!father->cnt) {
231        if (father->hash) {
232            aisc_free_hash((aisc_hash_node **)father->hash);
233            father->hash = 0;
234        }
235    }
236    return 0;
237}
238
239long aisc_find_lib(dllpublic_ext *parent, char *ident)
240{
241    if (!parent->hash) return 0;
242    if (!ident) return 0;
243    return aisc_read_hash((aisc_hash_node **)parent->hash, ident);
244}
245
246
247struct trf_dest_struct {
248    struct trf_dest_struct *next;
249    long                   *dest;
250};
251
252struct trf_struct {
253    struct trf_struct      *next;
254    long                    new_item;
255    long                    old;
256    struct trf_dest_struct *dests;
257};
258
259static int trf_hash(long p)
260{
261    return (p+(p>>8))&(TRF_HASH_SIZE-1);
262}
263
264static int trf_level = 0;
265static struct trf_struct **trf_sp = 0;
266
267void trf_create(long old, long new_item) {
268    long i;
269    struct trf_struct *ts;
270    struct trf_dest_struct *tds, *ntds;
271    if (!trf_sp) return;
272    i = trf_hash(old);
273    for (ts = trf_sp[i]; ts; ts = ts->next) {
274        if (ts->old == old) {
275            if (ts->new_item && (ts->new_item != new_item)) {
276                fprintf(stderr, "ERROR IN trf_create:\n");
277                *(int *) NULL = 0;
278            }
279            else {
280                ts->new_item = new_item;
281                for (tds = ts->dests; tds; tds = ntds) {
282                    *tds->dest = new_item;
283                    ntds = tds->next;
284                    free(tds);
285                }
286            }
287            return;
288        }
289    }
290    ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
291    ts->next = trf_sp[i];
292    trf_sp[i] = ts;
293    ts->new_item = new_item;
294    ts->old = old;
295}
296
297void trf_link(long old, long *dest)
298{
299    long i;
300    struct trf_struct *ts, *fts;
301    struct trf_dest_struct *tds;
302    if (!trf_sp) return;
303    i = trf_hash(old);
304    fts = 0;
305    for (ts = trf_sp[i]; ts; ts = ts->next) {
306        if (ts->old == old)     { fts = ts; break; }
307    }
308    if (!fts) {
309        ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
310        ts->next = trf_sp[i];
311        trf_sp[i] = ts;
312        ts->old = old;
313        fts = ts;
314    }
315    tds = (struct trf_dest_struct *)calloc(sizeof(struct trf_dest_struct), 1);
316    tds->next = fts->dests;
317    fts->dests = tds;
318    tds->dest = dest;
319}
320
321void trf_begin() {
322    if (trf_level==0) {
323        trf_sp = (struct trf_struct **)calloc(sizeof(struct trf_struct *), TRF_HASH_SIZE);
324    }
325    trf_level ++;
326}
327
328void trf_commit(int errors) {
329    // if errors == 1 then print errors and CORE
330    int i;
331    struct trf_dest_struct *tds, *ntds;
332    struct trf_struct *ts, *nts;
333    trf_level --;
334    if (!trf_level) {
335        for (i = 0; i < TRF_HASH_SIZE; i++) {
336            for (ts = trf_sp[i]; ts; ts = nts) {
337                if (errors) {
338                    if (ts->dests) {
339                        fprintf(stderr, "ERROR IN trf_commit:\n");
340                        *(int *) NULL = 0;
341                    }
342                }
343                else {
344                    for (tds = ts->dests; tds; tds = ntds) {
345                        ntds = tds->next;
346                        free(tds);
347                    }
348                }
349                nts = ts->next;
350                free(ts);
351            }
352        }
353        free(trf_sp);
354        trf_sp = 0;
355    }
356}
357
Note: See TracBrowser for help on using the repository browser.