cscvs to tla changeset 3
[onak.git] / hash.c
1 /*
2  * hash.c - hashing routines mainly used for caching key details.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2000-2002 Project Purple
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "hash.h"
13 #include "keydb.h"
14 #include "keyid.h"
15 #include "ll.h"
16 #include "stats.h"
17
18 /**
19  *      hashtable - the hash table array.
20  */
21 static struct ll *hashtable[HASHSIZE];
22
23 /**
24  *      elements - the number of elements in the hash table.
25  */
26 static unsigned long elements;
27
28 /**
29  *      inithash - Initialize the hash ready for use.
30  */
31 void inithash(void)
32 {
33         unsigned int i;
34
35         for (i = 0; i < HASHSIZE; i++) {
36                 hashtable[i] = NULL;
37         }
38         elements = 0;
39 }
40
41 void addtohash(struct stats_key *key)
42 {
43         ++elements;
44         hashtable[key->keyid & HASHMASK]=
45                 lladd(hashtable[key->keyid & HASHMASK], key);
46 }
47
48 /**
49  *      createandaddtohash - Creates a key and adds it to the hash.
50  *      @keyid: The key to create and add.
51  *
52  *      Takes a key, checks if it exists in the hash and if not creates it
53  *      and adds it to the hash. Returns the key from the hash whether it
54  *      already existed or we just created it.
55  */
56 struct stats_key *createandaddtohash(uint64_t keyid)
57 {
58         struct stats_key *tmpkey;
59
60         /*
61          * Check if the key already exists and if not create and add it.
62          */
63         tmpkey = findinhash(keyid);
64         if (tmpkey == NULL) {
65                 tmpkey = malloc(sizeof(*tmpkey));
66                 memset(tmpkey, 0, sizeof(*tmpkey));
67                 tmpkey->keyid = keyid;
68                 addtohash(tmpkey);
69         }
70         return tmpkey;
71 }
72
73 int stats_key_cmp(struct stats_key *key, uint64_t *keyid)
74 {
75         return !(key != NULL && key->keyid == *keyid);
76 }
77
78 struct stats_key *findinhash(uint64_t keyid)
79 {
80         int (*p)();
81         struct ll *found;
82
83         p = stats_key_cmp;
84         if ((found = llfind(hashtable[keyid & HASHMASK], &keyid, p))==NULL) {
85                 return NULL;
86         }
87         return found->object;
88 }
89
90 unsigned long hashelements(void)
91 {
92         return elements;
93 }
94
95 struct ll *gethashtableentry(int entry)
96 {
97         return hashtable[entry];
98 }
99
100 /**
101  *      hash_getkeysigs - Gets the signatures on a key.
102  *      @keyid: The key we want the signatures for.
103  *      
104  *      This function gets the signatures on a key. It's the same as the
105  *      getkeysigs function from the keydb module except we also cache the data
106  *      so that if we need it again we already have it available.
107  */
108 struct ll *hash_getkeysigs(uint64_t keyid)
109 {
110         struct stats_key *key = NULL;
111
112         key = findinhash(keyid);
113         if (key == NULL) {
114                 key = malloc(sizeof(*key));
115                 if (key != NULL) {
116                         key->keyid = keyid;
117                         key->colour = 0;
118                         key->parent = 0;
119                         key->sigs = NULL;
120                         key->gotsigs = false;
121                         addtohash(key);
122                 } else {
123                         perror("hash_getkeysigs()");
124                         return NULL;
125                 }
126         }
127         if (key->gotsigs == false) {
128                 key->sigs = getkeysigs(key->keyid);
129                 key->gotsigs = true;
130         }
131
132         return key->sigs;
133 }