FIX: Making Set/Dictionary etc. loops more robust

Joshua Scholar jscholar at access4less.net
Mon Nov 29 22:01:51 UTC 2004


Changes Set>>do:
from

do: aBlock
 tally = 0 ifTrue: [^ self].
 1 to: array size do:
  [:index |
  | each |
  (each _ array at: index) ifNotNil: [aBlock value: each]]

to

do: aBlock
 tally = 0 ifTrue: [^ self].
 array do: [:each | each ifNotNil: [aBlock value: each]].

The difference is that adding to a Set or Dictionary can put a new rehashed
hashed hash table into "array"

In the original version, if any block inside of a "do:" or any of the many
loops that depend on "do:" called code that added to that Set then there was
a chance the set would grow and rehash - and some element would be visited
more than once and some not at all.

The way it is with this change, adding to a Set in a loop adds an element
that might not be visited, and deleting an element doesn't necessarily mean
the element won't be visited but the meltdown scenario can't happen.

And of course the new version is at least as fast as the old one.

One other topic. The fact that Sets (and the many classes derived from Set)
never shrink is a potential memory leak.

There's probably not any apps that leak this way - after all the fastest way
to clear a Set or Dictionary is "aSet_Set new" not  "aSet do: [:e| aSet
remove: e ifAbsent: [] ]"

While this leak may not be important in general memory leaks are probably
imporant  because many people work by saving an image every day and that's
the equivalent to running Squeak forever.

Joshua Scholar
-------------- next part --------------
A non-text attachment was scrubbed...
Name: SetDo.1.cs
Type: application/octet-stream
Size: 267 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20041129/b0986527/SetDo.1.obj


More information about the Squeak-dev mailing list