6.6 Weak pointers
make-hash-table &key :test :weak :size :rehash-size :rehash-threshold
make-hash-table
described in chapter 11 of CLtL2, except that there is an additional keyword argument,:weak
.
:test
argument iseq
, then the:weak
argument is valid. It can benil
,:key
,:value
,:both,
or :one
. In the nil
case, a normal hash-table is returned.
:key
This is probably the most common kind of weak hash-table. This kind of hash-table can be used to maintain a property list for arbitrary objects. When the objects go away, the properties do so automatically.
:value
This produces a hash-table that implements a name-to-object mapping such that if the object goes away, the name becomes undefined.
:both
:one
The hash-table represents a bi-directional relation among a set of objects. The link in one direction is implemented byget-hash
, and in the other direction (less frequently used) bymap-hash
. As long as any object is alive, all the relations that involve that object are retained.
;;; We make a weak hash-table, where references to the value part ;;; of a hash entry do not constitute a reference. > (setq my-hasht (make-hash-table :test #'eq :weak :value)) #<Hash-Table 9A03AE> > (hash-table-count my-hasht) 0;;; We create a Lisp object, (a list), ;;; and store a weak reference to the object in our hash-table. > (setq fleeting-list '(a b c)) (A B C) > (setf (gethash 'item1 my-hasht) fleeting-list) (A B C)
;;; We now have one entry in the hash-table. > (hash-table-count my-hasht) 1
;;; Now, we eliminate the reference to the object. Since the ;;; value in the table is weak, we no longer have a reference ;;; to the object.
> (setq fleeting-list nil) NIL > (hash-table-count my-hasht) 1
;;; After a gc, we can see that the hash-table has automatically ;;; cleaned itself. > (gc) ;;; GC: 4180 words [16720 bytes] of dynamic storage in use. ;;; 454570 words [1818280 bytes] of free storage available before ;;; a GC. 913320 words [3653280 bytes] of free storage available ;;; if GC is disabled. 16824 1817152 3651128 > (hash-table-count my-hasht) 0 >
make-weak-set
make-weak-set
;;; We make a weak set and then adjoin a Lisp object to the set. > (setq my-weak-set (make-weak-set )) #<Structure WEAK-SET 9A081E>> (setq my-fleeting-list '(a b c)) (A B C) > (adjoin-to-weak-set my-fleeting-list my-weak-set) ;; This adds an object to a weak set if it is not already present. T
;;; We now remove the only reference to the Lisp object. > (setq my-fleeting-list nil) NIL
;;; After garbage collection, we see that the entry for our ;;; object in the weak set has been removed. This is because ;;; there are no non-weak references left that point to the ;;; object. Note that we call GC twice. This is because their are ;;; lingering references to MY-FLEETING-LIST, namely the * and ** ;;; Common Lisp variable. The point is to enter enough expressions ;;; to the top-level so that these variables no longer point to ;;; MY-FLEETING-LIST.
> (gc) ;;; GC: 1172 words [4688 bytes] of dynamic storage in use. ;;; 457578 words [1830312 bytes] of free storage available before ;;; a GC. 916328 words [3665312 bytes] of free storage available ;;; if GC is disabled. 4792 1829184 3663160
> (gc) ;;; GC: 1162 words [4648 bytes] of dynamic storage in use. ;;; 457588 words [1830352 bytes] of free storage available before ;;; a GC. 916338 words [3665352 bytes] of free storage available ;;; if GC is disabled. 4752 1829224 3663200
> (list-weak-set my-weak-set) NIL
make-weak-set
, weak-set-p
,member-of-weak-set
, adjoin-to-weak-set
, delete-from-weak-set
, list-weak-set
Syntax:weak-set-p
object
t
if object is a weak set, such as one created bymake-weak-set
.
> (weak-set-p (make-weak-set)) T > See Also:member-of-weak-set Functionmake-weak-set
Syntax:member-of-weak-set
object weak-set
t
if and only if the object is present in the set. The argument object is a Lisp object, and the argument weak-set is a weak set.
member
function were given a:test
argument ofeq
.
> (setq my-weak-set (make-weak-set )) #<Structure WEAK-SET 9A04DE>adjoin-to-weak-set Function> (setq my-fleeting-list '(a b c)) (A B C)
> (adjoin-to-weak-set my-fleeting-list my-weak-set) ;; This adds an object to a weak set if it is not already present. T
> (member-of-weak-set my-fleeting-list my-weak-set) T
;;; The following returns NIL, because this is a new list ;;; '(a b c), not eq
to the list '(a b c) that is the value ;;; of the variable my-fleeting-list. > (member-of-weak-set '(a b c) my-weak-set) NIL
Syntax:adjoin-to-weak-set
object weak-set
nil
if the object is already present in the set; returnst
when the set has to be extended by one element to hold object.
> (setq my-weak-set (make-weak-set)) #<Structure WEAK-SET 967EB6>> (adjoin-to-weak-set 'a my-weak-set) T
> (adjoin-to-weak-set 'a my-weak-set) NIL
> (list-weak-set my-weak-set) ;; This returns the elements of a ;; weak set while emptying the set. (A) >
make-weak-set
, member-of-weak-set
Syntax:delete-from-weak-set
object weak-set
t
if the object was already present in the set and was thus deleted; otherwise returnsnil
.
> (setq my-weak-set (make-weak-set)) #<Structure WEAK-SET 970686>> (adjoin-to-weak-set 'a my-weak-set) T
> (list-weak-set my-weak-set t) ;; This returns the elements of ;; a weak set but does not empty the set. (A)
> (delete-from-weak-set 'a my-weak-set) T
> (list-weak-set my-weak-set t) NIL >
make-weak-set
, member-of-weak-set
Syntax:list-weak-set
weak-set&optional
retain-entries
> (setq my-weak-set (make-weak-set)) #<Structure WEAK-SET 970686>> (adjoin-to-weak-set 'a my-weak-set) T
> (list-weak-set my-weak-set t) (A)
> (delete-from-weak-set 'a my-weak-set) T
> (list-weak-set my-weak-set t) NIL >
make-weak-set
, member-of-weak-set
Generated with Harlequin WebMaker