Next: Miscellaneous Extensions, Previous: Resolution of Name Conflicts, Up: Beyond the ANSI Standard

### 7.7 Hash Table Extensions

Hash table extensions supported by SBCL are all controlled by keyword arguments to `make-hash-table`.

— Function: cl:make-hash-table &key test size rehash-size rehash-threshold hash-function weakness synchronized

> 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 explicit `hash-function` is provided (see below), any two argument equivalence predicate can be used as the `test`.
> `: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 the `test` 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 using `sb-ext:define-hash-table-test`. If `hash-function` is specified, the `test` argument can be any two argument predicate consistent with it. The `hash-function` is expected to return a non-negative fixnum hash code.
> `:weakness`
>   If `nil` (the default) it is a normal non-weak hash table. If one of `:key`, `:value`, `:key-and-value`, `:key-or-value` it is a weak hash table. Depending on the type of weakness the lack of references to the key and the value may allow for removal of the entry. If `weakness` is `:key` and the key would otherwise be garbage the entry is eligible for removal from the hash table. Similarly, if `weakness` is `:value` the life of an entry depends on its value's references. If `weakness` is `:key-and-value` and either the key or the value would otherwise be garbage the entry can be removed. If `weakness` is `:key-or-value` and both the key and the value would otherwise be garbage the entry can be removed.
> `: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. If `t`, all concurrent accesses are safe, but note that `clhs` 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.

— Macro: sb-ext:define-hash-table-test name hash-function

> Defines `name` as a new kind of hash table test for use with the `:test` argument to `make-hash-table`, and associates a default `hash-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 cases `hash-table-test` will return the symbol `name`.

> `hash-function` must be a symbol naming a global hash function consistent with the predicate, or be a `lambda` form implementing one in the current lexical environment. The hash function must compute the same hash code for any two objects for which `name` returns true, and subsequent calls with already hashed objects must always return the same hash code.

> Note: The `:hash-function` keyword argument to `make-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 '==))

— Macro: sb-ext:with-locked-hash-table (hash-table) &body body

> Limits concurrent accesses to `hash-table` for the duration of `body`. If `hash-table` is synchronized, `body` will execute with exclusive ownership of the table. If `hash-table` is not synchronized, `body` will execute with other `with-locked-hash-table` bodies excluded `--` exclusion of hash-table accesses not surrounded by `with-locked-hash-table` is unspecified.

— Function: sb-ext:hash-table-synchronized-p instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:hash-table-weakness instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.