[squeak-dev] Improving WeakKeyDictionary comment

Chris Muller asqueaker at gmail.com
Wed Jun 1 00:37:26 UTC 2022


Argh!  This one:   :)

|d|
d:={('hello' copy) -> 'world'.  'hello2' copy -> 'there'} as:
WeakKeyDictionary.
Smalltalk garbageCollect.
self assert: (d includesKey: 'hello') not.   "good"
self assert: d notEmpty.   "bad"
self assert: d array asSet size > 1.   "bad"
d finalizeValues.   "required!"
self assert: d array asSet size = 1.   "good"
self assert: d isEmpty.   "good"
self assert: (d reject: [ : each | each isNil ]) isEmpty.   "alternative to
finalizeValues"


On Tue, May 31, 2022 at 7:12 PM Chris Muller <asqueaker at gmail.com> wrote:

> Please replace the script in my prior email with this one.  Even though it
> still illustrates the problem, the previous script has a conceptual bug
> because I was playing around with Identity vs. regular and forgot to
> correct it back.
>
> |d|
> d:={('hello' copy) -> 'world'.  'hello2' copy -> 'there'} as:
> WeakKeyDictionary.
> Smalltalk garbageCollect.
> self assert: (d includesKey: obj1) not.
> self assert: d notEmpty.
> self assert: d array asSet size > 1.
> d finalizeValues.
> self assert: d array asSet size = 1.
> self assert: d isEmpty.
> self assert: (d reject: [ : each | each isNil ]) isEmpty.
>
>
> On Tue, May 31, 2022 at 7:04 PM Chris Muller <asqueaker at gmail.com> wrote:
>
>> Hi Jakob, hi Levente,
>>
>> > Whenever I read the class comment of WeakKeyDictionary, I know that I
>>> have to take care of something, but I do not know what. Can we improve the
>>> comment please to tell the readers more directly what is expected of them?
>>> >
>>> > - Must one ensure that #finalizeValues is sent to one's
>>> WeakKeyDictionary instance regularly?
>>>
>>
>> Yes.  Either that, or you need to otherwise somehow remove the garbage
>> collected entries from its internal array.
>>
>> Otherwise, the WeakKeyDictionary will only ever grow in size internally,
>> with a bunch of nil keys.  Here's a short script showing the mechanics and
>> assumptions of this:
>>
>> |d|
>> d:={'hello' copy -> 'world'.  'hello' copy -> 'there'} as:
>> WeakIdentityKeyDictionary.
>> Smalltalk garbageCollect.
>> self assert: (d includesKey: 'hello') not.   "good"
>> self assert: d notEmpty.    "bad"
>> self assert: d array asSet size > 1.   "bad"
>> d finalizeValues.   "required!"
>> self assert: d array asSet size = 1.   "good"
>> self assert: d isEmpty.    "good"
>>
>>
>>> Only if you are interested in finalization and want to do it your own
>>> way.
>>> And even then, only if you want to have your finalizer executed as soon
>>> as
>>> possible when a key of your dictionary has been garbage collected.
>>> So, if you just want a dictionary with weak keys, the answer is no.
>>>
>>
>>> > - Should one register the dictionary instance via WeakArray
>>> addWeakDependent:?
>>>
>>> Same as above. I'm not even sure it would work with
>>> WeakKeyDictionaries. It's intended to work with WeakRegistries, which
>>> are
>>> the main providers of finalization.
>>>
>>
>> I believe it would.  Check out WeakArray class>>#finalizationProcess and,
>> perhaps doing so would allow those WeakKey dictionary's to clean themselves
>> up automatically so you don't have to time sending #finalizeValues
>> yourself.  But, I don't trust it, because it's hard to tell, because
>> #finalizationProcess waits on FinalizationSemaphore, which is an opaque
>> VM-controlled semaphore which I have no idea when it's signaled.
>>
>>
>>> > - Which VM feature is the WeakRegistry class comment referring to; is
>>> it the semaphore used on the class side of WeakArray; and is it relevant to
>>> the use of WeakKeyDictionary?
>>>
>>> One[1] that has never really been used in Squeak and has been
>>> obsoleted by ephemerons. Even though we do not use ephemerons for
>>> finalization yet.
>>>
>>> > - If the answers to the questions above do not give it away, what must
>>> one do to use a WeakKeyDictionary safely?
>>>
>>> The difference between a regular Dictionary and a WeakKeyDictionary is
>>> that the latter cannot hold nil as a key, and your associations may
>>> disappear when their keys are not referenced strongly.
>>>
>>
>> They only disappear from the perspective of using the object API
>> (excluding #isEmpty and #notEmpty as demonstrated by the script above).
>> Internally, the former Association objects don't disappear, and still take
>> up memory.
>>
>> Igor made some alternative-implementation WeakKeyDictionary's for Magma
>> back in 2007 which are faster than the one's built into Squeak to this day
>> (last I checked, anyway).  If interested, load "MaBase" from SqueakMap and
>> then see MaWeakIdentityKeyDictionary.
>>
>> Regards,
>>   Chris
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220531/b66d6b5e/attachment.html>


More information about the Squeak-dev mailing list