source: tags/arb_5.1/CONSENSUS_TREE/CT_hash.cxx

Last change on this file was 5390, checked in by westram, 16 years ago
  • TAB-Ex
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1/* Hashtabelle fuer parts */
2#include <stdio.h>
3#include <stdlib.h>
4
5#include <arbdb.h>
6#include <arbdbt.h>
7
8#include "CT_mem.hxx"
9#include "CT_part.hxx"
10#include "CT_hash.hxx"
11#include "CT_ntree.hxx"
12
13int Hash_max_count=0;
14HNODE *Hashlist[HASH_MAX];
15HNODE *Sortedlist = NULL;
16
17/** initalize Hashtable and free old data */
18void hash_init(void)
19{
20    Hash_max_count = 0;
21    hash_free();
22}
23
24
25/** set number of trees */
26void hash_settreecount(int tree_count)
27{
28    Tree_count = tree_count;
29}
30
31
32/** free Hashtable and Sortedlist */
33void hash_free(void)
34{
35    int i;
36    HNODE *hnp, *hnp_help;
37
38    for(i=0; i< HASH_MAX; i++) {
39        hnp = Hashlist[i];
40        while(hnp) {
41            hnp_help = hnp->next;
42            part_free(hnp->part);
43            free((char *)hnp);
44            hnp = hnp_help;
45        }
46        Hashlist[i] = NULL;
47    }
48
49    hnp = Sortedlist;
50    while(hnp) {
51        hnp_help = hnp->next;
52        part_free(hnp->part);
53        free((char *)hnp);
54        hnp = hnp_help;
55    }
56    Sortedlist = NULL;
57}
58
59
60/** return the first element (with the highest hitnumber) from the linear sorted
61    list and calculate percentile appearence of this parition in all trees and
62    calculate the average pathlength.
63    The element is removed from the list afterwards */
64PART *hash_getpart(void)
65{
66    HNODE *hnp;
67    PART *p;
68
69    if(!Sortedlist) return NULL;
70
71    hnp = Sortedlist;
72    Sortedlist = hnp->next;
73    p = hnp->part;
74    free((char *)hnp);
75    p->len /= (float) p->percent;
76    p->percent *= 10000;
77    p->percent /= Tree_count;
78
79    return  p;
80}
81
82
83/** insert part in hashtable with weight
84    @PARAMTER   part    the one to insert, is destructed afterwards
85    weight  the weight of the part                       */
86void hash_insert(PART *part, int weight)
87{
88    int key;
89    HNODE *hp;
90
91    part_standart(part);
92
93    key = part_key(part);
94    key %= HASH_MAX;
95
96    if(Hashlist[key]) {
97        for(hp=Hashlist[key]; hp; hp=hp->next) {
98            if(part_cmp(hp->part, part)) { /* if in list */
99                /* tree-add tree-id */
100                hp->part->percent += weight;
101                hp->part->len += ((float) weight) * part->len;
102                part_free(part);
103                if(hp->part->percent > Hash_max_count)
104                    Hash_max_count = hp->part->percent;
105                return;
106            }
107        }
108    }
109
110    /* Not yet in list -> insert */
111    hp = (HNODE *) getmem(sizeof(HNODE));
112    part->percent = weight;
113    part->len *= ((float) weight);
114    hp->part = part;
115    if(weight > Hash_max_count)
116        Hash_max_count = weight;
117
118    if(!Hashlist[key]) {
119        Hashlist[key] = hp;
120        return;
121    }
122
123    hp->next = Hashlist[key];
124    Hashlist[key] = hp;
125}
126
127
128/** sort the current hash list in a linear sorted list, the current hash
129    is empty afterwards. I use a simple trick speed up the function:
130    build for every hitnumber one list and put all elements with that hitnumber
131    in it. After that i conect the list together, what results in a sorted list
132*/
133void build_sorted_list(void)
134{
135    HNODE *hnp, *hnp_help;
136    HNODE **heads, **tails, *head, *tail;
137    int i, idx;
138
139    heads = (HNODE **) getmem(Hash_max_count*sizeof(HNODE *));
140    tails = (HNODE**)  getmem(Hash_max_count*sizeof(HNODE *));
141
142    /* build one list for each countvalue */
143
144    for(i=0; i< HASH_MAX; i++) {
145        hnp = Hashlist[i];
146        while(hnp) {
147            hnp_help = hnp->next;
148            idx = hnp->part->percent-1;
149            if(heads[idx]) {
150                hnp->next = heads[idx];
151                heads[idx] = hnp;
152            }
153            else {
154                heads[idx] = tails[idx] = hnp;
155                hnp->next = NULL;
156            }
157
158            hnp = hnp_help;
159        }
160        Hashlist[i] = NULL;
161    }
162
163    head = NULL;
164    tail = NULL;
165    /* concatinate lists */
166    for(i=Hash_max_count-1; i>=0; i--) {
167        if(heads[i]) {
168            if(!head) {
169                head = heads[i];
170                tail = tails[i];
171            }
172            else {
173                tail->next = heads[i];
174                tail = tails[i];
175            }
176        }
177    }
178
179    free((char *)heads);
180    free((char *)tails);
181
182    Sortedlist = head;
183}
184
185
186/** testfunction to print the hashtable */
187void hash_print(void)
188{
189    int i;
190    HNODE *hnp;
191
192    printf("\n HASHtable \n");
193
194    for(i=0; i< HASH_MAX; i++) {
195        printf("Key: %d \n", i);
196        hnp = Hashlist[i];
197        while(hnp) {
198            printf("node: count %d node ", hnp->part->percent);
199            part_print(hnp->part); printf(" (%d)\n", hnp->part->p[0]);
200            hnp = hnp->next;
201        }
202    }
203}
204
205
206/** testfunction to print the sorted linear list */
207void sorted_print(void)
208{
209    HNODE *hnp;
210
211    printf("\n sorted HASHlist \n");
212
213    hnp = Sortedlist;
214    while(hnp) {
215        printf("node: count %d node ", hnp->part->percent);
216        part_print(hnp->part); printf("\n");
217        hnp = hnp->next;
218    }
219}
Note: See TracBrowser for help on using the repository browser.