* hash.c: Added some documentation.
authorIan Lance Taylor <ian@airs.com>
Mon, 3 Jan 1994 16:47:46 +0000 (16:47 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 3 Jan 1994 16:47:46 +0000 (16:47 +0000)
bfd/ChangeLog
bfd/hash.c

index 18fdc63..035c25f 100644 (file)
@@ -1,3 +1,7 @@
+Mon Jan  3 11:41:45 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * hash.c: Added some documentation.
+
 Mon Jan  3 11:09:28 1994  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * aout-target.h, netbsd386.c: Replace NO_SWAP_MAGIC with SWAP_MAGIC,
index 991b2c3..9effba8 100644 (file)
@@ -23,6 +23,272 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "libbfd.h"
 #include "obstack.h"
 
+/*
+SECTION
+       Hash Tables
+
+@cindex Hash tables
+       BFD provides a simple set of hash table functions.  Routines
+       are provided to initialize a hash table, to free a hash table,
+       to look up a string in a hash table and optionally create an
+       entry for it, and to traverse a hash table.  There is
+       currently no routine to delete an string from a hash table.
+
+       The basic hash table does not permit any data to be stored
+       with a string.  However, a hash table is designed to present a
+       base class from which other types of hash tables may be
+       derived.  These derived types may store additional information
+       with the string.  Hash tables were implemented in this way,
+       rather than simply providing a data pointer in a hash table
+       entry, because they were designed for use by the linker back
+       ends.  The linker may create thousands of hash table entries,
+       and the overhead of allocating private data and storing and
+       following pointers becomes noticeable.
+
+       The basic hash table code is in <<hash.c>>.
+
+@menu
+@* Creating and Freeing a Hash Table::
+@* Looking Up or Entering a String::
+@* Traversing a Hash Table::
+@* Deriving a New Hash Table Type::
+@end menu
+
+INODE
+Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables
+SUBSECTION
+       Creating and freeing a hash table
+
+@findex bfd_hash_table_init
+@findex bfd_hash_table_init_n
+       To create a hash table, create an instance of a <<struct
+       bfd_hash_table>> (defined in <<bfd.h>>) and call
+       <<bfd_hash_table_init>> (if you know approximately how many
+       entries you will need, the function <<bfd_hash_table_init_n>>,
+       which takes a @var{size} argument, may be used).
+       <<bfd_hash_table_init>> returns <<false>> if some sort of
+       error occurs.
+
+@findex bfd_hash_newfunc
+       The function <<bfd_hash_table_init>> take as an argument a
+       function to use to create new entries.  For a basic hash
+       table, use the function <<bfd_hash_newfunc>>.  @xref{Deriving
+       a New Hash Table Type} for why you would want to use a
+       different value for this argument.
+
+@findex bfd_hash_allocate
+       <<bfd_hash_table_init>> will create an obstack which will be
+       used to allocate new entries.  You may allocate memory on this
+       obstack using <<bfd_hash_allocate>>.
+
+@findex bfd_hash_table_free
+       Use <<bfd_hash_table_free>> to free up all the memory that has
+       been allocated for a hash table.  This will not free up the
+       <<struct bfd_hash_table>> itself, which you must provide.
+
+INODE
+Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables
+SUBSECTION
+       Looking up or entering a string
+
+@findex bfd_hash_lookup
+       The function <<bfd_hash_lookup>> is used both to look up a
+       string in the hash table and to create a new entry.
+
+       If the @var{create} argument is <<false>>, <<bfd_hash_lookup>>
+       will look up a string.  If the string is found, it will
+       returns a pointer to a <<struct bfd_hash_entry>>.  If the
+       string is not found in the table <<bfd_hash_lookup>> will
+       return <<NULL>>.  You should not modify any of the fields in
+       the returns <<struct bfd_hash_entry>>.
+
+       If the @var{create} argument is <<true>>, the string will be
+       entered into the hash table if it is not already there.
+       Either way a pointer to a <<struct bfd_hash_entry>> will be
+       returned, either to the existing structure or to a newly
+       created one.  In this case, a <<NULL>> return means that an
+       error occurred.
+
+       If the @var{create} argument is <<true>>, and a new entry is
+       created, the @var{copy} argument is used to decide whether to
+       copy the string onto the hash table obstack or not.  If
+       @var{copy} is passed as <<false>>, you must be careful not to
+       deallocate or modify the string as long as the hash table
+       exists.
+
+INODE
+Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables
+SUBSECTION
+       Traversing a hash table
+
+@findex bfd_hash_traverse
+       The function <<bfd_hash_traverse>> may be used to traverse a
+       hash table, calling a function on each element.  The traversal
+       is done in a random order.
+
+       <<bfd_hash_traverse>> takes as arguments a function and a
+       generic <<void *>> pointer.  The function is called with a
+       hash table entry (a <<struct bfd_hash_entry *>>) and the
+       generic pointer passed to <<bfd_hash_traverse>>.  The function
+       must return a <<boolean>> value, which indicates whether to
+       continue traversing the hash table.  If the function returns
+       <<false>>, <<bfd_hash_traverse>> will stop the traversal and
+       return immediately.
+
+INODE
+Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables
+SUBSECTION
+       Deriving a new hash table type
+
+       Many uses of hash tables want to store additional information
+       which each entry in the hash table.  Some also find it
+       convenient to store additional information with the hash table
+       itself.  This may be done using a derived hash table.
+
+       Since C is not an object oriented language, creating a derived
+       hash table requires sticking together some boilerplate
+       routines with a few differences specific to the type of hash
+       table you want to create.
+
+       An example of a derived hash table is the linker hash table.
+       The structures for this are defined in <<bfdlink.h>>.  The
+       functions are in <<linker.c>>.
+
+       You may also derive a hash table from an already derived hash
+       table.  For example, the a.out linker backend code uses a hash
+       table derived from the linker hash table.
+
+@menu
+@* Define the Derived Structures::
+@* Write the Derived Creation Routine::
+@* Write Other Derived Routines::
+@end menu
+
+INODE
+Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type
+SUBSUBSECTION
+       Define the derived structures
+
+       You must define a structure for an entry in the hash table,
+       and a structure for the hash table itself.
+
+       The first field in the structure for an entry in the hash
+       table must be of the type used for an entry in the hash table
+       you are deriving from.  If you are deriving from a basic hash
+       table this is <<struct bfd_hash_entry>>, which is defined in
+       <<bfd.h>>.  The first field in the structure for the hash
+       table itself must be of the type of the hash table you are
+       deriving from itself.  If you are deriving from a basic hash
+       table, this is <<struct bfd_hash_table>>.
+
+       For example, the linker hash table defines <<struct
+       bfd_link_hash_entry>> (in <<bfdlink.h>>).  The first field,
+       <<root>>, is of type <<struct bfd_hash_entry>>.  Similarly,
+       the first field in <<struct bfd_link_hash_table>>, <<table>>,
+       is of type <<struct bfd_hash_table>>.
+
+INODE
+Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type
+SUBSUBSECTION
+       Write the derived creation routine
+
+       You must write a routine which will create and initialize an
+       entry in the hash table.  This routine is passed as the
+       function argument to <<bfd_hash_table_init>>.
+
+       In order to permit other hash tables to be derived from the
+       hash table you are creating, this routine must be written in a
+       standard way.
+
+       The first argument to the creation routine is a pointer to a
+       hash table entry.  This may be <<NULL>>, in which case the
+       routine should allocate the right amount of space.  Otherwise
+       the space has already been allocated by a hash table type
+       derived from this one.
+
+       After allocating space, the creation routine must call the
+       creation routine of the hash table type it is derived from,
+       passing in a pointer to the space it just allocated.  This
+       will initialize any fields used by the base hash table.
+
+       Finally the creation routine must initialize any local fields
+       for the new hash table type.
+
+       Here is a boilerplate example of a creation routine.
+       @var{function_name} is the name of the routine.
+       @var{entry_type} is the type of an entry in the hash table you
+       are creating.  @var{base_newfunc} is the name of the creation
+       routine of the hash table type your hash table is derived
+       from.
+
+EXAMPLE
+
+.struct bfd_hash_entry *
+.@var{function_name} (entry, table, string)
+.     struct bfd_hash_entry *entry;
+.     struct bfd_hash_table *table;
+.     const char *string;
+.{
+.  struct @var{entry_type} *ret = (@var{entry_type} *) entry;
+.
+. {* Allocate the structure if it has not already been allocated by a
+.    derived class.  *}
+.  if (ret == (@var{entry_type} *) NULL)
+.    ret = ((@var{entry_type} *)
+.         bfd_hash_allocate (table, sizeof (@var{entry_type})));
+.
+. {* Call the allocation method of the base class.  *}
+.  ret = ((@var{entry_type} *)
+.       @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string));
+.
+. {* Initialize the local fields here.  *}
+.
+.  return (struct bfd_hash_entry *) ret;
+.}
+
+DESCRIPTION
+       The creation routine for the linker hash table, which is in
+       <<linker.c>>, looks just like this example.
+       @var{function_name} is <<_bfd_link_hash_newfunc>>.
+       @var{entry_type} is <<struct bfd_link_hash_entry>>.
+       @var{base_newfunc} is <<bfd_hash_newfunc>>, the creation
+       routine for a basic hash table.
+
+       <<_bfd_link_hash_newfunc>> also initializes the local fields
+       in a linker hash table entry: <<type>>, <<written>> and
+       <<next>>.
+
+INODE
+Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type
+SUBSUBSECTION
+       Write other derived routines
+
+       You will want to write other routines for your new hash table,
+       as well.  
+
+       You will want an initialization routine which calls the
+       initialization routine of the hash table you are deriving from
+       and initializes any other local fields.  For the linker hash
+       table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>.
+
+       You will want a lookup routine which calls the lookup routine
+       of the hash table you are deriving from and casts the result.
+       The linker hash table uses <<bfd_link_hash_lookup>> in
+       <<linker.c>> (this actually takes an additional argument which
+       it uses to decide how to return the looked up value).
+
+       You may want a traversal routine.  This should just call the
+       traversal routine of the hash table you are deriving from with
+       appropriate casts.  The linker hash table uses
+       <<bfd_link_hash_traverse>> in <<linker.c>>.
+
+       These routines may simply be defined as macros.  For example,
+       the a.out backend linker hash table, which is derived from the
+       linker hash table, uses macros for the lookup and traversal
+       routines.  These are <<aout_link_hash_lookup>> and
+       <<aout_link_hash_traverse>> in aoutx.h.
+*/
+
 /* Obstack allocation and deallocation routines.  */
 #define obstack_chunk_alloc bfd_xmalloc_by_size_t
 #define obstack_chunk_free free