Summary > Report 63d21b

Bug Summary

File:home/avsej/code/libcouchbase/contrib/genhash/genhash.c
Warning:line 184, column 13
Value stored to 'rv' is never read
Report Bug

Annotated Source Code

1/*
2 * Copyright (c) 2006 Dustin Sallings <dustin@spy.net>
3 */
4
5#include <math.h>
6#include "internal.h"
7#include "genhash.h"
8
9/* Table of 32 primes by their distance from the nearest power of two */
10static lcb_size_t prime_size_table[] = {
11 3, 7, 13, 23, 47, 97, 193, 383, 769, 1531, 3067, 6143, 12289, 24571, 49157,
12 98299, 196613, 393209, 786433, 1572869, 3145721, 6291449, 12582917,
13 25165813, 50331653, 100663291, 201326611, 402653189, 805306357,
14 1610612741
15};
16
17#define TABLE_SIZE((int)(sizeof(prime_size_table) / sizeof(int))) ((int)(sizeof(prime_size_table) / sizeof(int)))
18
19struct genhash_entry_t {
20 /** The key for this entry */
21 void *key;
22 /** Size of the key */
23 lcb_size_t nkey;
24 /** The value for this entry */
25 void *value;
26 /** Size of the value */
27 lcb_size_t nvalue;
28 /** Pointer to the next entry */
29 struct genhash_entry_t *next;
30};
31
32struct _genhash {
33 lcb_size_t size;
34 struct lcb_hash_ops ops;
35 struct genhash_entry_t *buckets[1];
36};
37
38static lcb_size_t estimate_table_size(lcb_size_t est);
39
40
41static void *dup_key(genhash_t *h, const void *key, lcb_size_t klen)
42{
43 if (h->ops.dup_key != NULL((void*)0)) {
44 return h->ops.dup_key(key, klen);
45 } else {
46 return (void *)key;
47 }
48}
49
50static void *dup_value(genhash_t *h, const void *value, lcb_size_t vlen)
51{
52 if (h->ops.dup_value != NULL((void*)0)) {
53 return h->ops.dup_value(value, vlen);
54 } else {
55 return (void *)value;
56 }
57}
58
59static void free_key(genhash_t *h, void *key)
60{
61 if (h->ops.free_key != NULL((void*)0)) {
62 h->ops.free_key(key);
63 }
64}
65
66static void free_value(genhash_t *h, void *value)
67{
68 if (h->ops.free_value != NULL((void*)0)) {
69 h->ops.free_value(value);
70 }
71}
72
73static lcb_size_t estimate_table_size(lcb_size_t est)
74{
75 lcb_size_t rv = 0;
76 while (prime_size_table[rv] < est && rv + 1 < TABLE_SIZE((int)(sizeof(prime_size_table) / sizeof(int)))) {
77 rv++;
78 }
79 return prime_size_table[rv];
80}
81
82genhash_t *genhash_init(lcb_size_t est, struct lcb_hash_ops ops)
83{
84 genhash_t *rv = NULL((void*)0);
85 lcb_size_t size = 0;
86 if (est < 1) {
87 return NULL((void*)0);
88 }
89
90 lcb_assert(ops.hashfunc != NULL)((void) sizeof ((ops.hashfunc != ((void*)0)) ? 1 : 0), __extension__
({ if (ops.hashfunc != ((void*)0)) ; else __assert_fail ("ops.hashfunc != ((void*)0)"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 90
, __extension__ __PRETTY_FUNCTION__); }))
;
91 lcb_assert(ops.hasheq != NULL)((void) sizeof ((ops.hasheq != ((void*)0)) ? 1 : 0), __extension__
({ if (ops.hasheq != ((void*)0)) ; else __assert_fail ("ops.hasheq != ((void*)0)"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 91
, __extension__ __PRETTY_FUNCTION__); }))
;
92 lcb_assert((ops.dup_key != NULL && ops.free_key != NULL) || ops.free_key == NULL)((void) sizeof (((ops.dup_key != ((void*)0) && ops.free_key
!= ((void*)0)) || ops.free_key == ((void*)0)) ? 1 : 0), __extension__
({ if ((ops.dup_key != ((void*)0) && ops.free_key !=
((void*)0)) || ops.free_key == ((void*)0)) ; else __assert_fail
("(ops.dup_key != ((void*)0) && ops.free_key != ((void*)0)) || ops.free_key == ((void*)0)"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 92
, __extension__ __PRETTY_FUNCTION__); }))
;
93 lcb_assert((ops.dup_value != NULL && ops.free_value != NULL) || ops.free_value == NULL)((void) sizeof (((ops.dup_value != ((void*)0) && ops.
free_value != ((void*)0)) || ops.free_value == ((void*)0)) ? 1
: 0), __extension__ ({ if ((ops.dup_value != ((void*)0) &&
ops.free_value != ((void*)0)) || ops.free_value == ((void*)0
)) ; else __assert_fail ("(ops.dup_value != ((void*)0) && ops.free_value != ((void*)0)) || ops.free_value == ((void*)0)"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 93
, __extension__ __PRETTY_FUNCTION__); }))
;
94
95 size = estimate_table_size(est);
96 rv = calloc(1, sizeof(genhash_t)
97 + (size * sizeof(struct genhash_entry_t *)));
98 if (rv == NULL((void*)0)) {
99 return NULL((void*)0);
100 }
101 rv->size = size;
102 rv->ops = ops;
103
104 return rv;
105}
106
107void genhash_free(genhash_t *h)
108{
109 if (h != NULL((void*)0)) {
110 genhash_clear(h);
111 free(h);
112 }
113}
114
115int genhash_store(genhash_t *h, const void *k, lcb_size_t klen,
116 const void *v, lcb_size_t vlen)
117{
118 lcb_size_t n = 0;
119 struct genhash_entry_t *p;
120
121 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 121, __extension__ __PRETTY_FUNCTION__); }))
;
122
123 n = h->ops.hashfunc(k, klen) % h->size;
124 lcb_assert(n < h->size)((void) sizeof ((n < h->size) ? 1 : 0), __extension__ (
{ if (n < h->size) ; else __assert_fail ("n < h->size"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 124
, __extension__ __PRETTY_FUNCTION__); }))
;
125
126 p = calloc(1, sizeof(struct genhash_entry_t));
127 if (!p) {
128 return -1;
129 }
130
131 p->key = dup_key(h, k, klen);
132 p->nkey = klen;
133 p->value = dup_value(h, v, vlen);
134 p->nvalue = vlen;
135
136 p->next = h->buckets[n];
137 h->buckets[n] = p;
138 return 0;
139}
140
141static struct genhash_entry_t *genhash_find_entry(genhash_t *h,
142 const void *k,
143 lcb_size_t klen)
144{
145 lcb_size_t n = 0;
146 struct genhash_entry_t *p;
147
148 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 148, __extension__ __PRETTY_FUNCTION__); }))
;
149 n = h->ops.hashfunc(k, klen) % h->size;
150 lcb_assert(n < h->size)((void) sizeof ((n < h->size) ? 1 : 0), __extension__ (
{ if (n < h->size) ; else __assert_fail ("n < h->size"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 150
, __extension__ __PRETTY_FUNCTION__); }))
;
151
152 p = h->buckets[n];
153 for (p = h->buckets[n]; p && !h->ops.hasheq(k, klen, p->key, p->nkey); p = p->next);
154 return p;
155}
156
157void *genhash_find(genhash_t *h, const void *k, lcb_size_t klen)
158{
159 struct genhash_entry_t *p;
160 void *rv = NULL((void*)0);
161
162 p = genhash_find_entry(h, k, klen);
163
164 if (p) {
165 rv = p->value;
166 }
167 return rv;
168}
169
170enum update_type genhash_update(genhash_t *h, const void *k, lcb_size_t klen,
171 const void *v, lcb_size_t vlen)
172{
173 struct genhash_entry_t *p;
174 enum update_type rv = 0;
175
176 p = genhash_find_entry(h, k, klen);
177
178 if (p) {
179 free_value(h, p->value);
180 p->value = dup_value(h, v, vlen);
181 rv = MODIFICATION;
182 } else {
183 if (-1 == genhash_store(h, k, klen, v, vlen)) {
184 rv = ALLOC_FAILURE;
Value stored to 'rv' is never read
185 }
186 rv = NEW;
187 }
188
189 return rv;
190}
191
192enum update_type genhash_fun_update(genhash_t *h,
193 const void *k,
194 lcb_size_t klen,
195 void * (*upd)(const void *,
196 const void *,
197 lcb_size_t *,
198 void *),
199 void (*fr)(void *),
200 void *arg,
201 const void *def,
202 lcb_size_t deflen)
203{
204 struct genhash_entry_t *p;
205 enum update_type rv = 0;
206 lcb_size_t newSize = 0;
207
208 p = genhash_find_entry(h, k, klen);
209
210 if (p) {
211 void *newValue = upd(k, p->value, &newSize, arg);
212 free_value(h, p->value);
213 p->value = dup_value(h, newValue, newSize);
214 fr(newValue);
215 rv = MODIFICATION;
216 } else {
217 void *newValue = upd(k, def, &newSize, arg);
218 genhash_store(h, k, klen, newValue, newSize);
219 fr(newValue);
220 rv = NEW;
221 }
222
223 (void)deflen;
224 return rv;
225}
226
227static void free_item(genhash_t *h, struct genhash_entry_t *i)
228{
229 lcb_assert(i)((void) sizeof ((i) ? 1 : 0), __extension__ ({ if (i) ; else __assert_fail
("i", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 229, __extension__ __PRETTY_FUNCTION__); }))
;
230 free_key(h, i->key);
231 free_value(h, i->value);
232 free(i);
233}
234
235int genhash_delete(genhash_t *h, const void *k, lcb_size_t klen)
236{
237 struct genhash_entry_t *deleteme = NULL((void*)0);
238 lcb_size_t n = 0;
239 int rv = 0;
240
241 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 241, __extension__ __PRETTY_FUNCTION__); }))
;
242 n = h->ops.hashfunc(k, klen) % h->size;
243 lcb_assert(n < h->size)((void) sizeof ((n < h->size) ? 1 : 0), __extension__ (
{ if (n < h->size) ; else __assert_fail ("n < h->size"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 243
, __extension__ __PRETTY_FUNCTION__); }))
;
244
245 if (h->buckets[n] != NULL((void*)0)) {
246 /* Special case the first one */
247 if (h->ops.hasheq(h->buckets[n]->key, h->buckets[n]->nkey, k, klen)) {
248 deleteme = h->buckets[n];
249 h->buckets[n] = deleteme->next;
250 } else {
251 struct genhash_entry_t *p = NULL((void*)0);
252 for (p = h->buckets[n]; deleteme == NULL((void*)0) && p->next != NULL((void*)0); p = p->next) {
253 if (h->ops.hasheq(p->next->key, p->next->nkey, k, klen)) {
254 deleteme = p->next;
255 p->next = deleteme->next;
256 }
257 }
258 }
259 }
260 if (deleteme != NULL((void*)0)) {
261 free_item(h, deleteme);
262 rv++;
263 }
264
265 return rv;
266}
267
268int genhash_delete_all(genhash_t *h, const void *k, lcb_size_t klen)
269{
270 int rv = 0;
271 while (genhash_delete(h, k, klen) == 1) {
272 rv++;
273 }
274 return rv;
275}
276
277void genhash_iter(genhash_t *h,
278 void (*iterfunc)(const void *key, lcb_size_t nkey,
279 const void *val, lcb_size_t nval,
280 void *arg), void *arg)
281{
282 lcb_size_t i = 0;
283 struct genhash_entry_t *p = NULL((void*)0);
284 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 284, __extension__ __PRETTY_FUNCTION__); }))
;
285
286 for (i = 0; i < h->size; i++) {
287 for (p = h->buckets[i]; p != NULL((void*)0); p = p->next) {
288 iterfunc(p->key, p->nkey, p->value, p->nvalue, arg);
289 }
290 }
291}
292
293int genhash_clear(genhash_t *h)
294{
295 lcb_size_t i = 0;
296 int rv = 0;
297 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 297, __extension__ __PRETTY_FUNCTION__); }))
;
298
299 for (i = 0; i < h->size; i++) {
300 while (h->buckets[i]) {
301 struct genhash_entry_t *p = NULL((void*)0);
302 p = h->buckets[i];
303 h->buckets[i] = p->next;
304 free_item(h, p);
305 }
306 }
307
308 return rv;
309}
310
311static void count_entries(const void *key,
312 lcb_size_t klen,
313 const void *val,
314 lcb_size_t vlen,
315 void *arg)
316{
317 int *count = (int *)arg;
318 (*count)++;
319 (void)key;
320 (void)klen;
321 (void)val;
322 (void)vlen;
323}
324
325int genhash_size(genhash_t *h)
326{
327 int rv = 0;
328 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 328, __extension__ __PRETTY_FUNCTION__); }))
;
329 genhash_iter(h, count_entries, &rv);
330 return rv;
331}
332
333int genhash_size_for_key(genhash_t *h, const void *k, lcb_size_t klen)
334{
335 int rv = 0;
336 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 336, __extension__ __PRETTY_FUNCTION__); }))
;
337 genhash_iter_key(h, k, klen, count_entries, &rv);
338 return rv;
339}
340
341void genhash_iter_key(genhash_t *h, const void *key, lcb_size_t klen,
342 void (*iterfunc)(const void *key, lcb_size_t klen,
343 const void *val, lcb_size_t vlen,
344 void *arg), void *arg)
345{
346 lcb_size_t n = 0;
347 struct genhash_entry_t *p = NULL((void*)0);
348
349 lcb_assert(h != NULL)((void) sizeof ((h != ((void*)0)) ? 1 : 0), __extension__ ({ if
(h != ((void*)0)) ; else __assert_fail ("h != ((void*)0)", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 349, __extension__ __PRETTY_FUNCTION__); }))
;
350 n = h->ops.hashfunc(key, klen) % h->size;
351 lcb_assert(n < h->size)((void) sizeof ((n < h->size) ? 1 : 0), __extension__ (
{ if (n < h->size) ; else __assert_fail ("n < h->size"
, "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c", 351
, __extension__ __PRETTY_FUNCTION__); }))
;
352
353 for (p = h->buckets[n]; p != NULL((void*)0); p = p->next) {
354 if (h->ops.hasheq(key, klen, p->key, p->nkey)) {
355 iterfunc(p->key, p->nkey, p->value, p->nvalue, arg);
356 }
357 }
358}
359
360int genhash_string_hash(const void *p, lcb_size_t nkey)
361{
362 int rv = 5381;
363 int i = 0;
364 char *str = (char *)p;
365
366 for (i = 0; i < (int)nkey; i++) {
367 lcb_assert(str[i])((void) sizeof ((str[i]) ? 1 : 0), __extension__ ({ if (str[i
]) ; else __assert_fail ("str[i]", "/home/avsej/code/libcouchbase/contrib/genhash/genhash.c"
, 367, __extension__ __PRETTY_FUNCTION__); }))
;
368 rv = ((rv << 5) + rv) ^ str[i];
369 }
370
371 return rv;
372}