Previous: Weak Pairs, Up: Weak References
An
ephemeron is an object with two weakly referenced components called
its key and datum. The garbage collector drops an
ephemeron's references to both key and datum, rendering the ephemeron
broken, if and only if the garbage collector can prove that
there are no strong references to the key. In other words, an
ephemeron is broken when nobody else cares about its key. In
particular, the datum holding a reference to the key will not in
itself prevent the ephemeron from becoming broken; in contrast,
See Weak Pairs. Once broken, ephemerons never cease to be broken;
setting the key or datum of a broken ephemeron with
set-ephemeron-key!
or set-ephemeron-datum!
has no
effect. Note that an ephemeron's reference to its datum may be
dropped even if the datum is still reachable; all that matters is
whether the key is reachable.
Ephemerons are considerably heavier-weight than weak pairs, because garbage-collecting ephemerons is more complicated than garbage-collecting weak pairs. Each ephemeron needs five words of storage, rather than the two words needed by a weak pair. However, while the garbage collector spends more time on ephemerons than on other objects, the amount of time it spends on ephemerons scales linearly with the number of live ephemerons, which is how its running time scales with the total number of live objects anyway.
Allocates and returns a new ephemeron, with components key and datum.
Returns
#t
if the garbage collector has dropped ephemeron's references to its key and datum; otherwise returns#f
.
These return the key or datum component, respectively, of ephemeron. If ephemeron has been broken, these operations return
#f
, but they can also return#f
if that is the value that was stored in the key or value component.
These set the key or datum component, respectively, of ephemeron to object and return an unspecified result. If ephemeron is broken, neither of these operations has any effect.
Like weak-pair/car?
, ephemeron-broken?
must be used with
care. If (ephemeron-broken?
ephemeron)
yields false, it
guarantees only that prior evaluations of (ephemeron-key
ephemeron)
or (ephemeron-datum
ephemeron)
yielded the key
or datum that was stored in the ephemeron, but it makes no guarantees
about subsequent calls to ephemeron-key
or
ephemeron-datum
: the garbage collector may run and break the
ephemeron immediately after ephemeron-broken?
returns. Thus,
the correct idiom to fetch an ephemeron's key and datum and use them
if the ephemeron is not broken is
(let ((key (ephemeron-key ephemeron)) (datum (ephemeron-datum ephemeron))) (if (ephemeron-broken? ephemeron) ... broken case ... ... code using key and datum ...))