Function: make-hash-table

make-hash-table is a function defined in fns.c.

Signature

(make-hash-table &rest KEYWORD-ARGS)

Documentation

Create and return a new hash table.

Arguments are specified as keyword/argument pairs. The following arguments are defined:

:test TEST -- TEST must be a symbol that specifies how to compare
keys. Default is eql. Predefined are the tests eq, eql, and equal. User-supplied test and hash functions can be specified via define-hash-table-test.

:size SIZE -- A hint as to how many elements will be put in the table.
Default is 65.

:rehash-size REHASH-SIZE - Indicates how to expand the table when it
fills up. If REHASH-SIZE is an integer, increase the size by that amount. If it is a float, it must be > 1.0, and the new size is the old size multiplied by that factor. Default is 1.5.

:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
Resize the hash table when the ratio (table entries / table size) exceeds an approximation to THRESHOLD. Default is 0.8125.

:weakness WEAK -- WEAK must be one of nil, t, key, value,
key-or-value, or key-and-value. If WEAK is not nil, the table returned is a weak table. Key/value pairs are removed from a weak hash table when there are no non-weak references pointing to their key, value, one of key or value, or both key and value, depending on WEAK. WEAK t is equivalent to key-and-value. Default value of WEAK is nil.

:purecopy PURECOPY -- If PURECOPY is non-nil, the table can be copied
to pure storage when Emacs is being dumped, making the contents of the table read only. Any further changes to purified tables will result in an error.

Other relevant functions are documented in the hash-table group.

Probably introduced at or before Emacs version 21.1.

Shortdoc

;; hash-table
(make-hash-table)
    => #s(hash-table ...)

Aliases

cl-make-hash-table (obsolete since 24.3)

Source Code

// Defined in /usr/src/emacs/src/fns.c
{
  Lisp_Object test, weak;
  bool purecopy;
  struct hash_table_test testdesc;
  ptrdiff_t i;
  USE_SAFE_ALLOCA;

  /* The vector `used' is used to keep track of arguments that
     have been consumed.  */
  char *used = SAFE_ALLOCA (nargs * sizeof *used);
  memset (used, 0, nargs * sizeof *used);

  /* See if there's a `:test TEST' among the arguments.  */
  i = get_key_arg (QCtest, nargs, args, used);
  test = i ? args[i] : Qeql;
  if (EQ (test, Qeq))
    testdesc = hashtest_eq;
  else if (EQ (test, Qeql))
    testdesc = hashtest_eql;
  else if (EQ (test, Qequal))
    testdesc = hashtest_equal;
  else
    {
      /* See if it is a user-defined test.  */
      Lisp_Object prop;

      prop = Fget (test, Qhash_table_test);
      if (!CONSP (prop) || !CONSP (XCDR (prop)))
	signal_error ("Invalid hash table test", test);
      testdesc.name = test;
      testdesc.user_cmp_function = XCAR (prop);
      testdesc.user_hash_function = XCAR (XCDR (prop));
      testdesc.hashfn = hashfn_user_defined;
      testdesc.cmpfn = cmpfn_user_defined;
    }

  /* See if there's a `:purecopy PURECOPY' argument.  */
  i = get_key_arg (QCpurecopy, nargs, args, used);
  purecopy = i && !NILP (args[i]);
  /* See if there's a `:size SIZE' argument.  */
  i = get_key_arg (QCsize, nargs, args, used);
  Lisp_Object size_arg = i ? args[i] : Qnil;
  EMACS_INT size;
  if (NILP (size_arg))
    size = DEFAULT_HASH_SIZE;
  else if (FIXNATP (size_arg))
    size = XFIXNAT (size_arg);
  else
    signal_error ("Invalid hash table size", size_arg);

  /* Look for `:rehash-size SIZE'.  */
  float rehash_size;
  i = get_key_arg (QCrehash_size, nargs, args, used);
  if (!i)
    rehash_size = DEFAULT_REHASH_SIZE;
  else if (FIXNUMP (args[i]) && 0 < XFIXNUM (args[i]))
    rehash_size = - XFIXNUM (args[i]);
  else if (FLOATP (args[i]) && 0 < (float) (XFLOAT_DATA (args[i]) - 1))
    rehash_size = (float) (XFLOAT_DATA (args[i]) - 1);
  else
    signal_error ("Invalid hash table rehash size", args[i]);

  /* Look for `:rehash-threshold THRESHOLD'.  */
  i = get_key_arg (QCrehash_threshold, nargs, args, used);
  float rehash_threshold = (!i ? DEFAULT_REHASH_THRESHOLD
			    : !FLOATP (args[i]) ? 0
			    : (float) XFLOAT_DATA (args[i]));
  if (! (0 < rehash_threshold && rehash_threshold <= 1))
    signal_error ("Invalid hash table rehash threshold", args[i]);

  /* Look for `:weakness WEAK'.  */
  i = get_key_arg (QCweakness, nargs, args, used);
  weak = i ? args[i] : Qnil;
  if (EQ (weak, Qt))
    weak = Qkey_and_value;
  if (!NILP (weak)
      && !EQ (weak, Qkey)
      && !EQ (weak, Qvalue)
      && !EQ (weak, Qkey_or_value)
      && !EQ (weak, Qkey_and_value))
    signal_error ("Invalid hash table weakness", weak);

  /* Now, all args should have been used up, or there's a problem.  */
  for (i = 0; i < nargs; ++i)
    if (!used[i])
      signal_error ("Invalid argument list", args[i]);

  SAFE_FREE ();
  return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak,
			  purecopy);
}