Next: Miscellaneous Extensions, Previous: Resolution of Name Conflicts, Up: Beyond the ANSI Standard
Hash table extensions supported by SBCL are all controlled by keyword
arguments to make-hash-table
.
Create and return a new hash table. The keywords are as follows:
:test
- Determines how keys are compared. Must a designator for one of the standard hash table tests, or a hash table test defined using
sb-ext:define-hash-table-test
. Additionally, when an explicithash-function
is provided (see below), any two argument equivalence predicate can be used as thetest
.:size
- A hint as to how many elements will be put in this hash table.
:rehash-size
- Indicates how to expand the table when it fills up. If an integer, add space for that many elements. If a floating point number (which must be greater than 1.0), multiply the size by that amount.
:rehash-threshold
- Indicates how dense the table can become before forcing a rehash. Can be any positive number <=1, with density approaching zero as the threshold approaches 0. Density 1 means an average of one entry per bucket.
:hash-function
- If
nil
(the default), a hash function based on thetest
argument is used, which then must be one of the standardized hash table test functions, or one for which a default hash function has been defined usingsb-ext:define-hash-table-test
. Ifhash-function
is specified, thetest
argument can be any two argument predicate consistent with it. Thehash-function
is expected to return a non-negative fixnum hash code.:weakness
- When
:weakness
is notnil
, garbage collection may remove entries from the hash table. The value of:weakness
specifies how the presence of a key or value in the hash table preserves their entries from garbage collection.Valid values are:
:key
means that the key of an entry must be live to guarantee that the entry is preserved.
:value
means that the value of an entry must be live to guarantee that the entry is preserved.
:key-and-value
means that both the key and the value must be live to guarantee that the entry is preserved.
:key-or-value
means that either the key or the value must be live to guarantee that the entry is preserved.
nil
(the default) means that entries are always preserved.:synchronized
- If
nil
(the default), the hash-table may have multiple concurrent readers, but results are undefined if a thread writes to the hash-table concurrently with another reader or writer. Ift
, all concurrent accesses are safe, but note thatclhs
3.6 (Traversal Rules and Side Effects) remains in force. See also:sb-ext:with-locked-hash-table
. This keyword argument is experimental, and may change incompatibly or be removed in the future.
Defines
name
as a new kind of hash table test for use with the:test
argument tomake-hash-table
, and associates a defaulthash-function
with it.
name
must be a symbol naming a global two argument equivalence predicate. Afterwards both'name
and#'name
can be used with:test
argument. In both caseshash-table-test
will return the symbolname
.
hash-function
must be a symbol naming a global hash function consistent with the predicate, or be alambda
form implementing one in the current lexical environment. The hash function must compute the same hash code for any two objects for whichname
returns true, and subsequent calls with already hashed objects must always return the same hash code.Note: The
:hash-function
keyword argument tomake-hash-table
can be used to override the specified default hash-function.Attempting to define
name
in a locked package as hash-table test causes a package lock violation.Examples:
;;; 1. ;; We want to use objects of type FOO as keys (by their ;; names.) EQUALP would work, but would make the names ;; case-insensitive -- wich we don't want. (defstruct foo (name nil :type (or null string))) ;; Define an equivalence test function and a hash function. (defun foo-name= (f1 f2) (equal (foo-name f1) (foo-name f2))) (defun sxhash-foo-name (f) (sxhash (foo-name f))) (define-hash-table-test foo-name= sxhash-foo-name) ;; #'foo-name would work too. (defun make-foo-table () (make-hash-table :test 'foo-name=)) ;;; 2. (defun == (x y) (= x y)) (define-hash-table-test == (lambda (x) ;; Hash codes must be consistent with test, so ;; not (SXHASH X), since ;; (= 1 1.0) => T ;; (= (SXHASH 1) (SXHASH 1.0)) => NIL ;; Note: this doesn't deal with complex numbers or ;; bignums too large to represent as double floats. (sxhash (coerce x 'double-float)))) ;; #'== would work too (defun make-number-table () (make-hash-table :test '==))
Limits concurrent accesses to
hash-table
for the duration ofbody
. Ifhash-table
is synchronized,body
will execute with exclusive ownership of the table. Ifhash-table
is not synchronized,body
will execute with otherwith-locked-hash-table
bodies excluded--
exclusion of hash-table accesses not surrounded bywith-locked-hash-table
is unspecified.