Next: , 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.