1 /* Interface to hashtable implementations.
2 Copyright (C) 2006-2024 Free Software Foundation, Inc.
4 This file is part of libctf.
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "libiberty.h"
25 /* We have two hashtable implementations:
27 - ctf_dynhash_* is an interface to a dynamically-expanding hash with
28 unknown size that should support addition of large numbers of items,
29 and removal as well, and is used only at type-insertion time and during
30 linking. It can be constructed with an expected initial number of
31 elements, but need not be.
33 - ctf_dynset_* is an interface to a dynamically-expanding hash that contains
36 These can be implemented by the same underlying hashmap if you wish. */
38 /* The helem is used for general key/value mappings in the ctf_dynhash: the
39 owner may not have space allocated for it, and will be garbage (not
40 NULL!) in that case. */
42 typedef struct ctf_helem
44 void *key
; /* Either a pointer, or a coerced ctf_id_t. */
45 void *value
; /* The value (possibly a coerced int). */
46 ctf_dynhash_t
*owner
; /* The hash that owns us. */
49 /* Equally, the key_free and value_free may not exist. */
54 ctf_hash_free_fun key_free
;
55 ctf_hash_free_fun value_free
;
58 /* Hash and eq functions for the dynhash and hash. */
61 ctf_hash_integer (const void *ptr
)
63 ctf_helem_t
*hep
= (ctf_helem_t
*) ptr
;
65 return htab_hash_pointer (hep
->key
);
69 ctf_hash_eq_integer (const void *a
, const void *b
)
71 ctf_helem_t
*hep_a
= (ctf_helem_t
*) a
;
72 ctf_helem_t
*hep_b
= (ctf_helem_t
*) b
;
74 return htab_eq_pointer (hep_a
->key
, hep_b
->key
);
78 ctf_hash_string (const void *ptr
)
80 ctf_helem_t
*hep
= (ctf_helem_t
*) ptr
;
82 return htab_hash_string (hep
->key
);
86 ctf_hash_eq_string (const void *a
, const void *b
)
88 ctf_helem_t
*hep_a
= (ctf_helem_t
*) a
;
89 ctf_helem_t
*hep_b
= (ctf_helem_t
*) b
;
91 return !strcmp((const char *) hep_a
->key
, (const char *) hep_b
->key
);
94 /* Hash a type_key. */
96 ctf_hash_type_key (const void *ptr
)
98 ctf_helem_t
*hep
= (ctf_helem_t
*) ptr
;
99 ctf_link_type_key_t
*k
= (ctf_link_type_key_t
*) hep
->key
;
101 return htab_hash_pointer (k
->cltk_fp
) + 59
102 * htab_hash_pointer ((void *) (uintptr_t) k
->cltk_idx
);
106 ctf_hash_eq_type_key (const void *a
, const void *b
)
108 ctf_helem_t
*hep_a
= (ctf_helem_t
*) a
;
109 ctf_helem_t
*hep_b
= (ctf_helem_t
*) b
;
110 ctf_link_type_key_t
*key_a
= (ctf_link_type_key_t
*) hep_a
->key
;
111 ctf_link_type_key_t
*key_b
= (ctf_link_type_key_t
*) hep_b
->key
;
113 return (key_a
->cltk_fp
== key_b
->cltk_fp
)
114 && (key_a
->cltk_idx
== key_b
->cltk_idx
);
117 /* Hash a type_id_key. */
119 ctf_hash_type_id_key (const void *ptr
)
121 ctf_helem_t
*hep
= (ctf_helem_t
*) ptr
;
122 ctf_type_id_key_t
*k
= (ctf_type_id_key_t
*) hep
->key
;
124 return htab_hash_pointer ((void *) (uintptr_t) k
->ctii_input_num
)
125 + 59 * htab_hash_pointer ((void *) (uintptr_t) k
->ctii_type
);
129 ctf_hash_eq_type_id_key (const void *a
, const void *b
)
131 ctf_helem_t
*hep_a
= (ctf_helem_t
*) a
;
132 ctf_helem_t
*hep_b
= (ctf_helem_t
*) b
;
133 ctf_type_id_key_t
*key_a
= (ctf_type_id_key_t
*) hep_a
->key
;
134 ctf_type_id_key_t
*key_b
= (ctf_type_id_key_t
*) hep_b
->key
;
136 return (key_a
->ctii_input_num
== key_b
->ctii_input_num
)
137 && (key_a
->ctii_type
== key_b
->ctii_type
);
140 /* The dynhash, used for hashes whose size is not known at creation time. */
142 /* Free a single ctf_helem with arbitrary key/value functions. */
145 ctf_dynhash_item_free (void *item
)
147 ctf_helem_t
*helem
= item
;
149 if (helem
->owner
->key_free
&& helem
->key
)
150 helem
->owner
->key_free (helem
->key
);
151 if (helem
->owner
->value_free
&& helem
->value
)
152 helem
->owner
->value_free (helem
->value
);
157 ctf_dynhash_create_sized (unsigned long nelems
, ctf_hash_fun hash_fun
,
158 ctf_hash_eq_fun eq_fun
, ctf_hash_free_fun key_free
,
159 ctf_hash_free_fun value_free
)
161 ctf_dynhash_t
*dynhash
;
162 htab_del del
= ctf_dynhash_item_free
;
164 if (key_free
|| value_free
)
165 dynhash
= malloc (sizeof (ctf_dynhash_t
));
168 void *p
= malloc (offsetof (ctf_dynhash_t
, key_free
));
174 if (key_free
== NULL
&& value_free
== NULL
)
177 if ((dynhash
->htab
= htab_create_alloc (nelems
, (htab_hash
) hash_fun
, eq_fun
,
178 del
, xcalloc
, free
)) == NULL
)
184 if (key_free
|| value_free
)
186 dynhash
->key_free
= key_free
;
187 dynhash
->value_free
= value_free
;
194 ctf_dynhash_create (ctf_hash_fun hash_fun
, ctf_hash_eq_fun eq_fun
,
195 ctf_hash_free_fun key_free
, ctf_hash_free_fun value_free
)
197 /* 7 is arbitrary and not benchmarked yet. */
199 return ctf_dynhash_create_sized (7, hash_fun
, eq_fun
, key_free
, value_free
);
202 static ctf_helem_t
**
203 ctf_hashtab_lookup (struct htab
*htab
, const void *key
, enum insert_option insert
)
205 ctf_helem_t tmp
= { .key
= (void *) key
};
206 return (ctf_helem_t
**) htab_find_slot (htab
, &tmp
, insert
);
210 ctf_hashtab_insert (struct htab
*htab
, void *key
, void *value
,
211 ctf_hash_free_fun key_free
,
212 ctf_hash_free_fun value_free
)
216 slot
= ctf_hashtab_lookup (htab
, key
, INSERT
);
226 /* Only spend space on the owner if we're going to use it: if there is a
227 key or value freeing function. */
228 if (key_free
|| value_free
)
229 *slot
= malloc (sizeof (ctf_helem_t
));
232 void *p
= malloc (offsetof (ctf_helem_t
, owner
));
244 value_free ((*slot
)->value
);
246 (*slot
)->value
= value
;
251 ctf_dynhash_insert (ctf_dynhash_t
*hp
, void *key
, void *value
)
254 ctf_hash_free_fun key_free
= NULL
, value_free
= NULL
;
256 if (hp
->htab
->del_f
== ctf_dynhash_item_free
)
258 key_free
= hp
->key_free
;
259 value_free
= hp
->value_free
;
261 slot
= ctf_hashtab_insert (hp
->htab
, key
, value
,
262 key_free
, value_free
);
267 /* Keep track of the owner, so that the del function can get at the key_free
268 and value_free functions. Only do this if one of those functions is set:
269 if not, the owner is not even present in the helem. */
271 if (key_free
|| value_free
)
278 ctf_dynhash_remove (ctf_dynhash_t
*hp
, const void *key
)
280 ctf_helem_t hep
= { (void *) key
, NULL
, NULL
};
281 htab_remove_elt (hp
->htab
, &hep
);
285 ctf_dynhash_empty (ctf_dynhash_t
*hp
)
287 htab_empty (hp
->htab
);
291 ctf_dynhash_elements (ctf_dynhash_t
*hp
)
293 return htab_elements (hp
->htab
);
297 ctf_dynhash_lookup (ctf_dynhash_t
*hp
, const void *key
)
301 slot
= ctf_hashtab_lookup (hp
->htab
, key
, NO_INSERT
);
304 return (*slot
)->value
;
309 /* TRUE/FALSE return. */
311 ctf_dynhash_lookup_kv (ctf_dynhash_t
*hp
, const void *key
,
312 const void **orig_key
, void **value
)
316 slot
= ctf_hashtab_lookup (hp
->htab
, key
, NO_INSERT
);
321 *orig_key
= (*slot
)->key
;
323 *value
= (*slot
)->value
;
329 typedef struct ctf_traverse_cb_arg
333 } ctf_traverse_cb_arg_t
;
336 ctf_hashtab_traverse (void **slot
, void *arg_
)
338 ctf_helem_t
*helem
= *((ctf_helem_t
**) slot
);
339 ctf_traverse_cb_arg_t
*arg
= (ctf_traverse_cb_arg_t
*) arg_
;
341 arg
->fun (helem
->key
, helem
->value
, arg
->arg
);
346 ctf_dynhash_iter (ctf_dynhash_t
*hp
, ctf_hash_iter_f fun
, void *arg_
)
348 ctf_traverse_cb_arg_t arg
= { fun
, arg_
};
349 htab_traverse (hp
->htab
, ctf_hashtab_traverse
, &arg
);
352 typedef struct ctf_traverse_find_cb_arg
354 ctf_hash_iter_find_f fun
;
357 } ctf_traverse_find_cb_arg_t
;
360 ctf_hashtab_traverse_find (void **slot
, void *arg_
)
362 ctf_helem_t
*helem
= *((ctf_helem_t
**) slot
);
363 ctf_traverse_find_cb_arg_t
*arg
= (ctf_traverse_find_cb_arg_t
*) arg_
;
365 if (arg
->fun (helem
->key
, helem
->value
, arg
->arg
))
367 arg
->found_key
= helem
->key
;
374 ctf_dynhash_iter_find (ctf_dynhash_t
*hp
, ctf_hash_iter_find_f fun
, void *arg_
)
376 ctf_traverse_find_cb_arg_t arg
= { fun
, arg_
, NULL
};
377 htab_traverse (hp
->htab
, ctf_hashtab_traverse_find
, &arg
);
378 return arg
.found_key
;
381 typedef struct ctf_traverse_remove_cb_arg
384 ctf_hash_iter_remove_f fun
;
386 } ctf_traverse_remove_cb_arg_t
;
389 ctf_hashtab_traverse_remove (void **slot
, void *arg_
)
391 ctf_helem_t
*helem
= *((ctf_helem_t
**) slot
);
392 ctf_traverse_remove_cb_arg_t
*arg
= (ctf_traverse_remove_cb_arg_t
*) arg_
;
394 if (arg
->fun (helem
->key
, helem
->value
, arg
->arg
))
395 htab_clear_slot (arg
->htab
, slot
);
400 ctf_dynhash_iter_remove (ctf_dynhash_t
*hp
, ctf_hash_iter_remove_f fun
,
403 ctf_traverse_remove_cb_arg_t arg
= { hp
->htab
, fun
, arg_
};
404 htab_traverse (hp
->htab
, ctf_hashtab_traverse_remove
, &arg
);
407 /* Traverse a dynhash in arbitrary order, in _next iterator form.
409 Mutating the dynhash while iterating is not supported (just as it isn't for
412 Note: unusually, this returns zero on success and a *positive* value on
413 error, because it does not take an fp, taking an error pointer would be
414 incredibly clunky, and nearly all error-handling ends up stuffing the result
415 of this into some sort of errno or ctf_errno, which is invariably
416 positive. So doing this simplifies essentially all callers. */
418 ctf_dynhash_next (ctf_dynhash_t
*h
, ctf_next_t
**it
, void **key
, void **value
)
425 size_t size
= htab_size (h
->htab
);
427 /* If the table has too many entries to fit in an ssize_t, just give up.
428 This might be spurious, but if any type-related hashtable has ever been
429 nearly as large as that then something very odd is going on. */
430 if (((ssize_t
) size
) < 0)
433 if ((i
= ctf_next_create ()) == NULL
)
436 i
->u
.ctn_hash_slot
= h
->htab
->entries
;
439 i
->ctn_size
= (ssize_t
) size
;
440 i
->ctn_iter_fun
= (void (*) (void)) ctf_dynhash_next
;
444 if ((void (*) (void)) ctf_dynhash_next
!= i
->ctn_iter_fun
)
445 return ECTF_NEXT_WRONGFUN
;
447 if (h
!= i
->cu
.ctn_h
)
448 return ECTF_NEXT_WRONGFP
;
450 if ((ssize_t
) i
->ctn_n
== i
->ctn_size
)
453 while ((ssize_t
) i
->ctn_n
< i
->ctn_size
454 && (*i
->u
.ctn_hash_slot
== HTAB_EMPTY_ENTRY
455 || *i
->u
.ctn_hash_slot
== HTAB_DELETED_ENTRY
))
457 i
->u
.ctn_hash_slot
++;
461 if ((ssize_t
) i
->ctn_n
== i
->ctn_size
)
464 slot
= *i
->u
.ctn_hash_slot
;
469 *value
= slot
->value
;
471 i
->u
.ctn_hash_slot
++;
477 ctf_next_destroy (i
);
479 return ECTF_NEXT_END
;
483 ctf_dynhash_sort_by_name (const ctf_next_hkv_t
*one
, const ctf_next_hkv_t
*two
,
484 void *unused _libctf_unused_
)
486 return strcmp ((char *) one
->hkv_key
, (char *) two
->hkv_key
);
489 /* Traverse a sorted dynhash, in _next iterator form.
491 See ctf_dynhash_next for notes on error returns, etc.
493 Sort keys before iterating over them using the SORT_FUN and SORT_ARG.
495 If SORT_FUN is null, thunks to ctf_dynhash_next. */
497 ctf_dynhash_next_sorted (ctf_dynhash_t
*h
, ctf_next_t
**it
, void **key
,
498 void **value
, ctf_hash_sort_f sort_fun
, void *sort_arg
)
502 if (sort_fun
== NULL
)
503 return ctf_dynhash_next (h
, it
, key
, value
);
507 size_t els
= ctf_dynhash_elements (h
);
508 ctf_next_t
*accum_i
= NULL
;
511 ctf_next_hkv_t
*walk
;
513 if (((ssize_t
) els
) < 0)
516 if ((i
= ctf_next_create ()) == NULL
)
519 if ((i
->u
.ctn_sorted_hkv
= calloc (els
, sizeof (ctf_next_hkv_t
))) == NULL
)
521 ctf_next_destroy (i
);
524 walk
= i
->u
.ctn_sorted_hkv
;
528 while ((err
= ctf_dynhash_next (h
, &accum_i
, &key
, &value
)) == 0)
531 walk
->hkv_value
= value
;
534 if (err
!= ECTF_NEXT_END
)
536 ctf_next_destroy (i
);
541 ctf_qsort_r (i
->u
.ctn_sorted_hkv
, els
, sizeof (ctf_next_hkv_t
),
542 (int (*) (const void *, const void *, void *)) sort_fun
,
545 i
->ctn_size
= (ssize_t
) els
;
546 i
->ctn_iter_fun
= (void (*) (void)) ctf_dynhash_next_sorted
;
550 if ((void (*) (void)) ctf_dynhash_next_sorted
!= i
->ctn_iter_fun
)
551 return ECTF_NEXT_WRONGFUN
;
553 if (h
!= i
->cu
.ctn_h
)
554 return ECTF_NEXT_WRONGFP
;
556 if ((ssize_t
) i
->ctn_n
== i
->ctn_size
)
558 ctf_next_destroy (i
);
560 return ECTF_NEXT_END
;
564 *key
= i
->u
.ctn_sorted_hkv
[i
->ctn_n
].hkv_key
;
566 *value
= i
->u
.ctn_sorted_hkv
[i
->ctn_n
].hkv_value
;
572 ctf_dynhash_destroy (ctf_dynhash_t
*hp
)
575 htab_delete (hp
->htab
);
579 /* The dynset, used for sets of keys with no value. The implementation of this
580 can be much simpler, because without a value the slot can simply be the
581 stored key, which means we don't need to store the freeing functions and the
582 dynset itself is just a htab. */
585 ctf_dynset_create (htab_hash hash_fun
, htab_eq eq_fun
,
586 ctf_hash_free_fun key_free
)
588 /* 7 is arbitrary and untested for now. */
589 return (ctf_dynset_t
*) htab_create_alloc (7, (htab_hash
) hash_fun
, eq_fun
,
590 key_free
, xcalloc
, free
);
593 /* The dynset has one complexity: the underlying implementation reserves two
594 values for internal hash table implementation details (empty versus deleted
595 entries). These values are otherwise very useful for pointers cast to ints,
596 so transform the ctf_dynset_inserted value to allow for it. (This
597 introduces an ambiguity in that one can no longer store these two values in
598 the dynset, but if we pick high enough values this is very unlikely to be a
601 We leak this implementation detail to the freeing functions on the grounds
602 that any use of these functions is overwhelmingly likely to be in sets using
603 real pointers, which will be unaffected. */
605 #define DYNSET_EMPTY_ENTRY_REPLACEMENT ((void *) (uintptr_t) -64)
606 #define DYNSET_DELETED_ENTRY_REPLACEMENT ((void *) (uintptr_t) -63)
609 key_to_internal (const void *key
)
611 if (key
== HTAB_EMPTY_ENTRY
)
612 return DYNSET_EMPTY_ENTRY_REPLACEMENT
;
613 else if (key
== HTAB_DELETED_ENTRY
)
614 return DYNSET_DELETED_ENTRY_REPLACEMENT
;
620 internal_to_key (const void *internal
)
622 if (internal
== DYNSET_EMPTY_ENTRY_REPLACEMENT
)
623 return HTAB_EMPTY_ENTRY
;
624 else if (internal
== DYNSET_DELETED_ENTRY_REPLACEMENT
)
625 return HTAB_DELETED_ENTRY
;
626 return (void *) internal
;
630 ctf_dynset_insert (ctf_dynset_t
*hp
, void *key
)
632 struct htab
*htab
= (struct htab
*) hp
;
635 slot
= htab_find_slot (htab
, key_to_internal (key
), INSERT
);
646 (*htab
->del_f
) (*slot
);
649 *slot
= key_to_internal (key
);
655 ctf_dynset_remove (ctf_dynset_t
*hp
, const void *key
)
657 htab_remove_elt ((struct htab
*) hp
, key_to_internal (key
));
661 ctf_dynset_elements (ctf_dynset_t
*hp
)
663 return htab_elements ((struct htab
*) hp
);
667 ctf_dynset_destroy (ctf_dynset_t
*hp
)
670 htab_delete ((struct htab
*) hp
);
674 ctf_dynset_lookup (ctf_dynset_t
*hp
, const void *key
)
676 void **slot
= htab_find_slot ((struct htab
*) hp
,
677 key_to_internal (key
), NO_INSERT
);
680 return internal_to_key (*slot
);
684 /* TRUE/FALSE return. */
686 ctf_dynset_exists (ctf_dynset_t
*hp
, const void *key
, const void **orig_key
)
688 void **slot
= htab_find_slot ((struct htab
*) hp
,
689 key_to_internal (key
), NO_INSERT
);
691 if (orig_key
&& slot
)
692 *orig_key
= internal_to_key (*slot
);
693 return (slot
!= NULL
);
696 /* Look up a completely random value from the set, if any exist.
697 Keys with value zero cannot be distinguished from a nonexistent key. */
699 ctf_dynset_lookup_any (ctf_dynset_t
*hp
)
701 struct htab
*htab
= (struct htab
*) hp
;
702 void **slot
= htab
->entries
;
703 void **limit
= slot
+ htab_size (htab
);
706 && (*slot
== HTAB_EMPTY_ENTRY
|| *slot
== HTAB_DELETED_ENTRY
))
710 return internal_to_key (*slot
);
714 /* Traverse a dynset in arbitrary order, in _next iterator form.
716 Otherwise, just like ctf_dynhash_next. */
718 ctf_dynset_next (ctf_dynset_t
*hp
, ctf_next_t
**it
, void **key
)
720 struct htab
*htab
= (struct htab
*) hp
;
726 size_t size
= htab_size (htab
);
728 /* If the table has too many entries to fit in an ssize_t, just give up.
729 This might be spurious, but if any type-related hashtable has ever been
730 nearly as large as that then somthing very odd is going on. */
732 if (((ssize_t
) size
) < 0)
735 if ((i
= ctf_next_create ()) == NULL
)
738 i
->u
.ctn_hash_slot
= htab
->entries
;
741 i
->ctn_size
= (ssize_t
) size
;
742 i
->ctn_iter_fun
= (void (*) (void)) ctf_dynset_next
;
746 if ((void (*) (void)) ctf_dynset_next
!= i
->ctn_iter_fun
)
747 return ECTF_NEXT_WRONGFUN
;
749 if (hp
!= i
->cu
.ctn_s
)
750 return ECTF_NEXT_WRONGFP
;
752 if ((ssize_t
) i
->ctn_n
== i
->ctn_size
)
755 while ((ssize_t
) i
->ctn_n
< i
->ctn_size
756 && (*i
->u
.ctn_hash_slot
== HTAB_EMPTY_ENTRY
757 || *i
->u
.ctn_hash_slot
== HTAB_DELETED_ENTRY
))
759 i
->u
.ctn_hash_slot
++;
763 if ((ssize_t
) i
->ctn_n
== i
->ctn_size
)
766 slot
= *i
->u
.ctn_hash_slot
;
769 *key
= internal_to_key (slot
);
771 i
->u
.ctn_hash_slot
++;
777 ctf_next_destroy (i
);
779 return ECTF_NEXT_END
;
782 /* Helper functions for insertion/removal of types. */
785 ctf_dynhash_insert_type (ctf_dict_t
*fp
, ctf_dynhash_t
*hp
, uint32_t type
,
794 if ((str
= ctf_strptr_validate (fp
, name
)) == NULL
)
795 return ctf_errno (fp
) * -1;
798 return 0; /* Just ignore empty strings on behalf of caller. */
800 if ((err
= ctf_dynhash_insert (hp
, (char *) str
,
801 (void *) (ptrdiff_t) type
)) == 0)
804 /* ctf_dynhash_insert returns a negative error value: negate it for
806 ctf_set_errno (fp
, err
* -1);
811 ctf_dynhash_lookup_type (ctf_dynhash_t
*hp
, const char *key
)
815 if (ctf_dynhash_lookup_kv (hp
, key
, NULL
, &value
))
816 return (ctf_id_t
) (uintptr_t) value
;