Coverage Report

Created: 2023-04-12 06:22

/src/tor/src/ext/ht.h
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (c) 2002, Christopher Clark.
2
 * Copyright (c) 2005-2006, Nick Mathewson.
3
 * Copyright (c) 2007-2019, The Tor Project, Inc. */
4
/* See license at end. */
5
6
/* Based on ideas by Christopher Clark and interfaces from Niels Provos. */
7
8
/*
9
  These macros provide an intrustive implementation for a typesafe chaining
10
  hash table, loosely based on the BSD tree.h and queue.h macros.  Here's
11
  how to use them.
12
13
  First, pick a the structure that you'll be storing in the hashtable. Let's
14
  say that's  "struct dinosaur".  To this structure, you add an HT_ENTRY()
15
  member, as such:
16
17
      struct dinosaur {
18
          HT_ENTRY(dinosaur) node; // The name inside the () must match the
19
                                   // struct.
20
21
          // These are just fields from the dinosaur structure...
22
          long dinosaur_id;
23
          char *name;
24
          long age;
25
          int is_ornithischian;
26
          int is_herbivorous;
27
      };
28
29
  You can declare the hashtable itself as:
30
31
      HT_HEAD(dinosaur_ht, dinosaur);
32
33
  This declares a new 'struct dinosaur_ht' type.
34
35
  Now you need to declare two functions to help implement the hashtable: one
36
  compares two dinosaurs for equality, and one computes the hash of a
37
  dinosaur.  Let's say that two dinosaurs are equal if they have the same ID
38
  and name.
39
40
     int
41
     dinosaurs_equal(const struct dinosaur *d1, const struct dinosaur *d2)
42
     {
43
        return d1->dinosaur_id == d2->dinosaur_id &&
44
               0 == strcmp(d1->name, d2->name);
45
     }
46
47
     unsigned
48
     dinosaur_hash(const struct dinosaur *d)
49
     {
50
        // This is a very bad hash function. Use siphash24g instead.
51
        return (d->dinosaur_id + d->name[0] ) * 1337 + d->name[1] * 1337;
52
     }
53
54
  Now you'll need to declare the functions that manipulate the hash table.
55
  To do this, you put this declaration either in a header file, or inside
56
  a regular module, depending on what visibility you want.
57
58
     HT_PROTOTYPE(dinosaur_ht, // The name of the hashtable struct
59
                  dinosaur,    // The name of the element struct,
60
                  node,        // The name of HT_ENTRY member
61
                  dinosaur_hash, dinosaurs_equal);
62
63
  Later, inside a C function, you use this macro to declare the hashtable
64
  functions.
65
66
     HT_GENERATE2(dinosaur_ht, dinosaur, node, dinosaur_hash, dinosaurs_equal,
67
                  0.6, tor_reallocarray, tor_free_);
68
69
  Note the use of tor_free_, not tor_free.  The 0.6 is magic.
70
71
  Now you can use the hashtable!  You can initialize one with
72
73
     struct dinosaur_ht my_dinos = HT_INITIALIZER();
74
75
  Or create one in core with
76
77
     struct dinosaur_ht *dinos = tor_malloc(sizeof(dinosaur_ht));
78
     HT_INIT(dinosaur_ht, dinos);
79
80
  To the hashtable, you use the HT_FOO(dinosaur_ht, ...) macros.  For
81
  example, to put new_dino into dinos, you say:
82
83
     HT_REPLACE(dinosaur_ht, dinos, new_dino);
84
85
  If you're searching for an element, you need to use a dummy 'key' element in
86
  the search.  For example.
87
88
     struct dinosaur dino_key;
89
     dino_key.dinosaur_id = 12345;
90
     dino_key.name = tor_strdup("Atrociraptor");
91
92
     struct dinosaur *found = HT_FIND(dinosaurs_ht, dinos, &dino_key);
93
94
  Have fun with your hash table!
95
96
 */
97
98
#ifndef HT_H_INCLUDED_
99
#define HT_H_INCLUDED_
100
101
#define HT_HEAD(name, type)                                             \
102
  struct name {                                                         \
103
    /* The hash table itself. */                                        \
104
    struct type **hth_table;                                            \
105
    /* How long is the hash table? */                                   \
106
    unsigned hth_table_length;                                          \
107
    /* How many elements does the table contain? */                     \
108
    unsigned hth_n_entries;                                             \
109
    /* How many elements will we allow in the table before resizing it? */ \
110
    unsigned hth_load_limit;                                            \
111
    /* Position of hth_table_length in the primes table. */             \
112
    int hth_prime_idx;                                                  \
113
  }
114
115
#define HT_INITIALIZER()                        \
116
0
  { NULL, 0, 0, 0, -1 }
117
118
#ifdef HT_NO_CACHE_HASH_VALUES
119
#define HT_ENTRY(type)                          \
120
  struct {                                      \
121
    struct type *hte_next;                      \
122
  }
123
#else
124
#define HT_ENTRY(type)                          \
125
  struct {                                      \
126
    struct type *hte_next;                      \
127
    unsigned hte_hash;                          \
128
  }
129
#endif
130
131
/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
132
#define HT_EMPTY(head)                          \
133
0
  (((head)->hth_n_entries == 0) || 0)
134
135
/* How many elements in 'head'? */
136
#define HT_SIZE(head)                           \
137
0
  ((head)->hth_n_entries)
138
139
/* Return memory usage for a hashtable (not counting the entries themselves) */
140
#define HT_MEM_USAGE(head)                         \
141
0
  (sizeof(*head) + (head)->hth_table_length * sizeof(void*))
142
143
0
#define HT_FIND(name, head, elm)     name##_HT_FIND((head), (elm))
144
0
#define HT_INSERT(name, head, elm)   name##_HT_INSERT((head), (elm))
145
0
#define HT_REPLACE(name, head, elm)  name##_HT_REPLACE((head), (elm))
146
0
#define HT_REMOVE(name, head, elm)   name##_HT_REMOVE((head), (elm))
147
0
#define HT_START(name, head)         name##_HT_START(head)
148
0
#define HT_NEXT(name, head, elm)     name##_HT_NEXT((head), (elm))
149
0
#define HT_NEXT_RMV(name, head, elm) name##_HT_NEXT_RMV((head), (elm))
150
0
#define HT_CLEAR(name, head)         name##_HT_CLEAR(head)
151
0
#define HT_INIT(name, head)          name##_HT_INIT(head)
152
0
#define HT_REP_IS_BAD_(name, head)    name##_HT_REP_IS_BAD_(head)
153
#define HT_FOREACH_FN(name, head, fn, data) \
154
0
   name##_HT_FOREACH_FN((head), (fn), (data))
155
/* Helper: */
156
static inline unsigned
157
ht_improve_hash(unsigned h)
158
0
{
159
0
  /* Aim to protect against poor hash functions by adding logic here
160
0
   * - logic taken from java 1.4 hashtable source */
161
0
  h += ~(h << 9);
162
0
  h ^=  ((h >> 14) | (h << 18)); /* >>> */
163
0
  h +=  (h << 4);
164
0
  h ^=  ((h >> 10) | (h << 22)); /* >>> */
165
0
  return h;
166
0
}
Unexecuted instantiation: fuzzing_common.c:ht_improve_hash
Unexecuted instantiation: fuzz_hsdescv3_middle.c:ht_improve_hash
Unexecuted instantiation: config.c:ht_improve_hash
Unexecuted instantiation: control.c:ht_improve_hash
Unexecuted instantiation: control_auth.c:ht_improve_hash
Unexecuted instantiation: control_bootstrap.c:ht_improve_hash
Unexecuted instantiation: control_cmd.c:ht_improve_hash
Unexecuted instantiation: control_events.c:ht_improve_hash
Unexecuted instantiation: control_fmt.c:ht_improve_hash
Unexecuted instantiation: control_getinfo.c:ht_improve_hash
Unexecuted instantiation: control_hs.c:ht_improve_hash
Unexecuted instantiation: control_proto.c:ht_improve_hash
Unexecuted instantiation: describe.c:ht_improve_hash
Unexecuted instantiation: dirauth_config.c:ht_improve_hash
Unexecuted instantiation: dirauth_periodic.c:ht_improve_hash
Unexecuted instantiation: dirauth_sys.c:ht_improve_hash
Unexecuted instantiation: dirclient.c:ht_improve_hash
Unexecuted instantiation: dirclient_modes.c:ht_improve_hash
Unexecuted instantiation: directory.c:ht_improve_hash
Unexecuted instantiation: dirlist.c:ht_improve_hash
Unexecuted instantiation: dirserv.c:ht_improve_hash
Unexecuted instantiation: dirvote.c:ht_improve_hash
Unexecuted instantiation: dlstatus.c:ht_improve_hash
Unexecuted instantiation: dns.c:ht_improve_hash
Unexecuted instantiation: dnsserv.c:ht_improve_hash
Unexecuted instantiation: dsigs_parse.c:ht_improve_hash
Unexecuted instantiation: entrynodes.c:ht_improve_hash
Unexecuted instantiation: fmt_routerstatus.c:ht_improve_hash
Unexecuted instantiation: geoip_stats.c:ht_improve_hash
Unexecuted instantiation: getinfo_geoip.c:ht_improve_hash
Unexecuted instantiation: guardfraction.c:ht_improve_hash
Unexecuted instantiation: hibernate.c:ht_improve_hash
Unexecuted instantiation: hs_cache.c:ht_improve_hash
Unexecuted instantiation: hs_client.c:ht_improve_hash
Unexecuted instantiation: hs_common.c:ht_improve_hash
Unexecuted instantiation: hs_config.c:ht_improve_hash
Unexecuted instantiation: hs_control.c:ht_improve_hash
Unexecuted instantiation: hs_descriptor.c:ht_improve_hash
Unexecuted instantiation: hs_ident.c:ht_improve_hash
Unexecuted instantiation: hs_ob.c:ht_improve_hash
Unexecuted instantiation: hs_service.c:ht_improve_hash
Unexecuted instantiation: hs_stats.c:ht_improve_hash
Unexecuted instantiation: keypin.c:ht_improve_hash
Unexecuted instantiation: loadkey.c:ht_improve_hash
Unexecuted instantiation: main.c:ht_improve_hash
Unexecuted instantiation: metrics.c:ht_improve_hash
Unexecuted instantiation: microdesc.c:ht_improve_hash
Unexecuted instantiation: microdesc_parse.c:ht_improve_hash
Unexecuted instantiation: networkstatus.c:ht_improve_hash
Unexecuted instantiation: nickname.c:ht_improve_hash
Unexecuted instantiation: node_select.c:ht_improve_hash
Unexecuted instantiation: nodefamily.c:ht_improve_hash
Unexecuted instantiation: nodelist.c:ht_improve_hash
Unexecuted instantiation: ns_parse.c:ht_improve_hash
Unexecuted instantiation: onion_queue.c:ht_improve_hash
Unexecuted instantiation: predict_ports.c:ht_improve_hash
Unexecuted instantiation: process_descs.c:ht_improve_hash
Unexecuted instantiation: reachability.c:ht_improve_hash
Unexecuted instantiation: recommend_pkg.c:ht_improve_hash
Unexecuted instantiation: relay_config.c:ht_improve_hash
Unexecuted instantiation: relay_find_addr.c:ht_improve_hash
Unexecuted instantiation: rendcommon.c:ht_improve_hash
Unexecuted instantiation: rendmid.c:ht_improve_hash
Unexecuted instantiation: rephist.c:ht_improve_hash
Unexecuted instantiation: replaycache.c:ht_improve_hash
Unexecuted instantiation: resolve_addr.c:ht_improve_hash
Unexecuted instantiation: router.c:ht_improve_hash
Unexecuted instantiation: routerinfo.c:ht_improve_hash
Unexecuted instantiation: routerkeys.c:ht_improve_hash
Unexecuted instantiation: routerlist.c:ht_improve_hash
Unexecuted instantiation: routermode.c:ht_improve_hash
Unexecuted instantiation: routerparse.c:ht_improve_hash
Unexecuted instantiation: routerset.c:ht_improve_hash
Unexecuted instantiation: selftest.c:ht_improve_hash
Unexecuted instantiation: shared_random.c:ht_improve_hash
Unexecuted instantiation: shared_random_client.c:ht_improve_hash
Unexecuted instantiation: shared_random_state.c:ht_improve_hash
Unexecuted instantiation: shutdown.c:ht_improve_hash
Unexecuted instantiation: sigcommon.c:ht_improve_hash
Unexecuted instantiation: signing.c:ht_improve_hash
Unexecuted instantiation: statefile.c:ht_improve_hash
Unexecuted instantiation: torcert.c:ht_improve_hash
Unexecuted instantiation: transport_config.c:ht_improve_hash
Unexecuted instantiation: transports.c:ht_improve_hash
Unexecuted instantiation: unparseable.c:ht_improve_hash
Unexecuted instantiation: voteflags.c:ht_improve_hash
Unexecuted instantiation: voting_schedule.c:ht_improve_hash
Unexecuted instantiation: channel.c:ht_improve_hash
Unexecuted instantiation: channelpadding.c:ht_improve_hash
Unexecuted instantiation: channeltls.c:ht_improve_hash
Unexecuted instantiation: circuitbuild.c:ht_improve_hash
Unexecuted instantiation: circuitlist.c:ht_improve_hash
Unexecuted instantiation: circuitmux.c:ht_improve_hash
Unexecuted instantiation: circuitmux_ewma.c:ht_improve_hash
Unexecuted instantiation: circuitpadding.c:ht_improve_hash
Unexecuted instantiation: circuitpadding_machines.c:ht_improve_hash
Unexecuted instantiation: circuitstats.c:ht_improve_hash
Unexecuted instantiation: circuituse.c:ht_improve_hash
Unexecuted instantiation: command.c:ht_improve_hash
Unexecuted instantiation: congestion_control_common.c:ht_improve_hash
Unexecuted instantiation: congestion_control_flow.c:ht_improve_hash
Unexecuted instantiation: congestion_control_nola.c:ht_improve_hash
Unexecuted instantiation: congestion_control_vegas.c:ht_improve_hash
Unexecuted instantiation: congestion_control_westwood.c:ht_improve_hash
Unexecuted instantiation: connection.c:ht_improve_hash
Unexecuted instantiation: connection_edge.c:ht_improve_hash
Unexecuted instantiation: connection_or.c:ht_improve_hash
Unexecuted instantiation: cpuworker.c:ht_improve_hash
Unexecuted instantiation: crypt_path.c:ht_improve_hash
Unexecuted instantiation: dos.c:ht_improve_hash
Unexecuted instantiation: dos_sys.c:ht_improve_hash
Unexecuted instantiation: extendinfo.c:ht_improve_hash
Unexecuted instantiation: hs_ntor.c:ht_improve_hash
Unexecuted instantiation: mainloop.c:ht_improve_hash
Unexecuted instantiation: mainloop_pubsub.c:ht_improve_hash
Unexecuted instantiation: mainloop_sys.c:ht_improve_hash
Unexecuted instantiation: netstatus.c:ht_improve_hash
Unexecuted instantiation: ocirc_event.c:ht_improve_hash
Unexecuted instantiation: onion.c:ht_improve_hash
Unexecuted instantiation: onion_crypto.c:ht_improve_hash
Unexecuted instantiation: onion_fast.c:ht_improve_hash
Unexecuted instantiation: onion_tap.c:ht_improve_hash
Unexecuted instantiation: or_sys.c:ht_improve_hash
Unexecuted instantiation: orconn_event.c:ht_improve_hash
Unexecuted instantiation: periodic.c:ht_improve_hash
Unexecuted instantiation: policies.c:ht_improve_hash
Unexecuted instantiation: proto_cell.c:ht_improve_hash
Unexecuted instantiation: proto_control0.c:ht_improve_hash
Unexecuted instantiation: proto_http.c:ht_improve_hash
Unexecuted instantiation: proto_socks.c:ht_improve_hash
Unexecuted instantiation: protover.c:ht_improve_hash
Unexecuted instantiation: reasons.c:ht_improve_hash
Unexecuted instantiation: relay.c:ht_improve_hash
Unexecuted instantiation: relay_crypto.c:ht_improve_hash
Unexecuted instantiation: scheduler.c:ht_improve_hash
Unexecuted instantiation: scheduler_kist.c:ht_improve_hash
Unexecuted instantiation: scheduler_vanilla.c:ht_improve_hash
Unexecuted instantiation: sendme.c:ht_improve_hash
Unexecuted instantiation: status.c:ht_improve_hash
Unexecuted instantiation: versions.c:ht_improve_hash
Unexecuted instantiation: map.c:ht_improve_hash
Unexecuted instantiation: dispatch_naming.c:ht_improve_hash
Unexecuted instantiation: resolve.c:ht_improve_hash
Unexecuted instantiation: waitpid.c:ht_improve_hash
Unexecuted instantiation: sandbox.c:ht_improve_hash
Unexecuted instantiation: addressmap.c:ht_improve_hash
Unexecuted instantiation: authcert.c:ht_improve_hash
Unexecuted instantiation: authcert_parse.c:ht_improve_hash
Unexecuted instantiation: authmode.c:ht_improve_hash
Unexecuted instantiation: bridgeauth.c:ht_improve_hash
Unexecuted instantiation: bridges.c:ht_improve_hash
Unexecuted instantiation: btrack_circuit.c:ht_improve_hash
Unexecuted instantiation: btrack_orconn.c:ht_improve_hash
Unexecuted instantiation: btrack_orconn_cevent.c:ht_improve_hash
Unexecuted instantiation: btrack_orconn_maps.c:ht_improve_hash
Unexecuted instantiation: bwauth.c:ht_improve_hash
Unexecuted instantiation: bwhist.c:ht_improve_hash
Unexecuted instantiation: circpathbias.c:ht_improve_hash
Unexecuted instantiation: circuitbuild_relay.c:ht_improve_hash
Unexecuted instantiation: connstats.c:ht_improve_hash
Unexecuted instantiation: conscache.c:ht_improve_hash
Unexecuted instantiation: consdiff.c:ht_improve_hash
Unexecuted instantiation: consdiffmgr.c:ht_improve_hash
Unexecuted instantiation: dircache.c:ht_improve_hash
Unexecuted instantiation: dircollate.c:ht_improve_hash
Unexecuted instantiation: ext_orport.c:ht_improve_hash
Unexecuted instantiation: fp_pair.c:ht_improve_hash
Unexecuted instantiation: hs_cell.c:ht_improve_hash
Unexecuted instantiation: hs_circuit.c:ht_improve_hash
Unexecuted instantiation: hs_circuitmap.c:ht_improve_hash
Unexecuted instantiation: hs_dos.c:ht_improve_hash
Unexecuted instantiation: hs_intropoint.c:ht_improve_hash
Unexecuted instantiation: hs_metrics.c:ht_improve_hash
Unexecuted instantiation: hs_sys.c:ht_improve_hash
Unexecuted instantiation: metrics_sys.c:ht_improve_hash
Unexecuted instantiation: policy_parse.c:ht_improve_hash
Unexecuted instantiation: proxymode.c:ht_improve_hash
Unexecuted instantiation: relay_handshake.c:ht_improve_hash
Unexecuted instantiation: relay_periodic.c:ht_improve_hash
Unexecuted instantiation: relay_sys.c:ht_improve_hash
Unexecuted instantiation: or_periodic.c:ht_improve_hash
Unexecuted instantiation: proto_ext_or.c:ht_improve_hash
Unexecuted instantiation: namemap.c:ht_improve_hash
Unexecuted instantiation: relay_metrics.c:ht_improve_hash
167
168
#if 0
169
/** Basic string hash function, from Java standard String.hashCode(). */
170
static inline unsigned
171
ht_string_hash(const char *s)
172
{
173
  unsigned h = 0;
174
  int m = 1;
175
  while (*s) {
176
    h += ((signed char)*s++)*m;
177
    m = (m<<5)-1; /* m *= 31 */
178
  }
179
  return h;
180
}
181
#endif
182
183
#if 0
184
/** Basic string hash function, from Python's str.__hash__() */
185
static inline unsigned
186
ht_string_hash(const char *s)
187
{
188
  unsigned h;
189
  const unsigned char *cp = (const unsigned char *)s;
190
  h = *cp << 7;
191
  while (*cp) {
192
    h = (1000003*h) ^ *cp++;
193
  }
194
  /* This conversion truncates the length of the string, but that's ok. */
195
  h ^= (unsigned)(cp-(const unsigned char*)s);
196
  return h;
197
}
198
#endif
199
200
#ifndef HT_NO_CACHE_HASH_VALUES
201
#define HT_SET_HASH_(elm, field, hashfn)        \
202
0
    do { (elm)->field.hte_hash = hashfn(elm); } while (0)
203
#define HT_SET_HASHVAL_(elm, field, val)        \
204
    do { (elm)->field.hte_hash = (val); } while (0)
205
#define HT_ELT_HASH_(elm, field, hashfn)        \
206
0
    ((elm)->field.hte_hash)
207
#else
208
#define HT_SET_HASH_(elm, field, hashfn)        \
209
    ((void)0)
210
#define HT_ELT_HASH_(elm, field, hashfn)        \
211
    (hashfn(elm))
212
#define HT_SET_HASHVAL_(elm, field, val)        \
213
        ((void)0)
214
#endif
215
216
#define HT_BUCKET_NUM_(head, field, elm, hashfn)                        \
217
0
  (HT_ELT_HASH_(elm,field,hashfn) % head->hth_table_length)
218
219
/* Helper: alias for the bucket containing 'elm'. */
220
#define HT_BUCKET_(head, field, elm, hashfn)                            \
221
0
  ((head)->hth_table[HT_BUCKET_NUM_(head, field, elm, hashfn)])
222
223
#define HT_FOREACH(x, name, head)                 \
224
0
  for ((x) = HT_START(name, head);                \
225
0
       (x) != NULL;                               \
226
0
       (x) = HT_NEXT(name, head, x))
227
228
#ifndef HT_NDEBUG
229
#include "lib/err/torerr.h"
230
0
#define HT_ASSERT_(x) raw_assert(x)
231
#else
232
#define HT_ASSERT_(x) (void)0
233
#endif
234
235
/* Macro put at the end of the end of a macro definition so that it
236
 * consumes the following semicolon at file scope. Used only inside ht.h. */
237
#define HT_EAT_SEMICOLON__ struct ht_semicolon_eater
238
239
#define HT_PROTOTYPE(name, type, field, hashfn, eqfn)                   \
240
  int name##_HT_GROW(struct name *ht, unsigned min_capacity);           \
241
  void name##_HT_CLEAR(struct name *ht);                                \
242
  int name##_HT_REP_IS_BAD_(const struct name *ht);                     \
243
  static inline void                                                    \
244
0
  name##_HT_INIT(struct name *head) {                                   \
245
0
    head->hth_table_length = 0;                                         \
246
0
    head->hth_table = NULL;                                             \
247
0
    head->hth_n_entries = 0;                                            \
248
0
    head->hth_load_limit = 0;                                           \
249
0
    head->hth_prime_idx = -1;                                           \
250
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_INIT
Unexecuted instantiation: geoip_stats.c:clientmap_HT_INIT
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_INIT
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_INIT
Unexecuted instantiation: keypin.c:rsamap_HT_INIT
Unexecuted instantiation: keypin.c:edmap_HT_INIT
Unexecuted instantiation: microdesc.c:microdesc_map_HT_INIT
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_INIT
Unexecuted instantiation: nodelist.c:nodelist_map_HT_INIT
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_INIT
Unexecuted instantiation: channel.c:channel_gid_map_HT_INIT
Unexecuted instantiation: channel.c:channel_idmap_HT_INIT
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_INIT
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_INIT
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_INIT
Unexecuted instantiation: policies.c:policy_map_HT_INIT
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_INIT
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_INIT
Unexecuted instantiation: map.c:strmap_impl_HT_INIT
Unexecuted instantiation: map.c:digestmap_impl_HT_INIT
Unexecuted instantiation: map.c:digest256map_impl_HT_INIT
Unexecuted instantiation: waitpid.c:process_map_HT_INIT
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_INIT
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_INIT
Unexecuted instantiation: connstats.c:bidimap_HT_INIT
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_INIT
Unexecuted instantiation: dircollate.c:double_digest_map_HT_INIT
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_INIT
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_INIT
Unexecuted instantiation: namemap.c:namemap_ht_HT_INIT
251
  /* Helper: returns a pointer to the right location in the table       \
252
   * 'head' to find or insert the element 'elm'. */                     \
253
  static inline struct type **                                          \
254
  name##_HT_FIND_P_(struct name *head, struct type *elm)                \
255
0
  {                                                                     \
256
0
    struct type **p;                                                    \
257
0
    if (!head->hth_table)                                               \
258
0
      return NULL;                                                      \
259
0
    p = &HT_BUCKET_(head, field, elm, hashfn);                          \
260
0
    while (*p) {                                                        \
261
0
      if (eqfn(*p, elm))                                                \
262
0
        return p;                                                       \
263
0
      p = &(*p)->field.hte_next;                                        \
264
0
    }                                                                   \
265
0
    return p;                                                           \
266
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_FIND_P_
Unexecuted instantiation: geoip_stats.c:clientmap_HT_FIND_P_
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_FIND_P_
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_FIND_P_
Unexecuted instantiation: keypin.c:edmap_HT_FIND_P_
Unexecuted instantiation: keypin.c:rsamap_HT_FIND_P_
Unexecuted instantiation: microdesc.c:microdesc_map_HT_FIND_P_
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_FIND_P_
Unexecuted instantiation: nodelist.c:nodelist_map_HT_FIND_P_
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_FIND_P_
Unexecuted instantiation: channel.c:channel_gid_map_HT_FIND_P_
Unexecuted instantiation: channel.c:channel_idmap_HT_FIND_P_
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_FIND_P_
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_FIND_P_
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_FIND_P_
Unexecuted instantiation: policies.c:policy_map_HT_FIND_P_
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_FIND_P_
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_FIND_P_
Unexecuted instantiation: map.c:strmap_impl_HT_FIND_P_
Unexecuted instantiation: map.c:digestmap_impl_HT_FIND_P_
Unexecuted instantiation: map.c:digest256map_impl_HT_FIND_P_
Unexecuted instantiation: waitpid.c:process_map_HT_FIND_P_
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_FIND_P_
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_FIND_P_
Unexecuted instantiation: connstats.c:bidimap_HT_FIND_P_
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_FIND_P_
Unexecuted instantiation: dircollate.c:double_digest_map_HT_FIND_P_
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_FIND_P_
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_FIND_P_
Unexecuted instantiation: namemap.c:namemap_ht_HT_FIND_P_
267
  /* Return a pointer to the element in the table 'head' matching 'elm', \
268
   * or NULL if no such element exists */                               \
269
  ATTR_UNUSED static inline struct type *                               \
270
  name##_HT_FIND(const struct name *head, struct type *elm)             \
271
0
  {                                                                     \
272
0
    struct type **p;                                                    \
273
0
    struct name *h = (struct name *) head;                              \
274
0
    HT_SET_HASH_(elm, field, hashfn);                                   \
275
0
    p = name##_HT_FIND_P_(h, elm);                                      \
276
0
    return p ? *p : NULL;                                               \
277
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_FIND
Unexecuted instantiation: geoip_stats.c:clientmap_HT_FIND
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_FIND
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_FIND
Unexecuted instantiation: keypin.c:edmap_HT_FIND
Unexecuted instantiation: keypin.c:rsamap_HT_FIND
Unexecuted instantiation: microdesc.c:microdesc_map_HT_FIND
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_FIND
Unexecuted instantiation: nodelist.c:nodelist_map_HT_FIND
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_FIND
Unexecuted instantiation: channel.c:channel_idmap_HT_FIND
Unexecuted instantiation: channel.c:channel_gid_map_HT_FIND
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_FIND
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_FIND
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_FIND
Unexecuted instantiation: policies.c:policy_map_HT_FIND
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_FIND
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_FIND
Unexecuted instantiation: map.c:strmap_impl_HT_FIND
Unexecuted instantiation: map.c:digestmap_impl_HT_FIND
Unexecuted instantiation: map.c:digest256map_impl_HT_FIND
Unexecuted instantiation: waitpid.c:process_map_HT_FIND
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_FIND
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_FIND
Unexecuted instantiation: connstats.c:bidimap_HT_FIND
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_FIND
Unexecuted instantiation: dircollate.c:double_digest_map_HT_FIND
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_FIND
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_FIND
Unexecuted instantiation: namemap.c:namemap_ht_HT_FIND
278
  /* Insert the element 'elm' into the table 'head'.  Do not call this  \
279
   * function if the table might already contain a matching element. */ \
280
  ATTR_UNUSED static inline void                                        \
281
  name##_HT_INSERT(struct name *head, struct type *elm)                 \
282
0
  {                                                                     \
283
0
    struct type **p;                                                    \
284
0
    if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) \
285
0
      name##_HT_GROW(head, head->hth_n_entries+1);                      \
286
0
    ++head->hth_n_entries;                                              \
287
0
    HT_SET_HASH_(elm, field, hashfn);                                   \
288
0
    p = &HT_BUCKET_(head, field, elm, hashfn);                          \
289
0
    elm->field.hte_next = *p;                                           \
290
0
    *p = elm;                                                           \
291
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_INSERT
Unexecuted instantiation: geoip_stats.c:clientmap_HT_INSERT
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_INSERT
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_INSERT
Unexecuted instantiation: keypin.c:rsamap_HT_INSERT
Unexecuted instantiation: keypin.c:edmap_HT_INSERT
Unexecuted instantiation: microdesc.c:microdesc_map_HT_INSERT
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_INSERT
Unexecuted instantiation: nodelist.c:nodelist_map_HT_INSERT
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_INSERT
Unexecuted instantiation: channel.c:channel_idmap_HT_INSERT
Unexecuted instantiation: channel.c:channel_gid_map_HT_INSERT
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_INSERT
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_INSERT
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_INSERT
Unexecuted instantiation: policies.c:policy_map_HT_INSERT
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_INSERT
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_INSERT
Unexecuted instantiation: map.c:strmap_impl_HT_INSERT
Unexecuted instantiation: map.c:digestmap_impl_HT_INSERT
Unexecuted instantiation: map.c:digest256map_impl_HT_INSERT
Unexecuted instantiation: waitpid.c:process_map_HT_INSERT
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_INSERT
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_INSERT
Unexecuted instantiation: connstats.c:bidimap_HT_INSERT
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_INSERT
Unexecuted instantiation: dircollate.c:double_digest_map_HT_INSERT
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_INSERT
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_INSERT
Unexecuted instantiation: namemap.c:namemap_ht_HT_INSERT
292
  /* Insert the element 'elm' into the table 'head'. If there already   \
293
   * a matching element in the table, replace that element and return   \
294
   * it. */                                                             \
295
  ATTR_UNUSED static inline struct type *                               \
296
  name##_HT_REPLACE(struct name *head, struct type *elm)                \
297
0
  {                                                                     \
298
0
    struct type **p, *r;                                                \
299
0
    if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) \
300
0
      name##_HT_GROW(head, head->hth_n_entries+1);                      \
301
0
    HT_SET_HASH_(elm, field, hashfn);                                   \
302
0
    p = name##_HT_FIND_P_(head, elm);                                   \
303
0
    HT_ASSERT_(p != NULL); /* this holds because we called HT_GROW */   \
304
0
    r = *p;                                                             \
305
0
    *p = elm;                                                           \
306
0
    if (r && (r!=elm)) {                                                \
307
0
      elm->field.hte_next = r->field.hte_next;                          \
308
0
      r->field.hte_next = NULL;                                         \
309
0
      return r;                                                         \
310
0
    } else {                                                            \
311
0
      ++head->hth_n_entries;                                            \
312
0
      return NULL;                                                      \
313
0
    }                                                                   \
314
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_REPLACE
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_REPLACE
Unexecuted instantiation: geoip_stats.c:clientmap_HT_REPLACE
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_REPLACE
Unexecuted instantiation: keypin.c:rsamap_HT_REPLACE
Unexecuted instantiation: keypin.c:edmap_HT_REPLACE
Unexecuted instantiation: microdesc.c:microdesc_map_HT_REPLACE
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_REPLACE
Unexecuted instantiation: nodelist.c:nodelist_map_HT_REPLACE
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_REPLACE
Unexecuted instantiation: channel.c:channel_gid_map_HT_REPLACE
Unexecuted instantiation: channel.c:channel_idmap_HT_REPLACE
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_REPLACE
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_REPLACE
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_REPLACE
Unexecuted instantiation: policies.c:policy_map_HT_REPLACE
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_REPLACE
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_REPLACE
Unexecuted instantiation: map.c:strmap_impl_HT_REPLACE
Unexecuted instantiation: map.c:digestmap_impl_HT_REPLACE
Unexecuted instantiation: map.c:digest256map_impl_HT_REPLACE
Unexecuted instantiation: waitpid.c:process_map_HT_REPLACE
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_REPLACE
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_REPLACE
Unexecuted instantiation: connstats.c:bidimap_HT_REPLACE
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_REPLACE
Unexecuted instantiation: dircollate.c:double_digest_map_HT_REPLACE
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_REPLACE
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_REPLACE
Unexecuted instantiation: namemap.c:namemap_ht_HT_REPLACE
315
  /* Remove any element matching 'elm' from the table 'head'.  If such  \
316
   * an element is found, return it; otherwise return NULL. */          \
317
  ATTR_UNUSED static inline struct type *                               \
318
  name##_HT_REMOVE(struct name *head, struct type *elm)                 \
319
0
  {                                                                     \
320
0
    struct type **p, *r;                                                \
321
0
    HT_SET_HASH_(elm, field, hashfn);                                   \
322
0
    p = name##_HT_FIND_P_(head,elm);                                    \
323
0
    if (!p || !*p)                                                      \
324
0
      return NULL;                                                      \
325
0
    r = *p;                                                             \
326
0
    *p = r->field.hte_next;                                             \
327
0
    r->field.hte_next = NULL;                                           \
328
0
    --head->hth_n_entries;                                              \
329
0
    return r;                                                           \
330
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_REMOVE
Unexecuted instantiation: geoip_stats.c:clientmap_HT_REMOVE
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_REMOVE
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_REMOVE
Unexecuted instantiation: keypin.c:rsamap_HT_REMOVE
Unexecuted instantiation: keypin.c:edmap_HT_REMOVE
Unexecuted instantiation: microdesc.c:microdesc_map_HT_REMOVE
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_REMOVE
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_REMOVE
Unexecuted instantiation: nodelist.c:nodelist_map_HT_REMOVE
Unexecuted instantiation: channel.c:channel_gid_map_HT_REMOVE
Unexecuted instantiation: channel.c:channel_idmap_HT_REMOVE
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_REMOVE
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_REMOVE
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_REMOVE
Unexecuted instantiation: policies.c:policy_map_HT_REMOVE
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_REMOVE
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_REMOVE
Unexecuted instantiation: map.c:strmap_impl_HT_REMOVE
Unexecuted instantiation: map.c:digestmap_impl_HT_REMOVE
Unexecuted instantiation: map.c:digest256map_impl_HT_REMOVE
Unexecuted instantiation: waitpid.c:process_map_HT_REMOVE
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_REMOVE
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_REMOVE
Unexecuted instantiation: connstats.c:bidimap_HT_REMOVE
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_REMOVE
Unexecuted instantiation: dircollate.c:double_digest_map_HT_REMOVE
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_REMOVE
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_REMOVE
Unexecuted instantiation: namemap.c:namemap_ht_HT_REMOVE
331
  /* Invoke the function 'fn' on every element of the table 'head',     \
332
   * using 'data' as its second argument.  If the function returns      \
333
   * nonzero, remove the most recently examined element before invoking \
334
   * the function again. */                                             \
335
  ATTR_UNUSED static inline void                                        \
336
  name##_HT_FOREACH_FN(struct name *head,                               \
337
                       int (*fn)(struct type *, void *),                \
338
0
                       void *data)                                      \
339
0
{                                                                       \
340
0
    unsigned idx;                                                       \
341
0
    struct type **p, **nextp, *next;                                    \
342
0
    if (!head->hth_table)                                               \
343
0
      return;                                                           \
344
0
    for (idx=0; idx < head->hth_table_length; ++idx) {                  \
345
0
      p = &head->hth_table[idx];                                        \
346
0
      while (*p) {                                                      \
347
0
        nextp = &(*p)->field.hte_next;                                  \
348
0
        next = *nextp;                                                  \
349
0
        if (fn(*p, data)) {                                             \
350
0
          --head->hth_n_entries;                                        \
351
0
          *p = next;                                                    \
352
0
        } else {                                                        \
353
0
          p = nextp;                                                    \
354
0
        }                                                               \
355
0
      }                                                                 \
356
0
    }                                                                   \
357
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_FOREACH_FN
Unexecuted instantiation: geoip_stats.c:clientmap_HT_FOREACH_FN
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_FOREACH_FN
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_FOREACH_FN
Unexecuted instantiation: keypin.c:rsamap_HT_FOREACH_FN
Unexecuted instantiation: keypin.c:edmap_HT_FOREACH_FN
Unexecuted instantiation: microdesc.c:microdesc_map_HT_FOREACH_FN
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_FOREACH_FN
Unexecuted instantiation: nodelist.c:nodelist_map_HT_FOREACH_FN
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_FOREACH_FN
Unexecuted instantiation: channel.c:channel_gid_map_HT_FOREACH_FN
Unexecuted instantiation: channel.c:channel_idmap_HT_FOREACH_FN
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_FOREACH_FN
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_FOREACH_FN
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_FOREACH_FN
Unexecuted instantiation: policies.c:policy_map_HT_FOREACH_FN
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_FOREACH_FN
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_FOREACH_FN
Unexecuted instantiation: map.c:strmap_impl_HT_FOREACH_FN
Unexecuted instantiation: map.c:digestmap_impl_HT_FOREACH_FN
Unexecuted instantiation: map.c:digest256map_impl_HT_FOREACH_FN
Unexecuted instantiation: waitpid.c:process_map_HT_FOREACH_FN
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_FOREACH_FN
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_FOREACH_FN
Unexecuted instantiation: connstats.c:bidimap_HT_FOREACH_FN
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_FOREACH_FN
Unexecuted instantiation: dircollate.c:double_digest_map_HT_FOREACH_FN
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_FOREACH_FN
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_FOREACH_FN
Unexecuted instantiation: namemap.c:namemap_ht_HT_FOREACH_FN
358
  /* Return a pointer to the first element in the table 'head', under   \
359
   * an arbitrary order.  This order is stable under remove operations, \
360
   * but not under others. If the table is empty, return NULL. */       \
361
  ATTR_UNUSED static inline struct type **                              \
362
  name##_HT_START(struct name *head)                                    \
363
0
  {                                                                     \
364
0
    unsigned b = 0;                                                     \
365
0
    while (b < head->hth_table_length) {                                \
366
0
      if (head->hth_table[b]) {                                         \
367
0
        HT_ASSERT_(b ==                                                 \
368
0
                HT_BUCKET_NUM_(head,field,head->hth_table[b],hashfn));  \
369
0
        return &head->hth_table[b];                                     \
370
0
      }                                                                 \
371
0
      ++b;                                                              \
372
0
    }                                                                   \
373
0
    return NULL;                                                        \
374
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_START
Unexecuted instantiation: geoip_stats.c:clientmap_HT_START
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_START
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_START
Unexecuted instantiation: keypin.c:rsamap_HT_START
Unexecuted instantiation: keypin.c:edmap_HT_START
Unexecuted instantiation: microdesc.c:microdesc_map_HT_START
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_START
Unexecuted instantiation: nodelist.c:nodelist_map_HT_START
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_START
Unexecuted instantiation: channel.c:channel_idmap_HT_START
Unexecuted instantiation: channel.c:channel_gid_map_HT_START
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_START
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_START
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_START
Unexecuted instantiation: policies.c:policy_map_HT_START
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_START
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_START
Unexecuted instantiation: map.c:strmap_impl_HT_START
Unexecuted instantiation: map.c:digestmap_impl_HT_START
Unexecuted instantiation: map.c:digest256map_impl_HT_START
Unexecuted instantiation: waitpid.c:process_map_HT_START
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_START
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_START
Unexecuted instantiation: connstats.c:bidimap_HT_START
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_START
Unexecuted instantiation: dircollate.c:double_digest_map_HT_START
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_START
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_START
Unexecuted instantiation: namemap.c:namemap_ht_HT_START
375
  /* Return the next element in 'head' after 'elm', under the arbitrary \
376
   * order used by HT_START.  If there are no more elements, return     \
377
   * NULL.  If 'elm' is to be removed from the table, you must call     \
378
   * this function for the next value before you remove it, or use      \
379
   * HT_NEXT_RMV instead.                                               \
380
   */                                                                   \
381
  ATTR_UNUSED static inline struct type **                              \
382
  name##_HT_NEXT(struct name *head, struct type **elm)                  \
383
0
  {                                                                     \
384
0
    if ((*elm)->field.hte_next) {                                       \
385
0
      HT_ASSERT_(HT_BUCKET_NUM_(head,field,*elm,hashfn) ==              \
386
0
             HT_BUCKET_NUM_(head,field,(*elm)->field.hte_next,hashfn)); \
387
0
      return &(*elm)->field.hte_next;                                   \
388
0
    } else {                                                            \
389
0
      unsigned b = HT_BUCKET_NUM_(head,field,*elm,hashfn)+1;            \
390
0
      while (b < head->hth_table_length) {                              \
391
0
        if (head->hth_table[b]) {                                       \
392
0
          HT_ASSERT_(b ==                                               \
393
0
                 HT_BUCKET_NUM_(head,field,head->hth_table[b],hashfn)); \
394
0
          return &head->hth_table[b];                                   \
395
0
        }                                                               \
396
0
        ++b;                                                            \
397
0
      }                                                                 \
398
0
      return NULL;                                                      \
399
0
    }                                                                   \
400
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_NEXT
Unexecuted instantiation: geoip_stats.c:clientmap_HT_NEXT
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_NEXT
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_NEXT
Unexecuted instantiation: keypin.c:rsamap_HT_NEXT
Unexecuted instantiation: keypin.c:edmap_HT_NEXT
Unexecuted instantiation: microdesc.c:microdesc_map_HT_NEXT
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_NEXT
Unexecuted instantiation: nodelist.c:nodelist_map_HT_NEXT
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_NEXT
Unexecuted instantiation: channel.c:channel_idmap_HT_NEXT
Unexecuted instantiation: channel.c:channel_gid_map_HT_NEXT
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_NEXT
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_NEXT
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_NEXT
Unexecuted instantiation: policies.c:policy_map_HT_NEXT
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_NEXT
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_NEXT
Unexecuted instantiation: map.c:strmap_impl_HT_NEXT
Unexecuted instantiation: map.c:digestmap_impl_HT_NEXT
Unexecuted instantiation: map.c:digest256map_impl_HT_NEXT
Unexecuted instantiation: waitpid.c:process_map_HT_NEXT
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_NEXT
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_NEXT
Unexecuted instantiation: connstats.c:bidimap_HT_NEXT
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_NEXT
Unexecuted instantiation: dircollate.c:double_digest_map_HT_NEXT
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_NEXT
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_NEXT
Unexecuted instantiation: namemap.c:namemap_ht_HT_NEXT
401
  /* As HT_NEXT, but also remove the current element 'elm' from the     \
402
   * table. */                                                          \
403
  ATTR_UNUSED static inline struct type **                              \
404
  name##_HT_NEXT_RMV(struct name *head, struct type **elm)              \
405
0
  {                                                                     \
406
0
    unsigned h = HT_ELT_HASH_(*elm, field, hashfn);                     \
407
0
    *elm = (*elm)->field.hte_next;                                      \
408
0
    --head->hth_n_entries;                                              \
409
0
    if (*elm) {                                                         \
410
0
      return elm;                                                       \
411
0
    } else {                                                            \
412
0
      unsigned b = (h % head->hth_table_length)+1;                      \
413
0
      while (b < head->hth_table_length) {                              \
414
0
        if (head->hth_table[b])                                         \
415
0
          return &head->hth_table[b];                                   \
416
0
        ++b;                                                            \
417
0
      }                                                                 \
418
0
      return NULL;                                                      \
419
0
    }                                                                   \
420
0
  }                                                                     \
Unexecuted instantiation: dns.c:cache_map_HT_NEXT_RMV
Unexecuted instantiation: geoip_stats.c:clientmap_HT_NEXT_RMV
Unexecuted instantiation: geoip_stats.c:dirreqmap_HT_NEXT_RMV
Unexecuted instantiation: hs_service.c:hs_service_ht_HT_NEXT_RMV
Unexecuted instantiation: keypin.c:rsamap_HT_NEXT_RMV
Unexecuted instantiation: keypin.c:edmap_HT_NEXT_RMV
Unexecuted instantiation: microdesc.c:microdesc_map_HT_NEXT_RMV
Unexecuted instantiation: nodefamily.c:nodefamily_map_HT_NEXT_RMV
Unexecuted instantiation: nodelist.c:nodelist_map_HT_NEXT_RMV
Unexecuted instantiation: nodelist.c:nodelist_ed_map_HT_NEXT_RMV
Unexecuted instantiation: channel.c:channel_gid_map_HT_NEXT_RMV
Unexecuted instantiation: channel.c:channel_idmap_HT_NEXT_RMV
Unexecuted instantiation: circuitlist.c:chan_circid_map_HT_NEXT_RMV
Unexecuted instantiation: circuitmux.c:chanid_circid_muxinfo_map_HT_NEXT_RMV
Unexecuted instantiation: connection_or.c:or_connect_failure_ht_HT_NEXT_RMV
Unexecuted instantiation: policies.c:policy_map_HT_NEXT_RMV
Unexecuted instantiation: scheduler_kist.c:socket_table_s_HT_NEXT_RMV
Unexecuted instantiation: scheduler_kist.c:outbuf_table_s_HT_NEXT_RMV
Unexecuted instantiation: map.c:strmap_impl_HT_NEXT_RMV
Unexecuted instantiation: map.c:digestmap_impl_HT_NEXT_RMV
Unexecuted instantiation: map.c:digest256map_impl_HT_NEXT_RMV
Unexecuted instantiation: waitpid.c:process_map_HT_NEXT_RMV
Unexecuted instantiation: btrack_orconn_maps.c:bto_gid_ht_HT_NEXT_RMV
Unexecuted instantiation: btrack_orconn_maps.c:bto_chan_ht_HT_NEXT_RMV
Unexecuted instantiation: connstats.c:bidimap_HT_NEXT_RMV
Unexecuted instantiation: consdiffmgr.c:cdm_diff_ht_HT_NEXT_RMV
Unexecuted instantiation: dircollate.c:double_digest_map_HT_NEXT_RMV
Unexecuted instantiation: fp_pair.c:fp_pair_map_impl_HT_NEXT_RMV
Unexecuted instantiation: hs_circuitmap.c:hs_circuitmap_ht_HT_NEXT_RMV
Unexecuted instantiation: namemap.c:namemap_ht_HT_NEXT_RMV
421
  HT_EAT_SEMICOLON__
422
423
#define HT_GENERATE2(name, type, field, hashfn, eqfn, load, reallocarrayfn, \
424
                     freefn)                                            \
425
  /* Primes that aren't too far from powers of two. We stop at */       \
426
  /* P=402653189 because P*sizeof(void*) is less than SSIZE_MAX */      \
427
  /* even on a 32-bit platform. */                                      \
428
  static unsigned name##_PRIMES[] = {                                   \
429
    53, 97, 193, 389,                                                   \
430
    769, 1543, 3079, 6151,                                              \
431
    12289, 24593, 49157, 98317,                                         \
432
    196613, 393241, 786433, 1572869,                                    \
433
    3145739, 6291469, 12582917, 25165843,                               \
434
    50331653, 100663319, 201326611, 402653189                           \
435
  };                                                                    \
436
  static unsigned name##_N_PRIMES =                                     \
437
    (unsigned)(sizeof(name##_PRIMES)/sizeof(name##_PRIMES[0]));         \
438
  /* Expand the internal table of 'head' until it is large enough to    \
439
   * hold 'size' elements.  Return 0 on success, -1 on allocation       \
440
   * failure. */                                                        \
441
  int                                                                   \
442
  name##_HT_GROW(struct name *head, unsigned size)                      \
443
0
  {                                                                     \
444
0
    unsigned new_len, new_load_limit;                                   \
445
0
    int prime_idx;                                                      \
446
0
    struct type **new_table;                                            \
447
0
    if (head->hth_prime_idx == (int)name##_N_PRIMES - 1)                \
448
0
      return 0;                                                         \
449
0
    if (head->hth_load_limit > size)                                    \
450
0
      return 0;                                                         \
451
0
    prime_idx = head->hth_prime_idx;                                    \
452
0
    do {                                                                \
453
0
      new_len = name##_PRIMES[++prime_idx];                             \
454
0
      new_load_limit = (unsigned)(load*new_len);                        \
455
0
    } while (new_load_limit <= size &&                                  \
456
0
             prime_idx < (int)name##_N_PRIMES);                         \
457
0
    if ((new_table = reallocarrayfn(NULL, new_len, sizeof(struct type*)))) { \
458
0
      unsigned b;                                                       \
459
0
      memset(new_table, 0, new_len*sizeof(struct type*));               \
460
0
      for (b = 0; b < head->hth_table_length; ++b) {                    \
461
0
        struct type *elm, *next;                                        \
462
0
        unsigned b2;                                                    \
463
0
        elm = head->hth_table[b];                                       \
464
0
        while (elm) {                                                   \
465
0
          next = elm->field.hte_next;                                   \
466
0
          b2 = HT_ELT_HASH_(elm, field, hashfn) % new_len;              \
467
0
          elm->field.hte_next = new_table[b2];                          \
468
0
          new_table[b2] = elm;                                          \
469
0
          elm = next;                                                   \
470
0
        }                                                               \
471
0
      }                                                                 \
472
0
      if (head->hth_table)                                              \
473
0
        freefn(head->hth_table);                                        \
474
0
      head->hth_table = new_table;                                      \
475
0
    } else {                                                            \
476
0
      unsigned b, b2;                                                   \
477
0
      new_table = reallocarrayfn(head->hth_table, new_len, sizeof(struct type*)); \
478
0
      if (!new_table) return -1;                                        \
479
0
      memset(new_table + head->hth_table_length, 0,                     \
480
0
             (new_len - head->hth_table_length)*sizeof(struct type*));  \
481
0
      for (b=0; b < head->hth_table_length; ++b) {                      \
482
0
        struct type *e, **pE;                                           \
483
0
        for (pE = &new_table[b], e = *pE; e != NULL; e = *pE) {         \
484
0
          b2 = HT_ELT_HASH_(e, field, hashfn) % new_len;                \
485
0
          if (b2 == b) {                                                \
486
0
            pE = &e->field.hte_next;                                    \
487
0
          } else {                                                      \
488
0
            *pE = e->field.hte_next;                                    \
489
0
            e->field.hte_next = new_table[b2];                          \
490
0
            new_table[b2] = e;                                          \
491
0
          }                                                             \
492
0
        }                                                               \
493
0
      }                                                                 \
494
0
      head->hth_table = new_table;                                      \
495
0
    }                                                                   \
496
0
    head->hth_table_length = new_len;                                   \
497
0
    head->hth_prime_idx = prime_idx;                                    \
498
0
    head->hth_load_limit = new_load_limit;                              \
499
0
    return 0;                                                           \
500
0
  }                                                                     \
Unexecuted instantiation: cache_map_HT_GROW
Unexecuted instantiation: clientmap_HT_GROW
Unexecuted instantiation: dirreqmap_HT_GROW
Unexecuted instantiation: hs_service_ht_HT_GROW
Unexecuted instantiation: rsamap_HT_GROW
Unexecuted instantiation: edmap_HT_GROW
Unexecuted instantiation: microdesc_map_HT_GROW
Unexecuted instantiation: nodefamily_map_HT_GROW
Unexecuted instantiation: nodelist_map_HT_GROW
Unexecuted instantiation: nodelist_ed_map_HT_GROW
Unexecuted instantiation: channel_gid_map_HT_GROW
Unexecuted instantiation: channel_idmap_HT_GROW
Unexecuted instantiation: chan_circid_map_HT_GROW
Unexecuted instantiation: chanid_circid_muxinfo_map_HT_GROW
Unexecuted instantiation: or_connect_failure_ht_HT_GROW
Unexecuted instantiation: policy_map_HT_GROW
Unexecuted instantiation: socket_table_s_HT_GROW
Unexecuted instantiation: outbuf_table_s_HT_GROW
Unexecuted instantiation: strmap_impl_HT_GROW
Unexecuted instantiation: digestmap_impl_HT_GROW
Unexecuted instantiation: digest256map_impl_HT_GROW
Unexecuted instantiation: process_map_HT_GROW
Unexecuted instantiation: bto_gid_ht_HT_GROW
Unexecuted instantiation: bto_chan_ht_HT_GROW
Unexecuted instantiation: bidimap_HT_GROW
Unexecuted instantiation: cdm_diff_ht_HT_GROW
Unexecuted instantiation: double_digest_map_HT_GROW
Unexecuted instantiation: fp_pair_map_impl_HT_GROW
Unexecuted instantiation: hs_circuitmap_ht_HT_GROW
Unexecuted instantiation: namemap_ht_HT_GROW
501
  /* Free all storage held by 'head'.  Does not free 'head' itself, or  \
502
   * individual elements. */                                            \
503
  void                                                                  \
504
  name##_HT_CLEAR(struct name *head)                                    \
505
0
  {                                                                     \
506
0
    if (head->hth_table)                                                \
507
0
      freefn(head->hth_table);                                          \
508
0
    head->hth_table_length = 0;                                         \
509
0
    name##_HT_INIT(head);                                               \
510
0
  }                                                                     \
Unexecuted instantiation: cache_map_HT_CLEAR
Unexecuted instantiation: clientmap_HT_CLEAR
Unexecuted instantiation: dirreqmap_HT_CLEAR
Unexecuted instantiation: hs_service_ht_HT_CLEAR
Unexecuted instantiation: rsamap_HT_CLEAR
Unexecuted instantiation: edmap_HT_CLEAR
Unexecuted instantiation: microdesc_map_HT_CLEAR
Unexecuted instantiation: nodefamily_map_HT_CLEAR
Unexecuted instantiation: nodelist_map_HT_CLEAR
Unexecuted instantiation: nodelist_ed_map_HT_CLEAR
Unexecuted instantiation: channel_gid_map_HT_CLEAR
Unexecuted instantiation: channel_idmap_HT_CLEAR
Unexecuted instantiation: chan_circid_map_HT_CLEAR
Unexecuted instantiation: chanid_circid_muxinfo_map_HT_CLEAR
Unexecuted instantiation: or_connect_failure_ht_HT_CLEAR
Unexecuted instantiation: policy_map_HT_CLEAR
Unexecuted instantiation: socket_table_s_HT_CLEAR
Unexecuted instantiation: outbuf_table_s_HT_CLEAR
Unexecuted instantiation: strmap_impl_HT_CLEAR
Unexecuted instantiation: digestmap_impl_HT_CLEAR
Unexecuted instantiation: digest256map_impl_HT_CLEAR
Unexecuted instantiation: process_map_HT_CLEAR
Unexecuted instantiation: bto_gid_ht_HT_CLEAR
Unexecuted instantiation: bto_chan_ht_HT_CLEAR
Unexecuted instantiation: bidimap_HT_CLEAR
Unexecuted instantiation: cdm_diff_ht_HT_CLEAR
Unexecuted instantiation: double_digest_map_HT_CLEAR
Unexecuted instantiation: fp_pair_map_impl_HT_CLEAR
Unexecuted instantiation: hs_circuitmap_ht_HT_CLEAR
Unexecuted instantiation: namemap_ht_HT_CLEAR
511
  /* Debugging helper: return false iff the representation of 'head' is \
512
   * internally consistent. */                                          \
513
  int                                                                   \
514
  name##_HT_REP_IS_BAD_(const struct name *head)                        \
515
0
  {                                                                     \
516
0
    unsigned n, i;                                                      \
517
0
    struct type *elm;                                                   \
518
0
    if (!head->hth_table_length) {                                      \
519
0
      if (!head->hth_table && !head->hth_n_entries &&                   \
520
0
          !head->hth_load_limit && head->hth_prime_idx == -1)           \
521
0
        return 0;                                                       \
522
0
      else                                                              \
523
0
        return 1;                                                       \
524
0
    }                                                                   \
525
0
    if (!head->hth_table || head->hth_prime_idx < 0 ||                  \
526
0
        !head->hth_load_limit)                                          \
527
0
      return 2;                                                         \
528
0
    if (head->hth_n_entries > head->hth_load_limit)                     \
529
0
      return 3;                                                         \
530
0
    if (head->hth_table_length != name##_PRIMES[head->hth_prime_idx])   \
531
0
      return 4;                                                         \
532
0
    if (head->hth_load_limit != (unsigned)(load*head->hth_table_length)) \
533
0
      return 5;                                                         \
534
0
    for (n = i = 0; i < head->hth_table_length; ++i) {                  \
535
0
      for (elm = head->hth_table[i]; elm; elm = elm->field.hte_next) {  \
536
0
        if (HT_ELT_HASH_(elm, field, hashfn) != hashfn(elm))            \
537
0
          return 1000 + i;                                              \
538
0
        if (HT_BUCKET_NUM_(head,field,elm,hashfn) != i)                 \
539
0
          return 10000 + i;                                             \
540
0
        ++n;                                                            \
541
0
      }                                                                 \
542
0
    }                                                                   \
543
0
    if (n != head->hth_n_entries)                                       \
544
0
      return 6;                                                         \
545
0
    return 0;                                                           \
546
0
  }                                                                     \
Unexecuted instantiation: cache_map_HT_REP_IS_BAD_
Unexecuted instantiation: clientmap_HT_REP_IS_BAD_
Unexecuted instantiation: dirreqmap_HT_REP_IS_BAD_
Unexecuted instantiation: hs_service_ht_HT_REP_IS_BAD_
Unexecuted instantiation: rsamap_HT_REP_IS_BAD_
Unexecuted instantiation: edmap_HT_REP_IS_BAD_
Unexecuted instantiation: microdesc_map_HT_REP_IS_BAD_
Unexecuted instantiation: nodefamily_map_HT_REP_IS_BAD_
Unexecuted instantiation: nodelist_map_HT_REP_IS_BAD_
Unexecuted instantiation: nodelist_ed_map_HT_REP_IS_BAD_
Unexecuted instantiation: channel_gid_map_HT_REP_IS_BAD_
Unexecuted instantiation: channel_idmap_HT_REP_IS_BAD_
Unexecuted instantiation: chan_circid_map_HT_REP_IS_BAD_
Unexecuted instantiation: chanid_circid_muxinfo_map_HT_REP_IS_BAD_
Unexecuted instantiation: or_connect_failure_ht_HT_REP_IS_BAD_
Unexecuted instantiation: policy_map_HT_REP_IS_BAD_
Unexecuted instantiation: socket_table_s_HT_REP_IS_BAD_
Unexecuted instantiation: outbuf_table_s_HT_REP_IS_BAD_
Unexecuted instantiation: strmap_impl_HT_REP_IS_BAD_
Unexecuted instantiation: digestmap_impl_HT_REP_IS_BAD_
Unexecuted instantiation: digest256map_impl_HT_REP_IS_BAD_
Unexecuted instantiation: process_map_HT_REP_IS_BAD_
Unexecuted instantiation: bto_gid_ht_HT_REP_IS_BAD_
Unexecuted instantiation: bto_chan_ht_HT_REP_IS_BAD_
Unexecuted instantiation: bidimap_HT_REP_IS_BAD_
Unexecuted instantiation: cdm_diff_ht_HT_REP_IS_BAD_
Unexecuted instantiation: double_digest_map_HT_REP_IS_BAD_
Unexecuted instantiation: fp_pair_map_impl_HT_REP_IS_BAD_
Unexecuted instantiation: hs_circuitmap_ht_HT_REP_IS_BAD_
Unexecuted instantiation: namemap_ht_HT_REP_IS_BAD_
547
  HT_EAT_SEMICOLON__
548
549
#define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn,    \
550
                    reallocfn, freefn)                                  \
551
  static void *                                                         \
552
  name##_reallocarray(void *arg, size_t a, size_t b)                    \
553
  {                                                                     \
554
    if ((b) && (a) > SIZE_MAX / (b))                                    \
555
      return NULL;                                                      \
556
    if (arg)                                                            \
557
      return reallocfn((arg),(a)*(b));                                  \
558
    else                                                                \
559
      return mallocfn((a)*(b));                                         \
560
  }                                                                     \
561
  HT_GENERATE2(name, type, field, hashfn, eqfn, load,                   \
562
               name##_reallocarray, freefn)
563
564
/** Implements an over-optimized "find and insert if absent" block;
565
 * not meant for direct usage by typical code, or usage outside the critical
566
 * path.*/
567
#define HT_FIND_OR_INSERT_(name, field, hashfn, head, eltype, elm, var, y, n) \
568
0
  {                                                                     \
569
0
    struct name *var##_head_ = head;                                    \
570
0
    struct eltype **var;                                                \
571
0
    if (!var##_head_->hth_table ||                                      \
572
0
        var##_head_->hth_n_entries >= var##_head_->hth_load_limit)      \
573
0
      name##_HT_GROW(var##_head_, var##_head_->hth_n_entries+1);        \
574
0
    HT_SET_HASH_((elm), field, hashfn);                                 \
575
0
    var = name##_HT_FIND_P_(var##_head_, (elm));                        \
576
0
    HT_ASSERT_(var); /* Holds because we called HT_GROW */              \
577
0
    if (*var) {                                                         \
578
0
      y;                                                                \
579
0
    } else {                                                            \
580
0
      n;                                                                \
581
0
    }                                                                   \
582
0
  }
583
#define HT_FOI_INSERT_(field, head, elm, newent, var)       \
584
  {                                                         \
585
    HT_SET_HASHVAL_(newent, field, (elm)->field.hte_hash);  \
586
    newent->field.hte_next = NULL;                          \
587
    *var = newent;                                          \
588
    ++((head)->hth_n_entries);                              \
589
  }
590
591
/*
592
 * Copyright 2005, Nick Mathewson.  Implementation logic is adapted from code
593
 * by Christopher Clark, retrofit to allow drop-in memory management, and to
594
 * use the same interface as Niels Provos's tree.h.  This is probably still
595
 * a derived work, so the original license below still applies.
596
 *
597
 * Copyright (c) 2002, Christopher Clark
598
 * All rights reserved.
599
 *
600
 * Redistribution and use in source and binary forms, with or without
601
 * modification, are permitted provided that the following conditions
602
 * are met:
603
 *
604
 * * Redistributions of source code must retain the above copyright
605
 * notice, this list of conditions and the following disclaimer.
606
 *
607
 * * Redistributions in binary form must reproduce the above copyright
608
 * notice, this list of conditions and the following disclaimer in the
609
 * documentation and/or other materials provided with the distribution.
610
 *
611
 * * Neither the name of the original author; nor the names of any contributors
612
 * may be used to endorse or promote products derived from this software
613
 * without specific prior written permission.
614
 *
615
 *
616
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
617
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
618
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
619
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
620
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
621
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
622
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
623
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
624
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
625
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
626
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
627
*/
628
629
#endif