1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-12 23:00:22 +02:00

(Hash Table Reference): Collect up groups of

functions to avoid duplication.  Revise notes on hashx functions and
on vector implementation.  In make-hash-table, size is now optional.
Add hash-map and hash-for-each.
This commit is contained in:
Kevin Ryde 2003-08-17 00:28:51 +00:00
parent 78c2d49cde
commit ac5fa6d1be

View file

@ -2245,238 +2245,177 @@ a hash table, but @code{hash-fold} can be used for doing exactly that.
@node Hash Table Reference @node Hash Table Reference
@subsubsection Hash Table Reference @subsubsection Hash Table Reference
Like the association list functions, the hash table functions come @c FIXME: Describe in broad terms what happens for resizing, and what
in several varieties: @code{hashq}, @code{hashv}, and @code{hash}. @c the initial size means for this.
The @code{hashq} functions use @code{eq?} to determine whether two
keys match. The @code{hashv} functions use @code{eqv?}, and the
@code{hash} functions use @code{equal?}.
In each of the functions that follow, the @var{table} argument Like the association list functions, the hash table functions come in
must be a vector. The @var{key} and @var{value} arguments may be several varieties, according to the equality test used for the keys.
any Scheme object. Plain @code{hash-} functions use @code{equal?}, @code{hashq-}
functions use @code{eq?}, @code{hashv-} functions use @code{eqv?}, and
the @code{hashx-} functions use an application supplied test (for
instance to implement case insensitive strings).
@deffn {Scheme Procedure} make-hash-table size A single @code{make-hash-table} creates a hash table suitable for use
Create a new hash table of @var{size} slots. Note that the number of with any set of functions, but it's imperative that just one set is
slots does not limit the size of the table, it just tells how large then used consistently, or results will be unpredictable.
the underlying vector will be. The @var{size} should be similar to
the expected number of elements which will be added to the table, but
they need not match. For good performance, it might be a good idea to
use a prime number as the @var{size}.
@end deffn
@deffn {Scheme Procedure} hashq-ref table key [dflt] @sp 1
@deffnx {C Function} scm_hashq_ref (table, key, dflt) Hash tables are implemented as a vector indexed by an integer formed
Look up @var{key} in the hash table @var{table}, and return the from the key, with an association list of key/value pairs for each
value (if any) associated with it. If @var{key} is not found, bucket in case distinct keys hash together. Direct access to the
return @var{default} (or @code{#f} if no @var{default} argument pairs in those lists is provided by the @code{-handle-} functions.
is supplied). Uses @code{eq?} for equality testing.
@end deffn
@deffn {Scheme Procedure} hashv-ref table key [dflt] For the @code{hashx-} ``extended'' routines, an application supplies a
@deffnx {C Function} scm_hashv_ref (table, key, dflt) @var{hash} function producing an integer index (like @code{hashq} etc
Look up @var{key} in the hash table @var{table}, and return the below), and an @var{assoc} alist search function (like @code{assq}
value (if any) associated with it. If @var{key} is not found, etc, @xref{Retrieving Alist Entries}.). The aim in the @var{hash}
return @var{default} (or @code{#f} if no @var{default} argument function is to have different keys spread out across the vector, so
is supplied). Uses @code{eqv?} for equality testing. the bucket lists don't become long, but the exact values generated are
otherwise arbitrary.
@sp 1
@deffn {Scheme Procedure} make-hash-table [size]
Create a new hash table, with an optional initial vector @var{size}.
@var{size} doesn't limit the entries in the table, merely gives a
starting size for the internal vector. A prime number bigger than the
expected number of entries would be a good choice.
@end deffn @end deffn
@deffn {Scheme Procedure} hash-ref table key [dflt] @deffn {Scheme Procedure} hash-ref table key [dflt]
@deffnx {Scheme Procedure} hashq-ref table key [dflt]
@deffnx {Scheme Procedure} hashv-ref table key [dflt]
@deffnx {Scheme Procedure} hashx-ref hash assoc table key [dflt]
@deffnx {C Function} scm_hash_ref (table, key, dflt) @deffnx {C Function} scm_hash_ref (table, key, dflt)
Look up @var{key} in the hash table @var{table}, and return the @deffnx {C Function} scm_hashq_ref (table, key, dflt)
value (if any) associated with it. If @var{key} is not found, @deffnx {C Function} scm_hashv_ref (table, key, dflt)
return @var{default} (or @code{#f} if no @var{default} argument @deffnx {C Function} scm_hashx_ref (hash, assoc, table, key, dflt)
is supplied). Uses @code{equal?} for equality testing. Lookup @var{key} in the given hash @var{table}, and return the
@end deffn associated value. If @var{key} is not found, return @var{dflt}, or
@code{#f} if @var{dflt} is not given. (For the C functions,
@deffn {Scheme Procedure} hashq-set! table key val @var{dflt} must be given.)
@deffnx {C Function} scm_hashq_set_x (table, key, val)
Find the entry in @var{table} associated with @var{key}, and
store @var{value} there. Uses @code{eq?} for equality testing.
@end deffn
@deffn {Scheme Procedure} hashv-set! table key val
@deffnx {C Function} scm_hashv_set_x (table, key, val)
Find the entry in @var{table} associated with @var{key}, and
store @var{value} there. Uses @code{eqv?} for equality testing.
@end deffn @end deffn
@deffn {Scheme Procedure} hash-set! table key val @deffn {Scheme Procedure} hash-set! table key val
@deffnx {Scheme Procedure} hashq-set! table key val
@deffnx {Scheme Procedure} hashv-set! table key val
@deffnx {Scheme Procedure} hashx-set! hash assoc table key val
@deffnx {C Function} scm_hash_set_x (table, key, val) @deffnx {C Function} scm_hash_set_x (table, key, val)
Find the entry in @var{table} associated with @var{key}, and @deffnx {C Function} scm_hashq_set_x (table, key, val)
store @var{value} there. Uses @code{equal?} for equality @deffnx {C Function} scm_hashv_set_x (table, key, val)
testing. @deffnx {C Function} scm_hashx_set_x (hash, assoc, table, key, val)
@end deffn Associate @var{val} with @var{key} in the given hash @var{table}. If
@var{key} is already present then it's associated value is changed.
@deffn {Scheme Procedure} hashq-remove! table key If it's not present then a new entry is created.
@deffnx {C Function} scm_hashq_remove_x (table, key)
Remove @var{key} (and any value associated with it) from
@var{table}. Uses @code{eq?} for equality tests.
@end deffn
@deffn {Scheme Procedure} hashv-remove! table key
@deffnx {C Function} scm_hashv_remove_x (table, key)
Remove @var{key} (and any value associated with it) from
@var{table}. Uses @code{eqv?} for equality tests.
@end deffn @end deffn
@deffn {Scheme Procedure} hash-remove! table key @deffn {Scheme Procedure} hash-remove! table key
@deffnx {Scheme Procedure} hashq-remove! table key
@deffnx {Scheme Procedure} hashv-remove! table key
@deffnx {C Function} scm_hash_remove_x (table, key) @deffnx {C Function} scm_hash_remove_x (table, key)
Remove @var{key} (and any value associated with it) from @deffnx {C Function} scm_hashq_remove_x (table, key)
@var{table}. Uses @code{equal?} for equality tests. @deffnx {C Function} scm_hashv_remove_x (table, key)
@end deffn Remove any association for @var{key} in the given hash @var{table}.
If @var{key} is not in @var{table} then nothing is done.
The standard hash table functions may be too limited for some
applications. For example, you may want a hash table to store
strings in a case-insensitive manner, so that references to keys
named ``foobar'', ``FOOBAR'' and ``FooBaR'' will all yield the
same item. Guile provides you with @dfn{extended} hash tables
that permit you to specify a hash function and associator function
of your choosing. The functions described in the rest of this section
can be used to implement such custom hash table structures.
If you are unfamiliar with the inner workings of hash tables, then
this facility will probably be a little too abstract for you to
use comfortably. If you are interested in learning more, see an
introductory textbook on data structures or algorithms for an
explanation of how hash tables are implemented.
@deffn {Scheme Procedure} hashq key size
@deffnx {C Function} scm_hashq (key, size)
Determine a hash value for @var{key} that is suitable for
lookups in a hash table of size @var{size}, where @code{eq?} is
used as the equality predicate. The function returns an
integer in the range 0 to @var{size} - 1. Note that
@code{hashq} may use internal addresses. Thus two calls to
hashq where the keys are @code{eq?} are not guaranteed to
deliver the same value if the key object gets garbage collected
in between. This can happen, for example with symbols:
@code{(hashq 'foo n) (gc) (hashq 'foo n)} may produce two
different values, since @code{foo} will be garbage collected.
@end deffn
@deffn {Scheme Procedure} hashv key size
@deffnx {C Function} scm_hashv (key, size)
Determine a hash value for @var{key} that is suitable for
lookups in a hash table of size @var{size}, where @code{eqv?} is
used as the equality predicate. The function returns an
integer in the range 0 to @var{size} - 1. Note that
@code{(hashv key)} may use internal addresses. Thus two calls
to hashv where the keys are @code{eqv?} are not guaranteed to
deliver the same value if the key object gets garbage collected
in between. This can happen, for example with symbols:
@code{(hashv 'foo n) (gc) (hashv 'foo n)} may produce two
different values, since @code{foo} will be garbage collected.
@end deffn @end deffn
@deffn {Scheme Procedure} hash key size @deffn {Scheme Procedure} hash key size
@deffnx {Scheme Procedure} hashq key size
@deffnx {Scheme Procedure} hashv key size
@deffnx {C Function} scm_hash (key, size) @deffnx {C Function} scm_hash (key, size)
Determine a hash value for @var{key} that is suitable for @deffnx {C Function} scm_hashq (key, size)
lookups in a hash table of size @var{size}, where @code{equal?} @deffnx {C Function} scm_hashv (key, size)
is used as the equality predicate. The function returns an Return a hash value for @var{key}. This is a number in the range
integer in the range 0 to @var{size} - 1. @math{0} to @math{@var{size}-1}, which is suitable for use in a hash
@end deffn table of the given @var{size}.
@deffn {Scheme Procedure} hashx-ref hash assoc table key [dflt] Note that @code{hashq} and @code{hashv} may use internal addresses of
@deffnx {C Function} scm_hashx_ref (hash, assoc, table, key, dflt) objects, so if an object is garbage collected and re-created it can
This behaves the same way as the corresponding @code{ref} have a different hash value, even when the two are notionally
function, but uses @var{hash} as a hash function and @code{eq?}. For instance with symbols,
@var{assoc} to compare keys. @code{hash} must be a function
that takes two arguments, a key to be hashed and a table size.
@code{assoc} must be an associator function, like @code{assoc},
@code{assq} or @code{assv}.
By way of illustration, @code{hashq-ref table key} is @example
equivalent to @code{hashx-ref hashq assq table key}. (hashq 'something 123) @result{} 19
@end deffn (gc)
(hashq 'something 123) @result{} 62
@end example
@deffn {Scheme Procedure} hashx-set! hash assoc table key val In normal use this is not a problem, since an object entered into a
@deffnx {C Function} scm_hashx_set_x (hash, assoc, table, key, val) hash table won't be garbage collected until removed. It's only if
This behaves the same way as the corresponding @code{set!} hashing calculations are somehow separated from normal references that
function, but uses @var{hash} as a hash function and its lifetime needs to be considered.
@var{assoc} to compare keys. @code{hash} must be a function
that takes two arguments, a key to be hashed and a table size.
@code{assoc} must be an associator function, like @code{assoc},
@code{assq} or @code{assv}.
By way of illustration, @code{hashq-set! table key} is
equivalent to @code{hashx-set! hashq assq table key}.
@end deffn
@deffn {Scheme Procedure} hashq-get-handle table key
@deffnx {C Function} scm_hashq_get_handle (table, key)
This procedure returns the @code{(key . value)} pair from the
hash table @var{table}. If @var{table} does not hold an
associated value for @var{key}, @code{#f} is returned.
Uses @code{eq?} for equality testing.
@end deffn
@deffn {Scheme Procedure} hashv-get-handle table key
@deffnx {C Function} scm_hashv_get_handle (table, key)
This procedure returns the @code{(key . value)} pair from the
hash table @var{table}. If @var{table} does not hold an
associated value for @var{key}, @code{#f} is returned.
Uses @code{eqv?} for equality testing.
@end deffn @end deffn
@deffn {Scheme Procedure} hash-get-handle table key @deffn {Scheme Procedure} hash-get-handle table key
@deffnx {Scheme Procedure} hashq-get-handle table key
@deffnx {Scheme Procedure} hashv-get-handle table key
@deffnx {Scheme Procedure} hashx-get-handle hash assoc table key
@deffnx {C Function} scm_hash_get_handle (table, key) @deffnx {C Function} scm_hash_get_handle (table, key)
This procedure returns the @code{(key . value)} pair from the @deffnx {C Function} scm_hashq_get_handle (table, key)
hash table @var{table}. If @var{table} does not hold an @deffnx {C Function} scm_hashv_get_handle (table, key)
associated value for @var{key}, @code{#f} is returned.
Uses @code{equal?} for equality testing.
@end deffn
@deffn {Scheme Procedure} hashx-get-handle hash assoc table key
@deffnx {C Function} scm_hashx_get_handle (hash, assoc, table, key) @deffnx {C Function} scm_hashx_get_handle (hash, assoc, table, key)
This behaves the same way as the corresponding Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
@code{-get-handle} function, but uses @var{hash} as a hash given hash @var{table}, or @code{#f} if @var{key} is not in
function and @var{assoc} to compare keys. @code{hash} must be @var{table}.
a function that takes two arguments, a key to be hashed and a
table size. @code{assoc} must be an associator function, like
@code{assoc}, @code{assq} or @code{assv}.
@end deffn
@deffn {Scheme Procedure} hashq-create-handle! table key init
@deffnx {C Function} scm_hashq_create_handle_x (table, key, init)
This function looks up @var{key} in @var{table} and returns its handle.
If @var{key} is not already present, a new handle is created which
associates @var{key} with @var{init}.
@end deffn
@deffn {Scheme Procedure} hashv-create-handle! table key init
@deffnx {C Function} scm_hashv_create_handle_x (table, key, init)
This function looks up @var{key} in @var{table} and returns its handle.
If @var{key} is not already present, a new handle is created which
associates @var{key} with @var{init}.
@end deffn @end deffn
@deffn {Scheme Procedure} hash-create-handle! table key init @deffn {Scheme Procedure} hash-create-handle! table key init
@deffnx {Scheme Procedure} hashq-create-handle! table key init
@deffnx {Scheme Procedure} hashv-create-handle! table key init
@deffnx {Scheme Procedure} hashx-create-handle! hash assoc table key init
@deffnx {C Function} scm_hash_create_handle_x (table, key, init) @deffnx {C Function} scm_hash_create_handle_x (table, key, init)
This function looks up @var{key} in @var{table} and returns its handle. @deffnx {C Function} scm_hashq_create_handle_x (table, key, init)
If @var{key} is not already present, a new handle is created which @deffnx {C Function} scm_hashv_create_handle_x (table, key, init)
associates @var{key} with @var{init}. @deffnx {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, init)
Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
given hash @var{table}. If @var{key} is not in @var{table} then
create an entry for it with @var{init} as the value, and return that
pair.
@end deffn @end deffn
@deffn {Scheme Procedure} hashx-create-handle! hash assoc table key init @deffn {Scheme Procedure} hash-map proc table
@deffnx {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, init) @deffnx {Scheme Procedure} hash-for-each proc table
This behaves the same way as the corresponding @deffnx {C Function} scm_hash_map (proc, table)
@code{-create-handle} function, but uses @var{hash} as a hash @deffnx {C Function} scm_hash_for_each (proc, table)
function and @var{assoc} to compare keys. @code{hash} must be Apply @var{proc} to the entries in the given hash @var{table}. Each
a function that takes two arguments, a key to be hashed and a call is @code{(@var{proc} @var{key} @var{value})}. @code{hash-map}
table size. @code{assoc} must be an associator function, like returns a list of the results from these calls, @code{hash-for-each}
@code{assoc}, @code{assq} or @code{assv}. discards the results and returns unspecified value.
Calls are made over the table entries in an unspecified order, and for
@code{hash-map} the order of the values in the returned list is
unspecified. Results will be unpredictable if @var{table} is modified
while iterating.
For example the following returns a new alist comprising all the
entries from @code{mytable}, in no particular order.
@example
(hash-map cons mytable)
@end example
@end deffn @end deffn
@deffn {Scheme Procedure} hash-fold proc init table @deffn {Scheme Procedure} hash-fold proc init table
@deffnx {C Function} scm_hash_fold (proc, init, table) @deffnx {C Function} scm_hash_fold (proc, init, table)
An iterator over hash-table elements. Accumulate a result by applying @var{proc} to the elements of the
Accumulates and returns a result by applying PROC successively. given hash @var{table}. Each call is @code{(@var{proc} @var{key}
The arguments to PROC are "(key value prior-result)" where key @var{value} @var{prior-result})}, where @var{key} and @var{value} are
and value are successive pairs from the hash table TABLE, and from the @var{table} and @var{prior-result} is the return from the
prior-result is either INIT (for the first application of PROC) previous @var{proc} call. For the first call, @var{prior-result} is
or the return value of the previous application of PROC. the given @var{init} value.
For example, @code{(hash-fold acons '() tab)} will convert a hash
table into an a-list of key-value pairs. Calls are made over the table entries in an unspecified order.
Results will be unpredictable if @var{table} is modified while
@code{hash-fold} is running.
For example, the following returns a count of how many keys in
@code{mytable} are strings.
@example
(hash-fold (lambda (key value prior)
(if (string? key) (1+ prior) prior))
0 mytable)
@end example
@end deffn @end deffn