WeakIdDict.st
author Claus Gittinger <cg@exept.de>
Fri, 27 Oct 1995 16:56:51 +0100
changeset 451 5aab4706f2fd
parent 384 cc3d110ea879
child 530 07d0bce293c9
permissions -rw-r--r--
.

"
 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 comment:'
COPYRIGHT (c) 1992 by Claus Gittinger
	      All Rights Reserved

$Header: /cvs/stx/stx/libbasic/Attic/WeakIdDict.st,v 1.10 1995-08-11 03:04:57 claus Exp $
'!

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

version
"
$Header: /cvs/stx/stx/libbasic/Attic/WeakIdDict.st,v 1.10 1995-08-11 03:04:57 claus Exp $
"
!

documentation
"
    this is a special class 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.
"
! !

!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 methodsFor:'adding & removing'!

at:key put:value
    |wasBlocked|

    wasBlocked := OperatingSystem blockInterrupts.
    super at:key put:value.
    wasBlocked ifFalse:[OperatingSystem unblockInterrupts]
!

removeKey:aKey ifAbsent:aBlock
    |wasBlocked|

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

!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].
! !