cscvs to tla changeset 79
[onak.git] / stats.c
1 /*
2  * stats.c - various routines to do stats on the key graph
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2000-2002 Project Purple
7  *
8  * $Id: stats.c,v 1.11 2003/06/04 22:32:56 noodles Exp $
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include "getcgi.h"
15 #include "hash.h"
16 #include "keydb.h"
17 #include "ll.h"
18 #include "stats.h"
19
20 /**
21  *      initcolour - Clear the key graph ready for use.
22  *      @parent: Do we want to clear the parent pointers too?
23  *
24  *      Clears the parent and colour information on all elements in the key
25  *      graph.
26  */
27 void initcolour(bool parent)
28 {
29         unsigned long loop;
30         struct ll *curkey;
31
32         /*
33          * Init the colour/parent values. We get each entry list from the hash
34          * table and walk along it, zeroing the values.
35          */
36         for (loop = 0; loop < HASHSIZE; loop++) {
37                 curkey = gethashtableentry(loop);
38                 while (curkey != NULL) {
39                         ((struct stats_key *)curkey->object)->colour = 0;
40                         if (parent) {
41                                 ((struct stats_key *)curkey->object)->parent =
42                                         0;
43                         }
44                         curkey = curkey->next;
45                 }
46         }
47 }
48
49 /**
50  *      findpath - Given 2 keys finds a path between them.
51  *      @have: The key we have.
52  *      @want: The key we want to get to.
53  *
54  *      This does a breadth first search on the key tree, starting with the
55  *      key we have. It returns as soon as a path is found or when we run out
56  *      of keys; whichever comes sooner.
57  */
58 unsigned long findpath(struct stats_key *have, struct stats_key *want)
59 {
60         struct ll *keys = NULL;
61         struct ll *oldkeys = NULL;
62         struct ll *sigs = NULL;
63         struct ll *nextkeys = NULL;
64         long curdegree = 0;
65         long count = 0;
66         
67         curdegree = 1;
68         keys = lladd(NULL, want);
69         oldkeys = keys;
70
71         while (keys != NULL && have->colour == 0) {
72                 sigs = cached_getkeysigs(((struct stats_key *)
73                                         keys->object)->keyid);
74                 while (sigs != NULL && have->colour == 0) {
75                         /*
76                          * Check if we've seen this key before and if not mark
77                          * it and add its sigs to the list we want to look at.
78                          */
79                         if (!((struct stats_key *)sigs->object)->disabled &&
80                             ((struct stats_key *)sigs->object)->colour == 0) {
81                                 count++;
82                                 ((struct stats_key *)sigs->object)->colour =
83                                         curdegree;
84                                 ((struct stats_key *)sigs->object)->parent =
85                                         ((struct stats_key *)
86                                          keys->object)->keyid;
87                                 nextkeys = lladd(nextkeys, sigs->object);
88                         }
89                         sigs = sigs->next;
90                 }
91                 keys = keys->next;
92                 if (keys == NULL) {
93                         keys = nextkeys;
94                         llfree(oldkeys, NULL);
95                         oldkeys = keys;
96                         nextkeys = NULL;
97                         curdegree++;
98                 }
99         }
100         if (oldkeys != NULL) {
101                 llfree(oldkeys, NULL);
102                 oldkeys = NULL;
103         }
104         if (nextkeys != NULL) {
105                 llfree(nextkeys, NULL);
106                 nextkeys = NULL;
107         }
108
109         return count;
110 }
111
112 /**
113  *      dofindpath - Given 2 keys displays a path between them.
114  *      @have: The key we have.
115  *      @want: The key we want to get to.
116  *      @html: Should we output in html.
117  *      @count: How many paths we should look for.
118  *
119  *      This does a breadth first search on the key tree, starting with the
120  *      key we have. It returns as soon as a path is found or when we run out
121  *      of keys; whichever comes sooner.
122  */
123 void dofindpath(uint64_t have, uint64_t want, bool html, int count)
124 {
125         struct stats_key *keyinfoa, *keyinfob, *curkey;
126         uint64_t fullhave, fullwant;
127         int rec;
128         int pathnum;
129         char *uid;
130
131         fullhave = getfullkeyid(have);
132         fullwant = getfullkeyid(want);
133
134         /*
135          * Make sure the keys we have and want are in the cache.
136          */
137         cached_getkeysigs(fullhave);
138         cached_getkeysigs(fullwant);
139
140         if ((keyinfoa = findinhash(fullhave)) == NULL) {
141                 printf("Couldn't find key 0x%llX.\n", have);
142                 return;
143         }
144         if ((keyinfob = findinhash(fullwant)) == NULL) {
145                 printf("Couldn't find key 0x%llX.\n", want);
146                 return;
147         }
148
149         pathnum = 0;
150         
151         while (pathnum < count) {
152                 /*
153                  * Fill the tree info up.
154                  */
155                 initcolour(true);
156                 rec = findpath(keyinfoa, keyinfob);
157                 keyinfob->parent = 0;
158
159                 printf("%s%d nodes examined. %ld elements in the hash%s\n",
160                         html ? "<HR>" : "",
161                         rec,
162                         hashelements(),
163                         html ? "<BR>" : "");
164                 if (keyinfoa->colour == 0) {
165                         if (pathnum == 0) {
166                                 printf("Can't find a link from 0x%08llX to "
167                                 "0x%08llX%s\n",
168                                 have,
169                                 want,
170                                 html ? "<BR>" : "");
171                         } else {
172                                 printf("Can't find any further paths%s\n",
173                                         html ? "<BR>" : "");
174                         }
175                         pathnum = count;
176                 } else {
177                         printf("%d steps from 0x%08llX to 0x%08llX%s\n",
178                                 keyinfoa->colour, have & 0xFFFFFFFF,
179                                 want & 0xFFFFFFFF,
180                                 html ? "<BR>" : "");
181                         curkey = keyinfoa;
182                         while (curkey != NULL && curkey->keyid != 0) {
183                                 uid = keyid2uid(curkey->keyid);
184                                 if (html && uid == NULL) {
185                                         printf("<a href=\"lookup?op=get&search="
186                                                 "0x%08llX\">0x%08llX</a> (["
187                                                 "User id not found])%s<BR>\n",
188                                                 curkey->keyid & 0xFFFFFFFF,
189                                                 curkey->keyid & 0xFFFFFFFF,
190                                                 (curkey->keyid == fullwant) ?
191                                                         "" : " signs");
192                                 } else if (html && uid != NULL) {
193                                         printf("<a href=\"lookup?op=get&search="
194                                                 "0x%08llX\">0x%08llX</a>"
195                                                 " (<a href=\"lookup?op=vindex&"
196                                                 "search=0x%08llX\">%s</a>)%s"
197                                                 "<BR>\n",
198                                                 curkey->keyid & 0xFFFFFFFF,
199                                                 curkey->keyid & 0xFFFFFFFF,
200                                                 curkey->keyid & 0xFFFFFFFF,
201                                                 txt2html(uid),
202                                                 (curkey->keyid == fullwant) ?
203                                                 "" : " signs");
204                                 } else {
205                                         printf("0x%08llX (%s)%s\n",
206                                                 curkey->keyid & 0xFFFFFFFF,
207                                                 (uid == NULL) ?
208                                                         "[User id not found]" :
209                                                         uid,
210                                                 (curkey->keyid == fullwant) ?
211                                                 "" : " signs");
212                                 }
213                                 if (uid != NULL) {
214                                         free(uid);
215                                         uid = NULL;
216                                 }
217                                 if (curkey != keyinfoa && curkey != keyinfob) {
218                                         curkey->disabled = true;
219                                 }
220                                 curkey = findinhash(curkey->parent);
221                         }
222                         if (html) {
223                                 puts("<P>List of key ids in path:</P>");
224                         } else {
225                                 puts("List of key ids in path:");
226                         }
227                         curkey = keyinfoa;
228                         while (curkey != NULL && curkey->keyid != 0) {
229                                 printf("0x%08llX ", curkey->keyid & 0xFFFFFFFF);
230                                 curkey = findinhash(curkey->parent);
231                         }
232                         putchar('\n');
233                 }
234                 pathnum++;
235         }
236 }
237
238
239
240 struct stats_key *furthestkey(struct stats_key *have)
241 {
242         unsigned long count = 0;
243         unsigned long curdegree = 0;
244         struct ll *curll, *nextll, *tmp;
245         struct ll *sigs = NULL;
246         struct stats_key *max;
247
248         if (have == NULL) {
249                 return NULL;
250         }
251
252         ++curdegree;
253
254         nextll = NULL;
255         max = have;
256         curll = lladd(NULL, have);
257
258         while (curll != NULL) {
259                 sigs = cached_getkeysigs(((struct stats_key *)
260                                 curll->object)->keyid);
261                 while (sigs != NULL) {
262                         if (((struct stats_key *) sigs->object)->colour == 0) {
263                                 /*
264                                  * We've never seen it. Count it, mark it and
265                                  * explore its subtree.
266                                  */
267                                 count++;
268                                 max = (struct stats_key *)sigs->object;
269                                 ((struct stats_key *)sigs->object)->colour = 
270                                         curdegree;
271                                 ((struct stats_key *)sigs->object)->parent = 
272                                         ((struct stats_key *)
273                                          curll->object)->keyid;
274                                 
275                                 nextll=lladd(nextll, sigs->object);
276                         }
277                         sigs=sigs->next;
278                 }
279                 tmp = curll->next;
280                 free(curll);
281                 curll = tmp;
282                 if (curll == NULL) {
283                         curll = nextll;
284                         nextll = NULL;
285                         ++curdegree;
286                 };
287         }
288
289         return max;
290 }