6.6 Weak pointers

6.6.1 Reference pages

make-hash-table Function

Syntax:make-hash-table &key :test :weak :size :rehash-size :rehash-threshold

Creates a (possibly weak) hash-table.

This function behaves just like themake-hash-table described in chapter 11 of CLtL2, except that there is an additional keyword argument,:weak.

When the:test argument iseq, then the:weakargument is valid. It can benil,:key,:value,:both, or :one. In the nil case, a normal hash-table is returned.

:key
If the key is live (that is, if there is a reference to it), the entry survives; otherwise, the entry is deleted. The value acts like a normal reference, i.e., if the hash-table value is the only reference, the object still survives.

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
If the value is live, the entry survives; otherwise, the entry is deleted. The key acts like a normal reference.

This produces a hash-table that implements a name-to-object mapping such that if the object goes away, the name becomes undefined.

:both
If both the key and the value are live, the entry survives; otherwise, the entry is deleted. Neither the key nor the value count as references, since both are weak.

:one
If at least one of the key and the value are live, the entry survives and the other component acts as a normal reference.

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 >

See Also: make-weak-set

make-weak-set Function

Syntax:make-weak-set

Returns a new empty weak set.

Weak sets are simply lists of objects such that membership in the weak set is not a reference to those objects. Dead objects are removed from the set.

The notion of finalization permits a program to act on objects that are found to be dead. Instead of being discarded, they are placed in a finalization queue (where they become not- dead again). To end up in a finalization queue, objects must be registered. The registration does not constitute a reference to the object.

;;; 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

See Also: make-weak-set, weak-set-p,member-of-weak-set, adjoin-to-weak-set, delete-from-weak-set, list-weak-set

weak-set-p Function

Syntax:weak-set-p object

Tests whether an object is a weak set.

Returnst if object is a weak set, such as one created bymake-weak-set.

> (weak-set-p (make-weak-set))
T
> 
See Also: make-weak-set

member-of-weak-set Function

Syntax:member-of-weak-set object weak-set

Tests whether an object belongs to a weak set.

Returnst 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.

This function behaves as though themember function were given a:testargument ofeq.

> (setq my-weak-set (make-weak-set ))
#<Structure WEAK-SET 9A04DE>

> (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

adjoin-to-weak-set Function

Syntax:adjoin-to-weak-set object weak-set

Adds an object to a weak set, if it is not already present.

Returnsnil 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) >

See Also: make-weak-set, member-of-weak-set

delete-from-weak-set Function

Syntax:delete-from-weak-set object weak-set

Removes an item from a weak set.

Returnst 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 >

See Also: make-weak-set, member-of-weak-set

list-weak-set Function

Syntax:list-weak-set weak-set&optional retain-entries

Returns the elements of a weak set, while emptying the set.

Returns a (normal) list of all objects in the set, while deleting all the entries. If the optional second argument is non-null, the entries are not deleted. The order of entries in this list is not specified.

> (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 >

See Also: make-weak-set, member-of-weak-set


The Advanced User's Guide - 9 SEP 1996

Generated with Harlequin WebMaker