cscvs to tla changeset 10
[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 /**
42  *      destroyhash - Clean up the hash after use.
43  *
44  *      This function destroys the hash after use, freeing any memory that was
45  *      used during its lifetime.
46  */
47 void destroyhash(void)
48 {
49         int i;
50         struct ll *curll = NULL;
51         struct ll *nextll = NULL;
52
53         for (i = 0; i < HASHSIZE; i++) {
54                 curll = hashtable[i];
55                 while (curll != NULL) {
56                         nextll = curll->next;
57                         /*
58                          * TODO: The problem is the object has pointers that
59                          * need freed too.
60                          */
61                         free(curll->object);
62                         free(curll);
63                         curll = nextll;
64                 }
65                 hashtable[i] = NULL;
66         }
67         elements = 0;
68 }
69
70 /**
71  *      addtohash - Adds a key to the hash.
72  *      @key: The key to add.
73  *
74  *      Takes a key and stores it in the hash.
75  */
76 void addtohash(struct stats_key *key)
77 {
78         ++elements;
79         hashtable[key->keyid & HASHMASK]=
80                 lladd(hashtable[key->keyid & HASHMASK], key);
81 }
82
83 /**
84  *      createandaddtohash - Creates a key and adds it to the hash.
85  *      @keyid: The key to create and add.
86  *
87  *      Takes a key, checks if it exists in the hash and if not creates it
88  *      and adds it to the hash. Returns the key from the hash whether it
89  *      already existed or we just created it.
90  */
91 struct stats_key *createandaddtohash(uint64_t keyid)
92 {
93         struct stats_key *tmpkey;
94
95         /*
96          * Check if the key already exists and if not create and add it.
97          */
98         tmpkey = findinhash(keyid);
99         if (tmpkey == NULL) {
100                 tmpkey = malloc(sizeof(*tmpkey));
101                 memset(tmpkey, 0, sizeof(*tmpkey));
102                 tmpkey->keyid = keyid;
103                 addtohash(tmpkey);
104         }
105         return tmpkey;
106 }
107
108 int stats_key_cmp(struct stats_key *key, uint64_t *keyid)
109 {
110         return !(key != NULL && key->keyid == *keyid);
111 }
112
113 struct stats_key *findinhash(uint64_t keyid)
114 {
115         int (*p)();
116         struct ll *found;
117
118         p = stats_key_cmp;
119         if ((found = llfind(hashtable[keyid & HASHMASK], &keyid, p))==NULL) {
120                 return NULL;
121         }
122         return found->object;
123 }
124
125 unsigned long hashelements(void)
126 {
127         return elements;
128 }
129
130 struct ll *gethashtableentry(int entry)
131 {
132         return hashtable[entry];
133 }
134
135 /**
136  *      hash_getkeysigs - Gets the signatures on a key.
137  *      @keyid: The key we want the signatures for.
138  *      
139  *      This function gets the signatures on a key. It's the same as the
140  *      getkeysigs function from the keydb module except we also cache the data
141  *      so that if we need it again we already have it available.
142  */
143 struct ll *hash_getkeysigs(uint64_t keyid)
144 {
145         struct stats_key *key = NULL;
146
147         key = findinhash(keyid);
148         if (key == NULL) {
149                 key = malloc(sizeof(*key));
150                 if (key != NULL) {
151                         key->keyid = keyid;
152                         key->colour = 0;
153                         key->parent = 0;
154                         key->sigs = NULL;
155                         key->gotsigs = false;
156                         addtohash(key);
157                 } else {
158                         perror("hash_getkeysigs()");
159                         return NULL;
160                 }
161         }
162         if (key->gotsigs == false) {
163                 key->sigs = getkeysigs(key->keyid);
164                 key->gotsigs = true;
165         }
166
167         return key->sigs;
168 }