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