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