MOP questions (was Re: [Openmcl-devel] byte-strings)

Gary Byers gb at clozure.com
Tue Sep 7 02:53:31 PDT 2004



On Mon, 6 Sep 2004, Ben wrote:

> thanks for the answer -- another question:
>
> are there any docs on the weak hash-table support?  why is it only
> available for eq hash-tables?  i'm trying to make an object cache
> which is indexed by OIDs (integers), and let the gc decide what to gc.

A hash table can be "weak on key" or "weak on value"

A weak hash table is one where a {key, value} pair can be removed
from the hash table if the GC can prove that there is no other reference
to the member of the pair used to determine "weakness".

Immediate objects (fixnums, characters, ...) are always "referenced"
in this sense.  Objects that're allocated in memory may or may not have
strong references to them; referencing some other object that happens
to be EQL/EQUAL/EQUALP to the weak member of the weak hash table
doesn't cause that member to be referenced.

For example:

? (defvar *weak-hash-table* (make-hash-table :test #'eq :weak t)) ; weak on key
*WEAK-HASH-TABLE*
? (setf (gethash (cons nil nil) *weak-hash-table*) 10)
10
? (hash-table-count *weak-hash-table*) ; one way of telling that something's there
1
? ()	; ensure that there are no other references to the key in - or other
        ; REPL variables.   (Probably already gone, but ...)
NIL
? (gc)
NIL
? (hash-table-count *weak-hash-table*)  ; anything there anymore ?
0					; Nope.
;;; For the "weak on value" case:
? (defvar *weak-on-value-hash* (make-hash-table :test #'equalp :weak :value))
*WEAK-ON-VALUE-HASH*
? (setf (gethash 10 *weak-on-value-hash*) (cons nil nil))
(NIL)
? (gethash 10.0 *weak-on-value-hash*)
(NIL)
? ()				; get that cons cell out of */**/***
NIL
? ()
NIL
? ()
NIL
? (gc)
NIL
? (gethash 10 *weak-on-value-hash*)
NIL

In both examples, the weak member of the {key,value} pair was a cons
cell and we took some care to ensure that the cons cell was not
strongly referenced.  If we'd flipped the key/value arguments around,
we'd find that the fixnum was never "otherwise garbage"

MAKE-HASH-TABLE accepts a :FINALIZABLE keyword argument, but I believe
that it completely ignores it: keys/values aren't automatically
scheduled for termination.  (It's possible to call
CCL:TERMINATE-WHEN-UNREACHABLE on the object in question; if the
:FINALIZABLE keyword mechanism worked - I broke it a long, long time
ago - the GC would do this automatically.)




More information about the Openmcl-devel mailing list