"
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
IdentityDictionary subclass:#WeakIdentityDictionary
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'Collections-Unordered'
!
!WeakIdentityDictionary class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
WeakIdentityDictionaries behave like IdentityDictionaries,
as long as the contained objects are still referenced by some
other (non-weak) object.
However, once the last non-weak reference ceases to exist,
the object will be automatically removed from the Weakcollection
(with some delay: it will be removed after the next garbage collect).
This class was added to support keeping track of dependents without
keeping the values alive - values simply become nil when no one else
references it. The original dependency mechanism used a regular Dictionary,
which usually leads to a lot of garbage being kept due to a forgotten
release. Using a WeakDictionary may be incompatible to ST-80 but is much
more comfortable, since no manual release of dependents is needed.
[author:]
Claus Gittinger
[See also:]
WeakArray WeakIdentitySet
"
! !
!WeakIdentityDictionary methodsFor:'adding & removing'!
at:key put:anObject
"add the argument anObject under key, aKey to the receiver.
Return anObject (sigh).
Redefined to block interrupts, to avoid triuble when dependencies
are added within interrupting high prio processes."
|wasBlocked|
wasBlocked := OperatingSystem blockInterrupts.
super at:key put:anObject.
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
^ anObject
"Modified: 22.4.1996 / 17:39:09 / cg"
!
removeKey:aKey ifAbsent:aBlock
"remove the association under aKey from the collection,
return the value previously stored there..
If it was not in the collection return the result
from evaluating aBlock.
Redefined to avoid synchronization problems, in case
of interrupts (otherwise, there could be some other operation
on the receiver done by another process, which garbles my contents)."
|wasBlocked|
wasBlocked := OperatingSystem blockInterrupts.
[
super removeKey:aKey ifAbsent:aBlock
] valueNowOrOnUnwindDo:[
wasBlocked ifFalse:[OperatingSystem unblockInterrupts]
]
"Modified: 22.4.1996 / 17:39:57 / cg"
! !
!WeakIdentityDictionary methodsFor:'element disposal'!
informDispose
"an element (either key or value) died - rehash"
| sz "{ Class:SmallInteger }"
any wasBlocked |
"
have to block here - dispose may be done at a low priority
from the background finalizer. If new views are opened in
the foreground, the dependency dictionary may get corrupted
otherwise
"
wasBlocked := OperatingSystem blockInterrupts.
sz := keyArray size.
any := false.
1 to:sz do:[:index |
(keyArray at:index) isNil ifTrue:[
(valueArray at:index) notNil ifTrue:[
"/ soon to come; can then avoid rehash
"/ "
"/ if the next slot is not nil, it could be there due
"/ to a hash collision. In this case we have to put a
"/ DeletedMark into the slot.
"/ "
"/
"/ index == sz ifTrue:[
"/ next := 1
"/ ] ifFalse:[
"/ next := index + 1.
"/ ].
"/
"/ (keyArray basicAt:next) notNil ifTrue:[
"/ (valueArray basicAt:next) notNil ifTrue:[
"/ keyArray basicAt:index put:DeletedEntry
"/ ]
"/ ].
valueArray at:index put:nil.
tally := tally - 1.
any := true
]
]
].
any ifTrue:[self rehash].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
! !
!WeakIdentityDictionary methodsFor:'private'!
keyContainerOfSize:n
"return a container for keys of size n.
use WeakArrays here."
|w|
w := WeakArray new:n.
w watcher:self.
^ w
! !
!WeakIdentityDictionary class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libbasic/WeakIdentityDictionary.st,v 1.18 1996-04-25 16:18:46 cg Exp $'
! !