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