make-hash-table
code: fns.el
DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
doc: /* 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.
usage: (make-hash-table &rest KEYWORD-ARGS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
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);
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 (argsi); /* See if there's a `:size SIZE' argument. */
i = get_key_arg (QCsize, nargs, args, used);
Lisp_Object size_arg = i ? argsi : 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 (argsi) && 0 < XFIXNUM (argsi)) rehash_size = - XFIXNUM (argsi); else if (FLOATP (argsi) && 0 < (float) (XFLOAT_DATA (argsi) - 1)) rehash_size = (float) (XFLOAT_DATA (argsi) - 1); else
signal_error ("Invalid hash table rehash size", argsi); /* Look for `:rehash-threshold THRESHOLD'. */
i = get_key_arg (QCrehash_threshold, nargs, args, used);
float rehash_threshold = (!i ? DEFAULT_REHASH_THRESHOLD
: (float) XFLOAT_DATA (argsi)); if (! (0 < rehash_threshold && rehash_threshold <= 1))
signal_error ("Invalid hash table rehash threshold", argsi); /* Look for `:weakness WEAK'. */
i = get_key_arg (QCweakness, nargs, args, used);
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)
signal_error ("Invalid argument list", argsi); SAFE_FREE ();
return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak,
purecopy);
}
code: sample.el
(make-hash-table)
;; => #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) ;; 値の登録
(let ((tbl (make-hash-table)))
(puthash 'n 1 tbl)
tbl)
;; => #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data (n 1)) ;; 値の取り出し
(let ((tbl (make-hash-table)))
(puthash 'n 1 tbl)
(gethash 'n tbl))
;; => 1
(make-hash-table :test 'eq)
;; => #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :size 1)
;; => #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :rehash-size 1)
;; => #s(hash-table size 65 test eql rehash-size 1 rehash-threshold 0.8125 data ()) (make-hash-table :weakness t) ;; key-ond-valueと等価
;; => #s(hash-table size 65 test eql weakness key-and-value rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :weakness 'key)
;; => #s(hash-table size 65 test eql weakness key rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :weakness 'value)
;; => #s(hash-table size 65 test eql weakness value rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :weakness 'key-or-value)
;; => #s(hash-table size 65 test eql weakness key-or-value rehash-size 1.5 rehash-threshold 0.8125 data ()) (make-hash-table :purecopy t)
;; => #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 purecopy t data ())