WeakIdentityDictionary.st
author Claus Gittinger <cg@exept.de>
Fri, 24 Jan 1997 19:16:48 +0100
changeset 2256 ffd565c6e084
parent 2091 c11bb3e29a1b
child 2260 96d898c2874d
permissions -rw-r--r--
checkin from browser

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

'From Smalltalk/X, Version:3.1.3 on 7-jan-1997 at 17:23:20'                     !

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 keys 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 WeakValueDictionary 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 trouble when dependencies
     are added within interrupting high prio processes."

    |wasBlocked|

    wasBlocked := OperatingSystem blockInterrupts.
    [
        super at:key put:anObject.
    ] valueNowOrOnUnwindDo:[
        wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
    ].
    ^ anObject

    "Modified: 6.5.1996 / 12:22:26 / stefan"
    "Modified: 20.10.1996 / 14:04:46 / 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 ret|

    wasBlocked := OperatingSystem blockInterrupts.
    [
        ret := super removeKey:aKey ifAbsent:aBlock
    ] valueNowOrOnUnwindDo:[
        wasBlocked ifFalse:[OperatingSystem unblockInterrupts]
    ].
    ^ ret

    "Modified: 22.4.1996 / 17:39:57 / cg"
    "Modified: 6.5.1996 / 12:44:51 / stefan"
! !

!WeakIdentityDictionary methodsFor:'element disposal'!

update:something with:aParameter from:changedObject
    "an element (either key or value) died - rehash"

    |wasBlocked|

    something == #ElementExpired ifTrue:[
        "
         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.

        keyArray 
            forAllDeadIndicesDo:[:idx | 
                                    (valueArray at:idx) notNil ifTrue:[
                                        keyArray basicAt:idx put:DeletedEntry.
                                        valueArray basicAt:idx put:nil.
                                        tally := tally - 1.
                                    ]
                                ]
            replacingCorpsesWith:DeletedEntry.

        wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
    ]

    "Created: 7.1.1997 / 16:59:30 / stefan"
! !

!WeakIdentityDictionary methodsFor:'private'!

keyContainerOfSize:n
    "return a container for keys of size n.
     use WeakArrays here."

    |w|

    w := WeakArray new:n.
    w addDependent:self.
    ^ w

    "Modified: 7.1.1997 / 17:01:15 / stefan"
! !

!WeakIdentityDictionary class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/WeakIdentityDictionary.st,v 1.23 1997-01-08 19:42:15 stefan Exp $'
! !