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.
23 #include <urcu/compiler.h>
25 #include <common/common.h>
26 #include <common/defaults.h>
28 #include "hashtable.h"
31 unsigned long lttng_ht_seed
;
33 static unsigned long min_hash_alloc_size
= 1;
34 static unsigned long max_hash_buckets_size
= 0;
37 * Getter/lookup functions need to be called with RCU read-side lock
38 * held. However, modification functions (add, add_unique, replace, del)
39 * take the RCU lock internally, so it does not matter whether the
40 * caller hold the RCU lock or not.
44 * Match function for string node.
46 static int match_str(struct cds_lfht_node
*node
, const void *key
)
48 struct lttng_ht_node_str
*match_node
=
49 caa_container_of(node
, struct lttng_ht_node_str
, node
);
51 return hash_match_key_str(match_node
->key
, (void *) key
);
55 * Match function for ulong node.
57 static int match_ulong(struct cds_lfht_node
*node
, const void *key
)
59 struct lttng_ht_node_ulong
*match_node
=
60 caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
62 return hash_match_key_ulong((void *) match_node
->key
, (void *) key
);
66 * Match function for u64 node.
68 static int match_u64(struct cds_lfht_node
*node
, const void *key
)
70 struct lttng_ht_node_u64
*match_node
=
71 caa_container_of(node
, struct lttng_ht_node_u64
, node
);
73 return hash_match_key_u64(&match_node
->key
, (void *) key
);
77 * Match function for two uint64_t node.
79 static int match_two_u64(struct cds_lfht_node
*node
, const void *key
)
81 struct lttng_ht_node_two_u64
*match_node
=
82 caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);
84 return hash_match_key_two_u64((void *) &match_node
->key
, (void *) key
);
88 * Return an allocated lttng hashtable.
90 struct lttng_ht
*lttng_ht_new(unsigned long size
, int type
)
96 size
= DEFAULT_HT_SIZE
;
98 ht
= zmalloc(sizeof(*ht
));
100 PERROR("zmalloc lttng_ht");
104 ht
->ht
= cds_lfht_new(size
, min_hash_alloc_size
, max_hash_buckets_size
,
105 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
107 * There is already an assert in the RCU hashtable code so if the ht is
108 * NULL here there is a *huge* problem.
113 case LTTNG_HT_TYPE_STRING
:
114 ht
->match_fct
= match_str
;
115 ht
->hash_fct
= hash_key_str
;
117 case LTTNG_HT_TYPE_ULONG
:
118 ht
->match_fct
= match_ulong
;
119 ht
->hash_fct
= hash_key_ulong
;
121 case LTTNG_HT_TYPE_U64
:
122 ht
->match_fct
= match_u64
;
123 ht
->hash_fct
= hash_key_u64
;
125 case LTTNG_HT_TYPE_TWO_U64
:
126 ht
->match_fct
= match_two_u64
;
127 ht
->hash_fct
= hash_key_two_u64
;
130 ERR("Unknown lttng hashtable type %d", type
);
131 lttng_ht_destroy(ht
);
135 DBG3("Created hashtable size %lu at %p of type %d", size
, ht
->ht
, type
);
144 * Free a lttng hashtable.
146 void lttng_ht_destroy(struct lttng_ht
*ht
)
150 ret
= cds_lfht_destroy(ht
->ht
, NULL
);
156 * Init lttng ht node string.
158 void lttng_ht_node_init_str(struct lttng_ht_node_str
*node
, char *key
)
163 cds_lfht_node_init(&node
->node
);
167 * Init lttng ht node unsigned long.
169 void lttng_ht_node_init_ulong(struct lttng_ht_node_ulong
*node
,
175 cds_lfht_node_init(&node
->node
);
179 * Init lttng ht node uint64_t.
181 void lttng_ht_node_init_u64(struct lttng_ht_node_u64
*node
,
187 cds_lfht_node_init(&node
->node
);
191 * Init lttng ht node with two uint64_t.
193 void lttng_ht_node_init_two_u64(struct lttng_ht_node_two_u64
*node
,
194 uint64_t key1
, uint64_t key2
)
198 node
->key
.key1
= key1
;
199 node
->key
.key2
= key2
;
200 cds_lfht_node_init(&node
->node
);
204 * Free lttng ht node string.
206 void lttng_ht_node_free_str(struct lttng_ht_node_str
*node
)
213 * Free lttng ht node unsigned long.
215 void lttng_ht_node_free_ulong(struct lttng_ht_node_ulong
*node
)
222 * Free lttng ht node uint64_t.
224 void lttng_ht_node_free_u64(struct lttng_ht_node_u64
*node
)
231 * Free lttng ht node two uint64_t.
233 void lttng_ht_node_free_two_u64(struct lttng_ht_node_two_u64
*node
)
240 * Lookup function in hashtable.
242 void lttng_ht_lookup(struct lttng_ht
*ht
, void *key
,
243 struct lttng_ht_iter
*iter
)
248 cds_lfht_lookup(ht
->ht
, ht
->hash_fct(key
, lttng_ht_seed
),
249 ht
->match_fct
, key
, &iter
->iter
);
253 * Add unique string node to hashtable.
255 void lttng_ht_add_unique_str(struct lttng_ht
*ht
,
256 struct lttng_ht_node_str
*node
)
258 struct cds_lfht_node
*node_ptr
;
263 /* RCU read lock protects from ABA. */
265 node_ptr
= cds_lfht_add_unique(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
266 ht
->match_fct
, node
->key
, &node
->node
);
268 assert(node_ptr
== &node
->node
);
272 * Add string node to hashtable.
274 void lttng_ht_add_str(struct lttng_ht
*ht
,
275 struct lttng_ht_node_str
*node
)
281 /* RCU read lock protects from ABA. */
283 cds_lfht_add(ht
->ht
, ht
->hash_fct(node
->key
, lttng_ht_seed
),
289 * Add unsigned long node to hashtable.
291 void lttng_ht_add_ulong(struct lttng_ht
*ht
, struct lttng_ht_node_ulong
*node
)
297 /* RCU read lock protects from ABA. */
299 cds_lfht_add(ht
->ht
, ht
->hash_fct((void *) node
->key
, lttng_ht_seed
),
305 * Add uint64_t node to hashtable.
308 void lttng_ht_add_u64(struct lttng_ht
*ht
, struct lttng_ht_node_u64
*node
)
314 /* RCU read lock protects from ABA. */
316 cds_lfht_add(ht
->ht
, ht
->hash_fct(&node
->key
, lttng_ht_seed
),
322 * Add unique unsigned long node to hashtable.
324 void lttng_ht_add_unique_ulong(struct lttng_ht
*ht
,
325 struct lttng_ht_node_ulong
*node
)
327 struct cds_lfht_node
*node_ptr
;
332 /* RCU read lock protects from ABA. */
334 node_ptr
= cds_lfht_add_unique(ht
->ht
,
335 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
336 (void *) node
->key
, &node
->node
);
338 assert(node_ptr
== &node
->node
);
342 * Add unique uint64_t node to hashtable.
344 void lttng_ht_add_unique_u64(struct lttng_ht
*ht
,
345 struct lttng_ht_node_u64
*node
)
347 struct cds_lfht_node
*node_ptr
;
352 /* RCU read lock protects from ABA. */
354 node_ptr
= cds_lfht_add_unique(ht
->ht
,
355 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
356 &node
->key
, &node
->node
);
358 assert(node_ptr
== &node
->node
);
362 * Add unique two uint64_t node to hashtable.
364 void lttng_ht_add_unique_two_u64(struct lttng_ht
*ht
,
365 struct lttng_ht_node_two_u64
*node
)
367 struct cds_lfht_node
*node_ptr
;
372 /* RCU read lock protects from ABA. */
374 node_ptr
= cds_lfht_add_unique(ht
->ht
,
375 ht
->hash_fct((void *) &node
->key
, lttng_ht_seed
), ht
->match_fct
,
376 (void *) &node
->key
, &node
->node
);
378 assert(node_ptr
== &node
->node
);
382 * Add replace unsigned long node to hashtable.
384 struct lttng_ht_node_ulong
*lttng_ht_add_replace_ulong(struct lttng_ht
*ht
,
385 struct lttng_ht_node_ulong
*node
)
387 struct cds_lfht_node
*node_ptr
;
392 /* RCU read lock protects from ABA. */
394 node_ptr
= cds_lfht_add_replace(ht
->ht
,
395 ht
->hash_fct((void *) node
->key
, lttng_ht_seed
), ht
->match_fct
,
396 (void *) node
->key
, &node
->node
);
401 return caa_container_of(node_ptr
, struct lttng_ht_node_ulong
, node
);
403 assert(node_ptr
== &node
->node
);
407 * Add replace unsigned long node to hashtable.
409 struct lttng_ht_node_u64
*lttng_ht_add_replace_u64(struct lttng_ht
*ht
,
410 struct lttng_ht_node_u64
*node
)
412 struct cds_lfht_node
*node_ptr
;
417 /* RCU read lock protects from ABA. */
419 node_ptr
= cds_lfht_add_replace(ht
->ht
,
420 ht
->hash_fct(&node
->key
, lttng_ht_seed
), ht
->match_fct
,
421 &node
->key
, &node
->node
);
426 return caa_container_of(node_ptr
, struct lttng_ht_node_u64
, node
);
428 assert(node_ptr
== &node
->node
);
432 * Delete node from hashtable.
434 int lttng_ht_del(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
442 /* RCU read lock protects from ABA. */
444 ret
= cds_lfht_del(ht
->ht
, iter
->iter
.node
);
450 * Get first node in the hashtable.
452 void lttng_ht_get_first(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
458 cds_lfht_first(ht
->ht
, &iter
->iter
);
462 * Get next node in the hashtable.
464 void lttng_ht_get_next(struct lttng_ht
*ht
, struct lttng_ht_iter
*iter
)
470 cds_lfht_next(ht
->ht
, &iter
->iter
);
474 * Return the number of nodes in the hashtable.
476 unsigned long lttng_ht_get_count(struct lttng_ht
*ht
)
484 /* RCU read lock protects from ABA and allows RCU traversal. */
486 cds_lfht_count_nodes(ht
->ht
, &scb
, &count
, &sca
);
493 * Return lttng ht string node from iterator.
495 struct lttng_ht_node_str
*lttng_ht_iter_get_node_str(
496 struct lttng_ht_iter
*iter
)
498 struct cds_lfht_node
*node
;
501 node
= cds_lfht_iter_get_node(&iter
->iter
);
505 return caa_container_of(node
, struct lttng_ht_node_str
, node
);
509 * Return lttng ht unsigned long node from iterator.
511 struct lttng_ht_node_ulong
*lttng_ht_iter_get_node_ulong(
512 struct lttng_ht_iter
*iter
)
514 struct cds_lfht_node
*node
;
517 node
= cds_lfht_iter_get_node(&iter
->iter
);
521 return caa_container_of(node
, struct lttng_ht_node_ulong
, node
);
525 * Return lttng ht unsigned long node from iterator.
527 struct lttng_ht_node_u64
*lttng_ht_iter_get_node_u64(
528 struct lttng_ht_iter
*iter
)
530 struct cds_lfht_node
*node
;
533 node
= cds_lfht_iter_get_node(&iter
->iter
);
537 return caa_container_of(node
, struct lttng_ht_node_u64
, node
);
541 * Return lttng ht stream and index id node from iterator.
543 struct lttng_ht_node_two_u64
*lttng_ht_iter_get_node_two_u64(
544 struct lttng_ht_iter
*iter
)
546 struct cds_lfht_node
*node
;
549 node
= cds_lfht_iter_get_node(&iter
->iter
);
553 return caa_container_of(node
, struct lttng_ht_node_two_u64
, node
);
559 static void __attribute__((constructor
)) _init(void)
561 /* Init hash table seed */
562 lttng_ht_seed
= (unsigned long) time(NULL
);
This page took 0.044547 seconds and 5 git commands to generate.