[20/59] libctf: add new dynhash functions

Message ID 20200630233146.338613-21-nick.alcock@oracle.com
State New
Headers show
Series
  • Deduplicating CTF linker
Related show

Commit Message

H.J. Lu via Binutils June 30, 2020, 11:31 p.m.
Future commits will use these.

ctf_dynhash_elements: count elements in a dynhash
ctf_dynhash_lookup_kv: look up and return pointers to the original key
                       and value in a dynhash (the only way of getting
                       a reference to the original key)
ctf_dynhash_iter_find: iterate until an item is found, then return its
                       key
ctf_dynhash_cinsert: insert a const key / value into a dynhash (a thim
                     wrapper in a new header dedicated to inline
                     functions).

As with the rest of ctf_dynhash, this is not public API.  No impact
on existing callers is expected.

libctf/
	* ctf-inlines.h: New file.
	* ctf-impl.h: Include it.
	(ctf_hash_iter_find_f): New typedef.
	(ctf_dynhash_elements): New.
	(ctf_dynhash_lookup_kv): New.
	(ctf_dynhash_iter_find): New.
	* ctf-hash.c (ctf_dynhash_lookup_kv): New.
	(ctf_traverse_find_cb_arg_t): New.
	(ctf_hashtab_traverse_find): New.
	(ctf_dynhash_iter_find): New.
	(ctf_dynhash_elements): New.
---
 libctf/ctf-hash.c    | 55 ++++++++++++++++++++++++++++++++++++++++++++
 libctf/ctf-impl.h    |  8 +++++++
 libctf/ctf-inlines.h | 45 ++++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+)
 create mode 100644 libctf/ctf-inlines.h

-- 
2.27.0.247.g3dff7de930

Patch

diff --git a/libctf/ctf-hash.c b/libctf/ctf-hash.c
index 71c1f8e4e21..4696fcb2d43 100644
--- a/libctf/ctf-hash.c
+++ b/libctf/ctf-hash.c
@@ -218,6 +218,12 @@  ctf_dynhash_empty (ctf_dynhash_t *hp)
   htab_empty (hp->htab);
 }
 
+size_t
+ctf_dynhash_elements (ctf_dynhash_t *hp)
+{
+  return htab_elements (hp->htab);
+}
+
 void *
 ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key)
 {
@@ -231,6 +237,26 @@  ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key)
   return NULL;
 }
 
+/* TRUE/FALSE return.  */
+int
+ctf_dynhash_lookup_kv (ctf_dynhash_t *hp, const void *key,
+		       const void **orig_key, void **value)
+{
+  ctf_helem_t **slot;
+
+  slot = ctf_hashtab_lookup (hp->htab, key, NO_INSERT);
+
+  if (slot)
+    {
+      if (orig_key)
+	*orig_key = (*slot)->key;
+      if (value)
+	*value = (*slot)->value;
+      return 1;
+    }
+  return 0;
+}
+
 typedef struct ctf_traverse_cb_arg
 {
   ctf_hash_iter_f fun;
@@ -254,6 +280,35 @@  ctf_dynhash_iter (ctf_dynhash_t *hp, ctf_hash_iter_f fun, void *arg_)
   htab_traverse (hp->htab, ctf_hashtab_traverse, &arg);
 }
 
+typedef struct ctf_traverse_find_cb_arg
+{
+  ctf_hash_iter_find_f fun;
+  void *arg;
+  void *found_key;
+} ctf_traverse_find_cb_arg_t;
+
+static int
+ctf_hashtab_traverse_find (void **slot, void *arg_)
+{
+  ctf_helem_t *helem = *((ctf_helem_t **) slot);
+  ctf_traverse_find_cb_arg_t *arg = (ctf_traverse_find_cb_arg_t *) arg_;
+
+  if (arg->fun (helem->key, helem->value, arg->arg))
+    {
+      arg->found_key = helem->key;
+      return 0;
+    }
+  return 1;
+}
+
+void *
+ctf_dynhash_iter_find (ctf_dynhash_t *hp, ctf_hash_iter_find_f fun, void *arg_)
+{
+  ctf_traverse_find_cb_arg_t arg = { fun, arg_, NULL };
+  htab_traverse (hp->htab, ctf_hashtab_traverse_find, &arg);
+  return arg.found_key;
+}
+
 typedef struct ctf_traverse_remove_cb_arg
 {
   struct htab *htab;
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index f832c71b97c..3e097795bc6 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -382,6 +382,7 @@  typedef void (*ctf_hash_free_fun) (void *);
 
 typedef void (*ctf_hash_iter_f) (void *key, void *value, void *arg);
 typedef int (*ctf_hash_iter_remove_f) (void *key, void *value, void *arg);
+typedef int (*ctf_hash_iter_find_f) (void *key, void *value, void *arg);
 
 extern ctf_hash_t *ctf_hash_create (unsigned long, ctf_hash_fun, ctf_hash_eq_fun);
 extern int ctf_hash_insert_type (ctf_hash_t *, ctf_file_t *, uint32_t, uint32_t);
@@ -394,12 +395,17 @@  extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun,
 					  ctf_hash_free_fun, ctf_hash_free_fun);
 extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *);
 extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *);
+extern size_t ctf_dynhash_elements (ctf_dynhash_t *);
 extern void ctf_dynhash_empty (ctf_dynhash_t *);
 extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *);
+extern int ctf_dynhash_lookup_kv (ctf_dynhash_t *, const void *key,
+				  const void **orig_key, void **value);
 extern void ctf_dynhash_destroy (ctf_dynhash_t *);
 extern void ctf_dynhash_iter (ctf_dynhash_t *, ctf_hash_iter_f, void *);
 extern void ctf_dynhash_iter_remove (ctf_dynhash_t *, ctf_hash_iter_remove_f,
 				     void *);
+extern void *ctf_dynhash_iter_find (ctf_dynhash_t *, ctf_hash_iter_find_f,
+				    void *);
 
 #define	ctf_list_prev(elem)	((void *)(((ctf_list_t *)(elem))->l_prev))
 #define	ctf_list_next(elem)	((void *)(((ctf_list_t *)(elem))->l_next))
@@ -492,6 +498,8 @@  extern const char _CTF_NULLSTR[];	/* empty string */
 extern int _libctf_version;	/* library client version */
 extern int _libctf_debug;	/* debugging messages enabled */
 
+#include "ctf-inlines.h"
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/libctf/ctf-inlines.h b/libctf/ctf-inlines.h
new file mode 100644
index 00000000000..ad74b39f539
--- /dev/null
+++ b/libctf/ctf-inlines.h
@@ -0,0 +1,45 @@ 
+/* Inline functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This file is part of libctf.
+
+   libctf is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_CTF_INLINES_H
+#define	_CTF_INLINES_H
+
+#ifdef	__cplusplus
+extern "C"
+{
+#endif
+
+#include "config.h"
+
+#ifndef _libctf_malloc_
+#error "ctf-inlines.h" should not be included directly: include "ctf-impl.h".
+#endif
+
+
+static inline int
+ctf_dynhash_cinsert (ctf_dynhash_t *h, const void *k, const void *v)
+{
+  return ctf_dynhash_insert (h, (void *) k, (void *) v);
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _CTF_INLINES_H */