2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
4 * SPDX-License-Identifier: GPL-2.0-only
12 #include <urcu/compiler.h>
14 #include <common/common.h>
15 #include <common/defaults.h>
17 #include "hashtable.h"
20 /* seed_lock protects both seed_init and lttng_ht_seed. */
21 static pthread_mutex_t seed_lock
= PTHREAD_MUTEX_INITIALIZER
;
22 static bool seed_init
;
23 unsigned long lttng_ht_seed
;
25 static unsigned long min_hash_alloc_size
= 1;
26 static unsigned long max_hash_buckets_size
= 0;
29 * Getter/lookup functions need to be called with RCU read-side lock
30 * held. However, modification functions (add, add_unique, replace, del)
31 * take the RCU lock internally, so it does not matter whether the
32 * caller hold the RCU lock or not.
36 * Match function for string node.
38 static int match_str(struct cds_lfht_node
*node
, const void *key
)
40 struct lttng_ht_node_str
*match_node
=
41 caa_container_of(node
, struct lttng_ht_node_str
, node
);
43 return hash_match_key_str(match_node
->key
, (void *) key
);
47 * Match function for ulong node.
49 static int match_ulong(struct cds_lfht_node
*node
, const void *key
)
51 struct lttng_ht_node_ulong
*match_node
=
52 caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
54 return hash_match_key_ulong((void *) match_node
->key
, (void *) key
);
58 * Match function for u64 node.
60 static int match_u64(struct cds_lfht_node
*node
, const void *key
)
62 struct lttng_ht_node_u64
*match_node
=
63 caa_container_of(node
, struct lttng_ht_node_u64
, node
);
65 return hash_match_key_u64(&match_node
->key
, (void *) key
);
69 * Match function for two uint64_t node.
71 static int match_two_u64(struct cds_lfht_node
*node
, const void *key
)
73 struct lttng_ht_node_two_u64
*match_node
=
74 caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);
76 return hash_match_key_two_u64((void *) &match_node
->key
, (void *) key
);
80 const char *lttng_ht_type_str(enum lttng_ht_type type
)
83 case LTTNG_HT_TYPE_STRING
:
85 case LTTNG_HT_TYPE_ULONG
:
87 case LTTNG_HT_TYPE_U64
:
89 case LTTNG_HT_TYPE_TWO_U64
:
92 ERR("Unknown lttng hashtable type %d", type
);
98 * Return an allocated lttng hashtable.
101 struct lttng_ht
*lttng_ht_new(unsigned long size
, int type
)
107 size
= DEFAULT_HT_SIZE
;
109 pthread_mutex_lock(&seed_lock
);
111 lttng_ht_seed
= (unsigned long) time(NULL
);
114 pthread_mutex_unlock(&seed_lock
);
116 ht
= zmalloc(sizeof(*ht
));
118 PERROR("zmalloc lttng_ht");
122 ht
->ht
= cds_lfht_new(size
, min_hash_alloc_size
, max_hash_buckets_size
,
123 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
125 * There is already an assert in the RCU hashtable code so if the ht is
126 * NULL here there is a *huge* problem.
131 case LTTNG_HT_TYPE_STRING
:
132 ht
->match_fct
= match_str
;
133 ht
->hash_fct
= hash_key_str
;
135 case LTTNG_HT_TYPE_ULONG
:
136 ht
->match_fct
= match_ulong
;
137 ht
->hash_fct
= hash_key_ulong
;
139 case LTTNG_HT_TYPE_U64
:
140 ht
->match_fct
= match_u64
;
141 ht
->hash_fct
= hash_key_u64
;
143 case LTTNG_HT_TYPE_TWO_U64
:
144 ht
->match_fct
= match_two_u64
;
145 ht
->hash_fct
= hash_key_two_u64
;
148 ERR("Unknown lttng hashtable type %d", type
);
149 lttng_ht_destroy(ht
);
153 DBG3("Created hashtable size %lu at %p of type %s", size
, ht
->ht
,
154 lttng_ht_type_str(type
));
163 * Free a lttng hashtable.
166 void lttng_ht_destroy(struct lttng_ht
*ht
)
170 ret
= cds_lfht_destroy(ht
->ht
, NULL
);
176 * Init lttng ht node string.
179 void lttng_ht_node_init_str(struct lttng_ht_node_str
*node
, char *key
)
184 cds_lfht_node_init(&node
->node
);
188 * Init lttng ht node unsigned long.
191 void lttng_ht_node_init_ulong(struct lttng_ht_node_ulong
*node
,
197 cds_lfht_node_init(&node
->node
);
201 * Init lttng ht node uint64_t.
204 void lttng_ht_node_init_u64(struct lttng_ht_node_u64
*node
,
210 cds_lfht_node_init(&node
->node
);
214 * Init lttng ht node with two uint64_t.
217 void lttng_ht_node_init_two_u64(struct lttng_ht_node_two_u64
*node
,
218 uint64_t key1
, uint64_t key2
)
222 node
->key
.key1
= key1
;
223 node
->key
.key2
= key2
;
224 cds_lfht_node_init(&node
->node
);
228 * Free lttng ht node string.
231 void lttng_ht_node_free_str(struct lttng_ht_node_str
*node
)
238 * Free lttng ht node unsigned long.
241 void lttng_ht_node_free_ulong(struct lttng_ht_node_ulong
*node
)
248 * Free lttng ht node uint64_t.
251 void lttng_ht_node_free_u64(struct lttng_ht_node_u64
*node
)
258 * Free lttng ht node two uint64_t.
261 void lttng_ht_node_free_two_u64(struct lttng_ht_node_two_u64
*node
)
268 * Lookup function in hashtable.
271 void lttng_ht_lookup(struct lttng_ht
*ht
, const void *key
,
272 struct lttng_ht_iter
*iter
)
277 cds_lfht_lookup(ht
->ht
, ht
->hash_fct(key
, lttng_ht_seed
),
278 ht
->match_fct
, key
, &iter
->iter
);
282 * Add unique string node to hashtable.
285 void lttng_ht_add_unique_str(struct lttng_ht
*ht
,
286 struct lttng_ht_node_str
*node
)
288 struct cds_lfht_node
*node_ptr
;
293 /* RCU read lock protects from ABA. */
295 node_ptr
= cds_lfht_add_unique(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
296 ht
->match_fct
, node
->key
, &node
->node
);
298 assert(node_ptr
== &node
->node
);
302 * Add string node to hashtable.
305 void lttng_ht_add_str(struct lttng_ht
*ht
,
306 struct lttng_ht_node_str
*node
)
312 /* RCU read lock protects from ABA. */
314 cds_lfht_add(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
320 * Add unsigned long node to hashtable.
323 void lttng_ht_add_ulong(struct lttng_ht
*ht
, struct lttng_ht_node_ulong
*node
)
329 /* RCU read lock protects from ABA. */
331 cds_lfht_add(ht
->ht
, ht
->hash_fct((void *) node
->key
, lttng_ht_seed
),
337 * Add uint64_t node to hashtable.
340 void lttng_ht_add_u64(struct lttng_ht
*ht
, struct lttng_ht_node_u64
*node
)
346 /* RCU read lock protects from ABA. */
348 cds_lfht_add(ht
->ht
, ht
->hash_fct(&node
->key
, lttng_ht_seed
),
354 * Add unique unsigned long node to hashtable.
357 void lttng_ht_add_unique_ulong(struct lttng_ht
*ht
,
358 struct lttng_ht_node_ulong
*node
)
360 struct cds_lfht_node
*node_ptr
;
365 /* RCU read lock protects from ABA. */
367 node_ptr
= cds_lfht_add_unique(ht
->ht
,
368 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
369 (void *) node
->key
, &node
->node
);
371 assert(node_ptr
== &node
->node
);
375 * Add unique uint64_t node to hashtable.
378 void lttng_ht_add_unique_u64(struct lttng_ht
*ht
,
379 struct lttng_ht_node_u64
*node
)
381 struct cds_lfht_node
*node_ptr
;
386 /* RCU read lock protects from ABA. */
388 node_ptr
= cds_lfht_add_unique(ht
->ht
,
389 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
390 &node
->key
, &node
->node
);
392 assert(node_ptr
== &node
->node
);
396 * Add unique two uint64_t node to hashtable.
399 void lttng_ht_add_unique_two_u64(struct lttng_ht
*ht
,
400 struct lttng_ht_node_two_u64
*node
)
402 struct cds_lfht_node
*node_ptr
;
407 /* RCU read lock protects from ABA. */
409 node_ptr
= cds_lfht_add_unique(ht
->ht
,
410 ht
->hash_fct((void *) &node
->key
, lttng_ht_seed
), ht
->match_fct
,
411 (void *) &node
->key
, &node
->node
);
413 assert(node_ptr
== &node
->node
);
417 * Add replace unsigned long node to hashtable.
420 struct lttng_ht_node_ulong
*lttng_ht_add_replace_ulong(struct lttng_ht
*ht
,
421 struct lttng_ht_node_ulong
*node
)
423 struct cds_lfht_node
*node_ptr
;
428 /* RCU read lock protects from ABA. */
430 node_ptr
= cds_lfht_add_replace(ht
->ht
,
431 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
432 (void *) node
->key
, &node
->node
);
437 return caa_container_of(node_ptr
, struct lttng_ht_node_ulong
, node
);
439 assert(node_ptr
== &node
->node
);
443 * Add replace unsigned long node to hashtable.
446 struct lttng_ht_node_u64
*lttng_ht_add_replace_u64(struct lttng_ht
*ht
,
447 struct lttng_ht_node_u64
*node
)
449 struct cds_lfht_node
*node_ptr
;
454 /* RCU read lock protects from ABA. */
456 node_ptr
= cds_lfht_add_replace(ht
->ht
,
457 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
458 &node
->key
, &node
->node
);
463 return caa_container_of(node_ptr
, struct lttng_ht_node_u64
, node
);
465 assert(node_ptr
== &node
->node
);
469 * Delete node from hashtable.
472 int lttng_ht_del(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
480 /* RCU read lock protects from ABA. */
482 ret
= cds_lfht_del(ht
->ht
, iter
->iter
.node
);
488 * Get first node in the hashtable.
491 void lttng_ht_get_first(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
497 cds_lfht_first(ht
->ht
, &iter
->iter
);
501 * Get next node in the hashtable.
504 void lttng_ht_get_next(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
510 cds_lfht_next(ht
->ht
, &iter
->iter
);
514 * Return the number of nodes in the hashtable.
517 unsigned long lttng_ht_get_count(struct lttng_ht
*ht
)
525 /* RCU read lock protects from ABA and allows RCU traversal. */
527 cds_lfht_count_nodes(ht
->ht
, &scb
, &count
, &sca
);
534 * Return lttng ht string node from iterator.
537 struct lttng_ht_node_str
*lttng_ht_iter_get_node_str(
538 struct lttng_ht_iter
*iter
)
540 struct cds_lfht_node
*node
;
543 node
= cds_lfht_iter_get_node(&iter
->iter
);
547 return caa_container_of(node
, struct lttng_ht_node_str
, node
);
551 * Return lttng ht unsigned long node from iterator.
554 struct lttng_ht_node_ulong
*lttng_ht_iter_get_node_ulong(
555 struct lttng_ht_iter
*iter
)
557 struct cds_lfht_node
*node
;
560 node
= cds_lfht_iter_get_node(&iter
->iter
);
564 return caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
568 * Return lttng ht unsigned long node from iterator.
571 struct lttng_ht_node_u64
*lttng_ht_iter_get_node_u64(
572 struct lttng_ht_iter
*iter
)
574 struct cds_lfht_node
*node
;
577 node
= cds_lfht_iter_get_node(&iter
->iter
);
581 return caa_container_of(node
, struct lttng_ht_node_u64
, node
);
585 * Return lttng ht stream and index id node from iterator.
588 struct lttng_ht_node_two_u64
*lttng_ht_iter_get_node_two_u64(
589 struct lttng_ht_iter
*iter
)
591 struct cds_lfht_node
*node
;
594 node
= cds_lfht_iter_get_node(&iter
->iter
);
598 return caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);