All Manuals > LispWorks User Guide and Reference Manual > 38 The HCL Package

NextPrevUpTopContentsIndex

with-ensuring-gethash

Macro
Summary

A thread-safe way to get a value from a hash-table, adding a value if the key is not present. Allows a complicated form to construct the new value.

Package

hcl

Signature

with-ensuring-gethash key hash-table &key constructor constructor-form in-lock-constructor in-lock-constructor-form => result

Arguments

key

A Lisp object.

hash-table

A hash-table.

constructor

A function designator for a function of no arguments, or nil.

constructor-form

A Lisp form, or nil.

in-lock-constructor

A function designator for a function of one argument, or nil.

in-lock-constructor-form

A Lisp form, or nil.

Values

result

A Lisp object.

Description

The macro with-ensuring-gethash gets the value for the key key from the hash table hash-table, and if this fails constructs a new value, puts it in the table and returns it. with-ensuring-gethash does this in a thread-safe way, which means that all threads calling it with the same key and hash-table return the same value (as long as nothing removes it from the table).

Only one of constructor-form or constructor can be non-nil. When key is not found, constructor-form or constructor is used to construct the new value. If constructor is non-nil, it is called without arguments. If constructor-form is non-nil, it is executed. If both are nil, the new value is nil unless the in-lock-constructor or in-lock-constructor-form construct it. The call or execution of the constructor or constructor-form is done without any lock. The result may be discarded if, by the time it returned, there is a match for the key in the table.

Only one of in-lock-constructor or in-lock-constructor-form can be non-nil, which is used when the key is not found after constructing the new value. If in-lock-constructor-form is non-nil, it is executed and the result is the actual value to use (the result of the construction by constructor-form or constructor is ignored). If in-lock-constructor is non-nil, it is called with the result of the construction by constructor-form or constructor, and the result is used as the new value. In either case, the call or execution is done with hash-table locked, and the result is guaranteed to be put in hash-table and returned. If both in-lock-constructor and in-lock-constructor-form are nil, the result of the construction is used.

Notes
  1. When both constructor-form and in-lock-constructor-form are nil, gethash-ensuring is probably simpler and better.
  2. In most situations, doing all the construction out of the lock is better than doing anything inside the lock. It means that sometimes the work that was done in the constructions is wasted because another thread put the value in the table, but that overhead is normally less significant than the overhead of holding the lock for longer, with the associated potential deadlocks.
See also

ensure-hash-entry
gethash-ensuring
Modifying a hash table with multiprocessing


LispWorks User Guide and Reference Manual - 13 Feb 2015

NextPrevUpTopContentsIndex