2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <urcu/compiler.h>
24 #include <common/common.h>
25 #include <common/defaults.h>
27 #include "hashtable.h"
30 unsigned long lttng_ht_seed
;
32 static unsigned long min_hash_alloc_size
= 1;
33 static unsigned long max_hash_buckets_size
= 0;
36 * Getter/lookup functions need to be called with RCU read-side lock
37 * held. However, modification functions (add, add_unique, replace, del)
38 * take the RCU lock internally, so it does not matter whether the
39 * caller hold the RCU lock or not.
43 * Match function for string node.
45 static int match_str(struct cds_lfht_node
*node
, const void *key
)
47 struct lttng_ht_node_str
*match_node
=
48 caa_container_of(node
, struct lttng_ht_node_str
, node
);
50 return hash_match_key_str(match_node
->key
, (void *) key
);
54 * Match function for ulong node.
56 static int match_ulong(struct cds_lfht_node
*node
, const void *key
)
58 struct lttng_ht_node_ulong
*match_node
=
59 caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
61 return hash_match_key_ulong((void *) match_node
->key
, (void *) key
);
65 * Match function for u64 node.
67 static int match_u64(struct cds_lfht_node
*node
, const void *key
)
69 struct lttng_ht_node_u64
*match_node
=
70 caa_container_of(node
, struct lttng_ht_node_u64
, node
);
72 return hash_match_key_u64(&match_node
->key
, (void *) key
);
76 * Match function for two uint64_t node.
78 static int match_two_u64(struct cds_lfht_node
*node
, const void *key
)
80 struct lttng_ht_node_two_u64
*match_node
=
81 caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);
83 return hash_match_key_two_u64((void *) &match_node
->key
, (void *) key
);
87 * Return an allocated lttng hashtable.
89 struct lttng_ht
*lttng_ht_new(unsigned long size
, int type
)
95 size
= DEFAULT_HT_SIZE
;
97 ht
= zmalloc(sizeof(*ht
));
99 PERROR("zmalloc lttng_ht");
103 ht
->ht
= cds_lfht_new(size
, min_hash_alloc_size
, max_hash_buckets_size
,
104 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
106 * There is already an assert in the RCU hashtable code so if the ht is
107 * NULL here there is a *huge* problem.
112 case LTTNG_HT_TYPE_STRING
:
113 ht
->match_fct
= match_str
;
114 ht
->hash_fct
= hash_key_str
;
116 case LTTNG_HT_TYPE_ULONG
:
117 ht
->match_fct
= match_ulong
;
118 ht
->hash_fct
= hash_key_ulong
;
120 case LTTNG_HT_TYPE_U64
:
121 ht
->match_fct
= match_u64
;
122 ht
->hash_fct
= hash_key_u64
;
124 case LTTNG_HT_TYPE_TWO_U64
:
125 ht
->match_fct
= match_two_u64
;
126 ht
->hash_fct
= hash_key_two_u64
;
129 ERR("Unknown lttng hashtable type %d", type
);
130 lttng_ht_destroy(ht
);
134 DBG3("Created hashtable size %lu at %p of type %d", size
, ht
->ht
, type
);
143 * Free a lttng hashtable.
145 void lttng_ht_destroy(struct lttng_ht
*ht
)
149 ret
= cds_lfht_destroy(ht
->ht
, NULL
);
155 * Init lttng ht node string.
157 void lttng_ht_node_init_str(struct lttng_ht_node_str
*node
, char *key
)
162 cds_lfht_node_init(&node
->node
);
166 * Init lttng ht node unsigned long.
168 void lttng_ht_node_init_ulong(struct lttng_ht_node_ulong
*node
,
174 cds_lfht_node_init(&node
->node
);
178 * Init lttng ht node uint64_t.
180 void lttng_ht_node_init_u64(struct lttng_ht_node_u64
*node
,
186 cds_lfht_node_init(&node
->node
);
190 * Init lttng ht node with two uint64_t.
192 void lttng_ht_node_init_two_u64(struct lttng_ht_node_two_u64
*node
,
193 uint64_t key1
, uint64_t key2
)
197 node
->key
.key1
= key1
;
198 node
->key
.key2
= key2
;
199 cds_lfht_node_init(&node
->node
);
203 * Free lttng ht node string.
205 void lttng_ht_node_free_str(struct lttng_ht_node_str
*node
)
212 * Free lttng ht node unsigned long.
214 void lttng_ht_node_free_ulong(struct lttng_ht_node_ulong
*node
)
221 * Free lttng ht node uint64_t.
223 void lttng_ht_node_free_u64(struct lttng_ht_node_u64
*node
)
230 * Free lttng ht node two uint64_t.
232 void lttng_ht_node_free_two_u64(struct lttng_ht_node_two_u64
*node
)
239 * Lookup function in hashtable.
241 void lttng_ht_lookup(struct lttng_ht
*ht
, void *key
,
242 struct lttng_ht_iter
*iter
)
247 cds_lfht_lookup(ht
->ht
, ht
->hash_fct(key
, lttng_ht_seed
),
248 ht
->match_fct
, key
, &iter
->iter
);
252 * Add unique string node to hashtable.
254 void lttng_ht_add_unique_str(struct lttng_ht
*ht
,
255 struct lttng_ht_node_str
*node
)
257 struct cds_lfht_node
*node_ptr
;
262 /* RCU read lock protects from ABA. */
264 node_ptr
= cds_lfht_add_unique(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
265 ht
->match_fct
, node
->key
, &node
->node
);
267 assert(node_ptr
== &node
->node
);
271 * Add string node to hashtable.
273 void lttng_ht_add_str(struct lttng_ht
*ht
,
274 struct lttng_ht_node_str
*node
)
280 /* RCU read lock protects from ABA. */
282 cds_lfht_add(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
288 * Add unsigned long node to hashtable.
290 void lttng_ht_add_ulong(struct lttng_ht
*ht
, struct lttng_ht_node_ulong
*node
)
296 /* RCU read lock protects from ABA. */
298 cds_lfht_add(ht
->ht
, ht
->hash_fct((void *) node
->key
, lttng_ht_seed
),
304 * Add uint64_t node to hashtable.
307 void lttng_ht_add_u64(struct lttng_ht
*ht
, struct lttng_ht_node_u64
*node
)
313 /* RCU read lock protects from ABA. */
315 cds_lfht_add(ht
->ht
, ht
->hash_fct(&node
->key
, lttng_ht_seed
),
321 * Add unique unsigned long node to hashtable.
323 void lttng_ht_add_unique_ulong(struct lttng_ht
*ht
,
324 struct lttng_ht_node_ulong
*node
)
326 struct cds_lfht_node
*node_ptr
;
331 /* RCU read lock protects from ABA. */
333 node_ptr
= cds_lfht_add_unique(ht
->ht
,
334 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
335 (void *) node
->key
, &node
->node
);
337 assert(node_ptr
== &node
->node
);
341 * Add unique uint64_t node to hashtable.
343 void lttng_ht_add_unique_u64(struct lttng_ht
*ht
,
344 struct lttng_ht_node_u64
*node
)
346 struct cds_lfht_node
*node_ptr
;
351 /* RCU read lock protects from ABA. */
353 node_ptr
= cds_lfht_add_unique(ht
->ht
,
354 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
355 &node
->key
, &node
->node
);
357 assert(node_ptr
== &node
->node
);
361 * Add unique two uint64_t node to hashtable.
363 void lttng_ht_add_unique_two_u64(struct lttng_ht
*ht
,
364 struct lttng_ht_node_two_u64
*node
)
366 struct cds_lfht_node
*node_ptr
;
371 /* RCU read lock protects from ABA. */
373 node_ptr
= cds_lfht_add_unique(ht
->ht
,
374 ht
->hash_fct((void *) &node
->key
, lttng_ht_seed
), ht
->match_fct
,
375 (void *) &node
->key
, &node
->node
);
377 assert(node_ptr
== &node
->node
);
381 * Add replace unsigned long node to hashtable.
383 struct lttng_ht_node_ulong
*lttng_ht_add_replace_ulong(struct lttng_ht
*ht
,
384 struct lttng_ht_node_ulong
*node
)
386 struct cds_lfht_node
*node_ptr
;
391 /* RCU read lock protects from ABA. */
393 node_ptr
= cds_lfht_add_replace(ht
->ht
,
394 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
395 (void *) node
->key
, &node
->node
);
400 return caa_container_of(node_ptr
, struct lttng_ht_node_ulong
, node
);
402 assert(node_ptr
== &node
->node
);
406 * Add replace unsigned long node to hashtable.
408 struct lttng_ht_node_u64
*lttng_ht_add_replace_u64(struct lttng_ht
*ht
,
409 struct lttng_ht_node_u64
*node
)
411 struct cds_lfht_node
*node_ptr
;
416 /* RCU read lock protects from ABA. */
418 node_ptr
= cds_lfht_add_replace(ht
->ht
,
419 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
420 &node
->key
, &node
->node
);
425 return caa_container_of(node_ptr
, struct lttng_ht_node_u64
, node
);
427 assert(node_ptr
== &node
->node
);
431 * Delete node from hashtable.
433 int lttng_ht_del(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
441 /* RCU read lock protects from ABA. */
443 ret
= cds_lfht_del(ht
->ht
, iter
->iter
.node
);
449 * Get first node in the hashtable.
451 void lttng_ht_get_first(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
457 cds_lfht_first(ht
->ht
, &iter
->iter
);
461 * Get next node in the hashtable.
463 void lttng_ht_get_next(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
469 cds_lfht_next(ht
->ht
, &iter
->iter
);
473 * Return the number of nodes in the hashtable.
475 unsigned long lttng_ht_get_count(struct lttng_ht
*ht
)
483 /* RCU read lock protects from ABA and allows RCU traversal. */
485 cds_lfht_count_nodes(ht
->ht
, &scb
, &count
, &sca
);
492 * Return lttng ht string node from iterator.
494 struct lttng_ht_node_str
*lttng_ht_iter_get_node_str(
495 struct lttng_ht_iter
*iter
)
497 struct cds_lfht_node
*node
;
500 node
= cds_lfht_iter_get_node(&iter
->iter
);
504 return caa_container_of(node
, struct lttng_ht_node_str
, node
);
508 * Return lttng ht unsigned long node from iterator.
510 struct lttng_ht_node_ulong
*lttng_ht_iter_get_node_ulong(
511 struct lttng_ht_iter
*iter
)
513 struct cds_lfht_node
*node
;
516 node
= cds_lfht_iter_get_node(&iter
->iter
);
520 return caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
524 * Return lttng ht unsigned long node from iterator.
526 struct lttng_ht_node_u64
*lttng_ht_iter_get_node_u64(
527 struct lttng_ht_iter
*iter
)
529 struct cds_lfht_node
*node
;
532 node
= cds_lfht_iter_get_node(&iter
->iter
);
536 return caa_container_of(node
, struct lttng_ht_node_u64
, node
);
540 * Return lttng ht stream and index id node from iterator.
542 struct lttng_ht_node_two_u64
*lttng_ht_iter_get_node_two_u64(
543 struct lttng_ht_iter
*iter
)
545 struct cds_lfht_node
*node
;
548 node
= cds_lfht_iter_get_node(&iter
->iter
);
552 return caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);
558 static void __attribute__((constructor
)) _init(void)
560 /* Init hash table seed */
561 lttng_ht_seed
= (unsigned long) time(NULL
);
This page took 0.042132 seconds and 4 git commands to generate.