<div dir="ltr"><div>Hi Marcel,</div><div>The presence of whole ancestry is not mandatory, as long as the common ancestor is present.</div><div>MC is robust to the absence of some ancestors.</div><div>You may consider the absence as equivalent to a git squash.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mar. 16 juin 2020 à 08:55, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Marcel Taeumel uploaded a new version of Collections to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Collections-mt.898.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Collections-mt.898.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Collections-mt.898<br>
Author: mt<br>
Time: 16 June 2020, 8:55:38.416917 am<br>
UUID: 89207449-befb-f84f-83a0-ff0d727d40bc<br>
Ancestors: Collections-mt.896, Collections-ul.897<br>
<br>
Merges ancestry. <br>
<br>
Does somebody know where to find Collections-ul.896?<br>
<br>
=============== Diff against Collections-mt.896 ===============<br>
<br>
Item was removed:<br>
- ----- Method: ByteArray>>atAllPut: (in category 'accessing') -----<br>
- atAllPut: value<br>
-       "Fill the receiver with the given value"<br>
- <br>
-       <primitive: 145><br>
-       super atAllPut: value!<br>
<br>
Item was changed:<br>
  ----- Method: String>>< (in category 'comparing') -----<br>
  < aString <br>
        "Answer whether the receiver sorts before aString.<br>
        The collation order is simple ascii (with case differences)."<br>
<br>
+       ^(self compareWith: aString) < 0!<br>
-       ^ (self compare: self with: aString collated: AsciiOrder) = 1!<br>
<br>
Item was changed:<br>
  ----- Method: String>><= (in category 'comparing') -----<br>
  <= aString <br>
        "Answer whether the receiver sorts before or equal to aString.<br>
        The collation order is simple ascii (with case differences)."<br>
<br>
+       ^(self compareWith: aString) <= 0!<br>
-       ^ (self compare: self with: aString collated: AsciiOrder) <= 2!<br>
<br>
Item was changed:<br>
  ----- Method: String>>= (in category 'comparing') -----<br>
  = aString <br>
        "Answer whether the receiver sorts equally as aString.<br>
        The collation order is simple ascii (with case differences)."<br>
<br>
        self == aString ifTrue: [ ^true ].<br>
        aString isString ifFalse: [ ^false ].<br>
        self size = aString size ifFalse: [ ^false ].<br>
+       ^ (self compareWith: aString) = 0!<br>
-       ^ (self compare: self with: aString collated: AsciiOrder) = 2!<br>
<br>
Item was changed:<br>
  ----- Method: String>>> (in category 'comparing') -----<br>
  > aString <br>
        "Answer whether the receiver sorts after aString.<br>
        The collation order is simple ascii (with case differences)."<br>
<br>
+       ^(self compareWith: aString) > 0!<br>
-       ^ (self compare: self with: aString collated: AsciiOrder) = 3!<br>
<br>
Item was changed:<br>
  ----- Method: String>>>= (in category 'comparing') -----<br>
  >= aString <br>
        "Answer whether the receiver sorts after or equal to aString.<br>
        The collation order is simple ascii (with case differences)."<br>
<br>
+       ^(self compareWith: aString) >= 0!<br>
-       ^ (self compare: self with: aString collated: AsciiOrder) >= 2!<br>
<br>
Item was changed:<br>
  ----- Method: String>>compare:caseSensitive: (in category 'comparing') -----<br>
  compare: aString caseSensitive: aBool<br>
        "Answer a comparison code telling how the receiver sorts relative to aString:<br>
                1 - before<br>
                2 - equal<br>
                3 - after.<br>
        "<br>
        | map |<br>
        map := aBool ifTrue:[CaseSensitiveOrder] ifFalse:[CaseInsensitiveOrder].<br>
+       ^(self compareWith: aString collated: map) + 2!<br>
-       ^self compare: self with: aString collated: map!<br>
<br>
Item was added:<br>
+ ----- Method: String>>compareWith: (in category 'comparing') -----<br>
+ compareWith: aString<br>
+ <br>
+       "<primitive: 158>"<br>
+       ^(self compare: self with: aString collated: AsciiOrder) - 2!<br>
<br>
Item was added:<br>
+ ----- Method: String>>compareWith:collated: (in category 'comparing') -----<br>
+ compareWith: aString collated: collation<br>
+ <br>
+       "<primitive: 158>"<br>
+       ^(self compare: self with: aString collated: collation) - 2!<br>
<br>
Item was removed:<br>
- ----- Method: WeakIdentityDictionary>>cleanupIndex: (in category 'private') -----<br>
- cleanupIndex: anInteger<br>
-       array at: anInteger put: vacuum.<br>
-       tally := tally - 1.<br>
-       self fixCollisionsFrom: anInteger.!<br>
<br>
Item was changed:<br>
  ----- Method: WeakIdentityDictionary>>fixCollisionsFrom: (in category 'private') -----<br>
  fixCollisionsFrom: start<br>
        "The element at start has been removed and replaced by vacuum.<br>
        This method moves forward from there, relocating any entries<br>
        that had been placed below due to collisions with this one."<br>
<br>
        | element index |<br>
        index := start.<br>
        [ (element := array at: (index := index \\ array size + 1)) == vacuum ] whileFalse: [<br>
                element<br>
                        ifNil:<br>
                                [ "The binding at this slot was reclaimed - finish the cleanup"<br>
                                array at: index put: vacuum.<br>
                                tally := tally - 1 ]<br>
                        ifNotNil:<br>
                                [| newIndex |<br>
+                               (newIndex := self scanFor: element key) = index ifFalse: [<br>
-                               (newIndex := self scanWithoutGarbagingFor: element key) = index ifFalse: [<br>
                                        array <br>
                                                at: newIndex put: element;<br>
                                                at: index put: vacuum ] ] ]!<br>
<br>
Item was changed:<br>
  ----- Method: WeakIdentityDictionary>>removeKey:ifAbsent: (in category 'removing') -----<br>
  removeKey: key ifAbsent: aBlock <br>
        "Remove key (and its associated value) from the receiver. If key is not in <br>
        the receiver, answer the result of evaluating aBlock. Otherwise, answer <br>
        the value externally named by key."<br>
<br>
        | index association |<br>
        index := self scanFor: key.<br>
        (association := (array at: index)) == vacuum ifTrue: [ ^aBlock value ].<br>
+       array at: index put: vacuum.<br>
+       tally := tally - 1.<br>
+       self fixCollisionsFrom: index.<br>
-       self cleanupIndex: index.<br>
        ^association value!<br>
<br>
Item was changed:<br>
  ----- Method: WeakIdentityDictionary>>scanFor: (in category 'private') -----<br>
  scanFor: anObject<br>
        "Scan the array for the first slot containing either<br>
        - a vacuum object indicating an empty slot<br>
        - or a binding whose key matches anObject.<br>
+       Answer the index of that slot or raise an error if no slot is found which should never happen."<br>
-       Answer the index of that slot or raise an error if no slot is found.<br>
-       When garbage collected slots are encountered, perform a clean-up."<br>
<br>
+       | index start size |<br>
+       index := start := anObject scaledIdentityHash \\ (size := array size) + 1.<br>
+       [ <br>
+               (array at: index) ifNotNil: [ :element |<br>
+                       (element == vacuum or: [ element key == anObject ])<br>
+                               ifTrue: [ ^index ] ].<br>
+               (index := index \\ size + 1) = start ] whileFalse.<br>
-       | index start rescan |  <br>
-       [<br>
-               rescan := false.<br>
-               index := start := anObject scaledIdentityHash \\ array size + 1.<br>
-               [ <br>
-                       (array at: index) <br>
-                               ifNil:<br>
-                                       ["Object at this slot has been garbage collected.<br>
-                                       A rescan is necessary because fixing collisions<br>
-                                       might have moved the target before current index."<br>
-                                       self cleanupIndex: index.<br>
-                                       rescan := true]<br>
-                               ifNotNil:<br>
-                                       [:element | (element == vacuum or: [ element key == anObject ])<br>
-                                               ifTrue: [ ^index ].<br>
-                                       (index := index \\ array size + 1) = start ] ] whileFalse.<br>
-               rescan ] whileTrue.<br>
        self errorNoFreeSpace!<br>
<br>
Item was changed:<br>
  ----- Method: WeakIdentityDictionary>>scanForEmptySlotFor: (in category 'private') -----<br>
  scanForEmptySlotFor: anObject<br>
+       "Scan the array for the first empty slot marked by vacuum object or nil.<br>
+       Answer the index of that slot or raise an error if no slot is found, which should never happen."<br>
-       "Scan the array for the first empty slot marked by vacuum object.<br>
-       Answer the index of that slot or raise an error if no slot is found.<br>
-       Ignore the slots that have been garbage collected (those containing nil)."<br>
<br>
        | index start | <br>
        index := start := anObject scaledIdentityHash \\ array size + 1.<br>
        [ <br>
+               | element |<br>
+               ((element := array at: index) == vacuum or: [ element == nil ]) ifTrue: [ ^index ].<br>
-               (array at: index) <br>
-                       ifNotNil:<br>
-                               [:element | element == vacuum ifTrue: [ ^index ] ].<br>
                (index := index \\ array size + 1) = start ] whileFalse.<br>
        self errorNoFreeSpace!<br>
<br>
Item was removed:<br>
- ----- Method: WeakIdentityDictionary>>scanWithoutGarbagingFor: (in category 'private') -----<br>
- scanWithoutGarbagingFor: anObject<br>
-       "Scan the array for the first slot containing either<br>
-       - a vacuum object indicating an empty slot<br>
-       - or a binding whose key matches anObject.<br>
-       Answer the index of that slot or raise an error if no slot is found.<br>
-       Ignore the slots that have been garbage collected (those containing nil)"<br>
- <br>
-       | index start | <br>
-       index := start := anObject scaledIdentityHash \\ array size + 1.<br>
-       [ <br>
-               (array at: index) <br>
-                       ifNotNil:<br>
-                               [:element | (element == vacuum or: [ element key == anObject ])<br>
-                                       ifTrue: [ ^index ] ].<br>
-               (index := index \\ array size + 1) = start ] whileFalse.<br>
-       self errorNoFreeSpace!<br>
<br>
<br>
</blockquote></div>