Marcel Taeumel uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-mt.102.mcz
==================== Summary ====================
Name: PreferenceBrowser-mt.102
Author: mt
Time: 18 February 2020, 9:09:35.730015 am
UUID: 3a5db0c6-52ec-f94a-a738-680dec6a1dfb
Ancestors: PreferenceBrowser-mt.101
Small fix in the wizard's labels when installing extra packages. Make all labels appear in the same form, which starts with an uppercase letter and is (more or less) title case.
(Note that, after the release, we might want to re-design #findFeatures in String. That extra #asLowercase destroys information from the original text. But maybe that was intended after all to better cluster features.)
=============== Diff against PreferenceBrowser-mt.101 ===============
Item was changed:
----- Method: PreferenceWizardMorph>>installExtraPackages (in category 'actions') -----
installExtraPackages
"Removes the buttons and adds the progress bar during installation."
| steps page |
self removeProperty: #checkInternet. "No frequent checks for connectivity from here."
steps := #(
InstallLatestUpdates
InstallMetacello
InstallRefactoringTools
InstallAutoComplete
InstallGitInfrastructure
InstallFFI
InstallOSProcess )
+ select: [:ea | self perform: ('state', ea) asSymbol].
- select: [:ea | self perform: ('state', ea) asSymbol]
- thenCollect: [:ea | ea withFirstCharacterDownshifted asSymbol].
page := controlMorph firstSubmorph.
page submorphs second hide. "question"
page submorphs last delete. "url"
page submorphs last delete. "no button"
page submorphs last delete. "yes button"
page submorphs last delete. "package list"
self refreshWorld.
[
PreferenceWizardProgressMorph install.
page
addMorphBack: PreferenceWizardProgressMorph uniqueInstance;
addMorphBack: self createVerticalSpacer.
steps
+ do: [:step | self perform: step withFirstCharacterDownshifted asSymbol]
+ displayingProgress: [:step | String streamContents: [:s |
+ step findFeatureIndicesDo: [:start :end |
+ s nextPutAll: (step copyFrom: start to: end); space].
+ s nextPutAll: '...']].
- do: [:step | self perform: step]
- displayingProgress: [:step | (step findFeatures joinSeparatedBy: String space), ' ...'].
] ensure: [
PreferenceWizardProgressMorph reset.
self showSqueak].!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1132.mcz
==================== Summary ====================
Name: System-mt.1132
Author: mt
Time: 17 February 2020, 4:16:14.662347 pm
UUID: 6bc18c86-ae75-1f43-9ffb-6a741507fa39
Ancestors: System-cmm.1131
Fixes scaling bug due to invalidation of (recently introduced) cache for ScaleFactor.
=============== Diff against System-cmm.1131 ===============
Item was changed:
----- Method: UserInterfaceTheme>>fixFontsAndScaleAround: (in category 'private') -----
fixFontsAndScaleAround: block
"Due to the current situation with fonts and the real-estate manager, this is a small workaround to support theme switching with largely different font sizes."
lastScaleFactor ifNil: [lastScaleFactor := RealEstateAgent scaleFactor].
"Due to the current font situation, update TextConstants."
[ ignoreApply := true.
(self get: #standardSystemFont) ifNotNil: [:font | Preferences setSystemFontTo: font].
(self get: #standardFixedFont) ifNotNil: [:font | Preferences setFixedFontTo: font].
+ RealEstateAgent applyUserInterfaceTheme. "Reset cached scale factor now. Sigh."
] ensure: [ignoreApply := false].
"Apply theme etc."
block value.
"Due to the current real-estate manager situation, resize all windows. Works only for Morphic projects."
(RealEstateAgent scaleFactor - lastScaleFactor) abs > 0.1 ifTrue: [
Project current isMorphic ifTrue: [
| scale |
scale := RealEstateAgent scaleFactor / lastScaleFactor.
Project current world submorphs
select: [:ea | ea isSystemWindow]
thenDo: [:ea |
ea extent: (ea extent * scale).
ea layoutChanged.
ea setFramesForLabelArea]]].
lastScaleFactor := nil.!
Marcel Taeumel uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-mt.101.mcz
==================== Summary ====================
Name: PreferenceBrowser-mt.101
Author: mt
Time: 17 February 2020, 9:43:57.633291 am
UUID: 3f4a443f-0440-c14e-a7ef-475e81641bc5
Ancestors: PreferenceBrowser-dtl.100
Fixes re-use of preference and service browsers.
Thanks to Jakob (jr) and Christoph (ct) for the hint!
=============== Diff against PreferenceBrowser-dtl.100 ===============
Item was changed:
----- Method: PreferenceBrowser>>representsSameBrowseeAs: (in category 'user interface') -----
representsSameBrowseeAs: anotherModel
+ "If an existing Preference browser is on-screen, use it. Compare preferences with #== because those are typically persistent (or long living) database objects in the image."
+
+ ^ self class = anotherModel class
+ and: [self preferences == anotherModel preferences]!
- "If an existing Preference browser is on-screen, use it."
- ^ self class = anotherModel class!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.875.mcz
==================== Summary ====================
Name: Collections-ul.875
Author: ul
Time: 17 February 2020, 12:18:54.69743 am
UUID: e8d8fa4d-f205-4861-ac70-46989463beed
Ancestors: Collections-ul.874
- remove cruft and migration code from HashedCollection class >> #goodPrimeAtLeast:
=============== Diff against Collections-ul.874 ===============
Item was changed:
----- Method: HashedCollection class>>goodPrimeAtLeast: (in category 'sizing') -----
goodPrimeAtLeast: lowerLimit
"Answer the smallest good prime >= lowerlimit.
If lowerLimit is larger than the largest known good prime, just make it odd.
Use linear search, and exponential search to speed up cases when lowerLimit is small (<2500 and <100000, respectively).
Assume that there are goodPrimes greater than 100000."
| highIndex midIndex lowIndex prime |
- lowerLimit <= 7 ifTrue: [
- lowerLimit <= 3 ifTrue: [ ^3 ].
- lowerLimit <= 5 ifTrue: [ ^5 ].
- ^7 ].
- GoodPrimes ifNil: [ "migration only"
- self initializeGoodPrimes ].
lowerLimit < 2500 ifTrue: [
"Use linear search when the limit is small. The boundary is based on measurements."
+ highIndex := 1.
- highIndex := 4. "skip 3 5 and 7"
[ (GoodPrimes at: highIndex) < lowerLimit ] whileTrue: [
highIndex := highIndex + 1 ].
^GoodPrimes at: highIndex ].
lowerLimit < 100000
ifTrue: [
"Use exponential search when the limit is not too large. The boundary is based on measurements."
highIndex := 1.
[ (GoodPrimes at: highIndex) < lowerLimit ] whileTrue: [
highIndex := highIndex * 2 ].
lowIndex := highIndex // 2 + 1. "highIndex // 2 was smaller than lowerLimit" ]
ifFalse: [
"Regular binary search."
lowIndex := 1.
highIndex := GoodPrimes size.
"Check whether the largest prime would fit"
(GoodPrimes at: highIndex) < lowerLimit ifTrue: [
^lowerLimit bitOr: 1 ]. ].
[ highIndex - lowIndex <= 1 ] whileFalse: [
midIndex := highIndex + lowIndex // 2.
prime := GoodPrimes at: midIndex.
lowerLimit < prime
ifTrue: [ highIndex := midIndex ]
ifFalse: [
lowerLimit > prime
ifTrue: [ lowIndex := midIndex ]
ifFalse: [ ^prime ] ] ].
(GoodPrimes at: lowIndex) >= lowerLimit ifTrue: [ ^GoodPrimes at: lowIndex ].
^GoodPrimes at: highIndex!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.874.mcz
==================== Summary ====================
Name: Collections-ul.874
Author: ul
Time: 17 February 2020, 12:18:14.300566 am
UUID: b9affc2a-3c70-44f8-8e6a-66b7df1a41d0
Ancestors: Collections-topa.873
HashedCollection changes:
- speed up #goodPrimeAtLeast: when its argument is small
- let #sizeFor: return the smallest possible capacity (3)
- use #sizeFor: instead of #goodPrimeAtLeast: in #compact. This fixes the case when a 4 element dictionary is compacted to 80% capacity (array size = 5), which is higher than the advertised maximum: 75%.
- fixed the formula in #sizeFor:, which made the shortcut for small values unnecessary. Removed the shortcut. The fix often yields smaller dictionaries.
- store good primes in a class variable GoodPrimes for faster access and possible customization
- use blocks instead of symbols in #compactAll and #rehashAll
- introduced #slowSize in HashedCollection, which makes it possible to not override #growSize and #compact in weak subclasses
=============== Diff against Collections-topa.873 ===============
Item was changed:
Collection subclass: #HashedCollection
instanceVariableNames: 'tally array'
+ classVariableNames: 'GoodPrimes'
- classVariableNames: ''
poolDictionaries: ''
category: 'Collections-Abstract'!
!HashedCollection commentStamp: 'ul 4/12/2010 22:37' prior: 0!
I am an abstract collection of objects that implement hash and equality in a consitent way. This means that whenever two objects are equal, their hashes have to be equal too. If two objects are equal then I can only store one of them. Hashes are expected to be integers (preferably SmallIntegers). I also expect that the objects contained by me do not change their hashes. If that happens, hash invariants have to be re-established, which can be done by #rehash.
Since I'm abstract, no instances of me should exist. My subclasses should implement #scanFor:, #fixCollisionsFrom: and #noCheckNoGrowFillFrom:.
Instance Variables
array: <ArrayedCollection> (typically Array or WeakArray)
tally: <Integer> (non-negative)
array
- An array whose size is a prime number, it's non-nil elements are the elements of the collection, and whose nil elements are empty slots. There is always at least one nil. In fact I try to keep my "load" at 75% or less so that hashing will work well.
tally
- The number of elements in the collection. The array size is always greater than this.
Implementation details:
I implement a hash table which uses open addressing with linear probing as the method of collision resolution. Searching for an element or a free slot for an element is done by #scanFor: which should return the index of the slot in array corresponding to it's argument. When an element is removed #fixCollisionsFrom: should rehash all elements in array between the original index of the removed element, wrapping around after the last slot until reaching an empty slot. My maximum load factor (75%) is hardcoded in #atNewIndex:put:, so it can only be changed by overriding that method. When my load factor reaches this limit I replace my array with a larger one (see #grow) ensuring that my load factor will be less than or equal to 50%. The new array is filled by #noCheckNoGrowFillFrom: which should use #scanForEmptySlotFor: instead of #scanFor: for better performance. I do not shrink.
!
Item was changed:
----- Method: HashedCollection class>>compactAll (in category 'initialize-release') -----
compactAll
"HashedCollection compactAll"
+ self allSubclassesDo: [ :each | each compactAllInstances ]!
- self allSubclassesDo: #compactAllInstances!
Item was changed:
----- Method: HashedCollection class>>goodPrimeAtLeast: (in category 'sizing') -----
goodPrimeAtLeast: lowerLimit
+ "Answer the smallest good prime >= lowerlimit.
+ If lowerLimit is larger than the largest known good prime, just make it odd.
+ Use linear search, and exponential search to speed up cases when lowerLimit is small (<2500 and <100000, respectively).
+ Assume that there are goodPrimes greater than 100000."
- "Answer the next good prime >= lowerlimit.
- If lowerLimit is larger than the largest known good prime,
- just make it odd."
+ | highIndex midIndex lowIndex prime |
+ lowerLimit <= 7 ifTrue: [
+ lowerLimit <= 3 ifTrue: [ ^3 ].
+ lowerLimit <= 5 ifTrue: [ ^5 ].
+ ^7 ].
+ GoodPrimes ifNil: [ "migration only"
+ self initializeGoodPrimes ].
+ lowerLimit < 2500 ifTrue: [
+ "Use linear search when the limit is small. The boundary is based on measurements."
+ highIndex := 4. "skip 3 5 and 7"
+ [ (GoodPrimes at: highIndex) < lowerLimit ] whileTrue: [
+ highIndex := highIndex + 1 ].
+ ^GoodPrimes at: highIndex ].
+ lowerLimit < 100000
+ ifTrue: [
+ "Use exponential search when the limit is not too large. The boundary is based on measurements."
+ highIndex := 1.
+ [ (GoodPrimes at: highIndex) < lowerLimit ] whileTrue: [
+ highIndex := highIndex * 2 ].
+ lowIndex := highIndex // 2 + 1. "highIndex // 2 was smaller than lowerLimit" ]
+ ifFalse: [
+ "Regular binary search."
+ lowIndex := 1.
+ highIndex := GoodPrimes size.
+ "Check whether the largest prime would fit"
+ (GoodPrimes at: highIndex) < lowerLimit ifTrue: [
+ ^lowerLimit bitOr: 1 ]. ].
+ [ highIndex - lowIndex <= 1 ] whileFalse: [
+ midIndex := highIndex + lowIndex // 2.
+ prime := GoodPrimes at: midIndex.
- | low mid high prime primes |
- primes := self goodPrimes.
- high := primes size.
- lowerLimit > (primes at: high) ifTrue: [
- ^lowerLimit bitOr: 1 ].
- low := 1.
- [ high - low <= 1 ] whileFalse: [
- mid := high + low // 2.
- prime := primes at: mid.
lowerLimit < prime
+ ifTrue: [ highIndex := midIndex ]
- ifTrue: [ high := mid ]
ifFalse: [
lowerLimit > prime
+ ifTrue: [ lowIndex := midIndex ]
- ifTrue: [ low := mid ]
ifFalse: [ ^prime ] ] ].
+ (GoodPrimes at: lowIndex) >= lowerLimit ifTrue: [ ^GoodPrimes at: lowIndex ].
+ ^GoodPrimes at: highIndex!
- (primes at: low) >= lowerLimit ifTrue: [ ^primes at: low ].
- ^primes at: high!
Item was changed:
----- Method: HashedCollection class>>goodPrimes (in category 'sizing') -----
goodPrimes
+ "Answer a sorted array of prime numbers less than one billion that make good hash table sizes. See #initializeGoodPrimes."
- "Answer a sorted array of prime numbers less than one billion that make good
- hash table sizes. Should be expanded as needed. See comments below code"
+ ^GoodPrimes ifNil: [
+ self initializeGoodPrimes.
+ GoodPrimes ]!
- ^#(3 5 7 11 13 17 23 31 43 59 79 107 149 199 269 359 479 641 857 1151 1549 2069
- 2237 2423 2617 2797 2999 3167 3359 3539 3727 3911
- 4441 4787 5119 5471 5801 6143 6521 6827 7177 7517 7853
- 8783 9601 10243 10867 11549 12239 12919 13679 14293 15013 15731
- 17569 19051 20443 21767 23159 24611 25847 27397 28571 30047 31397
- 35771 38201 40841 43973 46633 48989 51631 54371 57349 60139 62969
- 70589 76091 80347 85843 90697 95791 101051 106261 111143 115777 120691 126311
- 140863 150523 160969 170557 181243 190717 201653 211891 221251 232591 242873 251443
- 282089 300869 321949 341227 362353 383681 401411 422927 443231 464951 482033 504011
- 562621 605779 647659 681607 723623 763307 808261 844709 886163 926623 967229 1014617
- 1121987 1201469 1268789 1345651 1429531 1492177 1577839 1651547 1722601 1800377 1878623 1942141 2028401
- 2242727 2399581 2559173 2686813 2836357 3005579 3144971 3283993 3460133 3582923 3757093 3903769 4061261
- 4455361 4783837 5068529 5418079 5680243 6000023 6292981 6611497 6884641 7211599 7514189 7798313 8077189
- 9031853 9612721 10226107 10745291 11338417 11939203 12567671 13212697 13816333 14337529 14938571 15595673 16147291
- 17851577 18993941 20180239 21228533 22375079 23450491 24635579 25683871 26850101 27921689 29090911 30153841 31292507 32467307
- 35817611 37983761 40234253 42457253 44750177 46957969 49175831 51442639 53726417 55954637 58126987 60365939 62666977 64826669
- 71582779 76039231 80534381 84995153 89500331 93956777 98470819 102879613 107400389 111856841 116365721 120819287 125246581 129732203
- 143163379 152076289 161031319 169981667 179000669 187913573 196826447 205826729 214748357 223713691 232679021 241591901 250504801 259470131
- 285162679 301939921 318717121 335494331 352271573 369148753 385926017 402603193 419480419 436157621 453034849 469712051 486589307 503366497 520043707
- 570475349 603929813 637584271 671138659 704693081 738247541 771801929 805356457 838910803 872365267 905919671 939574117 973128521 1006682977 1040137411
- 1073741833)
-
- "The above primes past 2069 were chosen carefully so that they do not interact badly with 1664525 (used by hashMultiply), and so that gcd(p, (256^k) +/- a) = 1, for 0<a<=32 and 0<k<=8. See Knuth's TAOCP for details."
-
- "The above primes also try to map the values of ((0 to: 4095) collect: [ :each | each << 18 \\ prime ]) sort to an equidistant sequence of numbers. This helps to avoid the collision of chains in identity-based hashed collections. To do that they were chosen to return a low value when the following block is evaluated with them as argument:
- [ :prime |
- | n slots cost optimalDistance |
- n := 1 bitShift: 22.
- slots := Array new: n + 1.
- 0 to: n - 1 do: [ :ea | slots at: ea + 1 put: (ea bitShift: 8) \\ prime ].
- slots at: n + 1 put: prime.
- slots sort.
- cost := 0.
- optimalDistance := prime // n.
- 2 to: n + 1 do: [ :index |
- | newCost |
- newCost := optimalDistance - ((slots at: index) - (slots at: index - 1)).
- newCost > cost ifTrue: [ cost := newCost ] ].
- result add: prime -> cost ]
-
- The shifts in the block relate to the numer of bits the #identityHash consists of (22) and the number of bits #scaledIdentityHash shifts it (8)"!
Item was added:
+ ----- Method: HashedCollection class>>initialize (in category 'sizing') -----
+ initialize
+
+ self initializeGoodPrimes!
Item was added:
+ ----- Method: HashedCollection class>>initializeGoodPrimes (in category 'sizing') -----
+ initializeGoodPrimes
+ "GoodPrimes is a sorted array of prime numbers less than one billion that make good hash table sizes. Should be expanded as needed. See comments below code."
+
+ GoodPrimes := #(3 5 7 11 13 17 23 31 43 59 79 107 149 199 269 359 479 641 857 1151 1549 2069
+ 2237 2423 2617 2797 2999 3167 3359 3539 3727 3911
+ 4441 4787 5119 5471 5801 6143 6521 6827 7177 7517 7853
+ 8783 9601 10243 10867 11549 12239 12919 13679 14293 15013 15731
+ 17569 19051 20443 21767 23159 24611 25847 27397 28571 30047 31397
+ 35771 38201 40841 43973 46633 48989 51631 54371 57349 60139 62969
+ 70589 76091 80347 85843 90697 95791 101051 106261 111143 115777 120691 126311
+ 140863 150523 160969 170557 181243 190717 201653 211891 221251 232591 242873 251443
+ 282089 300869 321949 341227 362353 383681 401411 422927 443231 464951 482033 504011
+ 562621 605779 647659 681607 723623 763307 808261 844709 886163 926623 967229 1014617
+ 1121987 1201469 1268789 1345651 1429531 1492177 1577839 1651547 1722601 1800377 1878623 1942141 2028401
+ 2242727 2399581 2559173 2686813 2836357 3005579 3144971 3283993 3460133 3582923 3757093 3903769 4061261
+ 4455361 4783837 5068529 5418079 5680243 6000023 6292981 6611497 6884641 7211599 7514189 7798313 8077189
+ 9031853 9612721 10226107 10745291 11338417 11939203 12567671 13212697 13816333 14337529 14938571 15595673 16147291
+ 17851577 18993941 20180239 21228533 22375079 23450491 24635579 25683871 26850101 27921689 29090911 30153841 31292507 32467307
+ 35817611 37983761 40234253 42457253 44750177 46957969 49175831 51442639 53726417 55954637 58126987 60365939 62666977 64826669
+ 71582779 76039231 80534381 84995153 89500331 93956777 98470819 102879613 107400389 111856841 116365721 120819287 125246581 129732203
+ 143163379 152076289 161031319 169981667 179000669 187913573 196826447 205826729 214748357 223713691 232679021 241591901 250504801 259470131
+ 285162679 301939921 318717121 335494331 352271573 369148753 385926017 402603193 419480419 436157621 453034849 469712051 486589307 503366497 520043707
+ 570475349 603929813 637584271 671138659 704693081 738247541 771801929 805356457 838910803 872365267 905919671 939574117 973128521 1006682977 1040137411
+ 1073741833)
+
+ "The above primes past 2069 were chosen carefully so that they do not interact badly with 1664525 (used by hashMultiply), and so that gcd(p, (256^k) +/- a) = 1, for 0<a<=32 and 0<k<=8. See Knuth's TAOCP for details."
+
+ "The above primes also try to map the values of ((0 to: 4095) collect: [ :each | each << 18 \\ prime ]) sort to an equidistant sequence of numbers. This helps to avoid the collision of chains in identity-based hashed collections. To do that they were chosen to return a low value when the following block is evaluated with them as argument:
+ [ :prime |
+ | n slots cost optimalDistance |
+ n := 1 bitShift: 22.
+ slots := Array new: n + 1.
+ 0 to: n - 1 do: [ :ea | slots at: ea + 1 put: (ea bitShift: 8) \\ prime ].
+ slots at: n + 1 put: prime.
+ slots sort.
+ cost := 0.
+ optimalDistance := prime // n.
+ 2 to: n + 1 do: [ :index |
+ | newCost |
+ newCost := optimalDistance - ((slots at: index) - (slots at: index - 1)).
+ newCost > cost ifTrue: [ cost := newCost ] ].
+ result add: prime -> cost ]
+
+ The shifts in the block relate to the numer of bits the #identityHash consists of (22) and the number of bits #scaledIdentityHash shifts it (8)"!
Item was changed:
----- Method: HashedCollection class>>new (in category 'instance creation') -----
new
+ "Create a HashedCollection large enough to hold 3 different objects without growing."
+
+ ^self basicNew initialize: 5 "For performance, inline the value 5 which would normally be returned by #sizeFor:."!
- ^ self basicNew initialize: 5!
Item was changed:
----- Method: HashedCollection class>>new: (in category 'instance creation') -----
+ new: numberOfElements
+ "Create a HashedCollection large enough to hold numberOfElements different objects without growing."
+
+ ^self basicNew initialize: (numberOfElements <= 3
+ ifFalse: [ self sizeFor: numberOfElements ]
+ ifTrue: [ "Inline values returned by #sizeFor: to ensure that #new: is not significantly slower than #new for small values."
+ numberOfElements < 3
+ ifTrue: [ 3 ]
+ ifFalse: [ 5 ] ])!
- new: nElements
- "Create a Set large enough to hold nElements without growing"
- ^ self basicNew initialize: (self sizeFor: nElements)!
Item was changed:
----- Method: HashedCollection class>>rehashAll (in category 'initialize-release') -----
rehashAll
"HashedCollection rehashAll"
+ self allSubclassesDo: [ :each | each rehashAllInstances ]!
- self allSubclassesDo: #rehashAllInstances!
Item was changed:
----- Method: HashedCollection class>>sizeFor: (in category 'sizing') -----
+ sizeFor: numberOfElements
+ "Return a large enough prime (or odd if too large), the size of the internal array to hold numberOfElements with at most 75% load factor."
- sizeFor: nElements
- "Large enough prime (or odd if too large) size to hold nElements with some slop (see fullCheck)"
+ ^self goodPrimeAtLeast: numberOfElements * 4 + 2 // 3 "Optimized version of (numberOfElements * 4 / 3) ceiling."!
- nElements < 4 ifTrue: [ ^5 ].
- ^self goodPrimeAtLeast: nElements + 1 * 4 // 3!
Item was changed:
----- Method: HashedCollection>>compact (in category 'private') -----
compact
"Reduce the size of array so that the load factor will be ~75%."
| newCapacity |
+ newCapacity := self class sizeFor: self slowSize.
- newCapacity := self class goodPrimeAtLeast: tally * 4 // 3.
self growTo: newCapacity!
Item was changed:
----- Method: HashedCollection>>growSize (in category 'private') -----
growSize
"Answer what my next higher table size should be"
+ ^self class sizeFor: self slowSize * 2!
- ^self class goodPrimeAtLeast: array size * 3 // 2 + 2!
Item was added:
+ ----- Method: HashedCollection>>slowSize (in category 'accessing') -----
+ slowSize
+ "Answer an upper bound of the number of elements in this collection. For regular collections, this can simply be the value of tally, but for collections that cannot maintain an exact value, like current weak collections, this has to be calculated on the fly."
+
+ ^tally!
Item was removed:
- ----- Method: WeakIdentityDictionary>>compact (in category 'private') -----
- compact
- "Reduce the size of array so that the load factor will be ~75%."
-
- | newCapacity |
- tally := self slowSize.
- newCapacity := self class goodPrimeAtLeast: tally * 4 // 3.
- self growTo: newCapacity!
Item was removed:
- ----- Method: WeakKeyDictionary>>compact (in category 'private') -----
- compact
- "Reduce the size of array so that the load factor will be ~75%."
-
- | newCapacity |
- newCapacity := self class goodPrimeAtLeast: self slowSize * 4 // 3.
- self growTo: newCapacity!
Item was removed:
- ----- Method: WeakKeyDictionary>>growSize (in category 'private') -----
- growSize
- "Answer what my next table size should be.
- Note that, it can be less than the current."
-
- ^self class goodPrimeAtLeast: self slowSize * 2 + 2!
Item was removed:
- ----- Method: WeakSet>>compact (in category 'private') -----
- compact
- "Reduce the size of array so that the load factor will be ~75%."
-
- | newCapacity |
- newCapacity := self class goodPrimeAtLeast: self slowSize * 4 // 3.
- self growTo: newCapacity!
Item was removed:
- ----- Method: WeakSet>>growSize (in category 'private') -----
- growSize
- "Answer what my next table size should be.
- Note that, it can be less than the current."
-
- ^self class goodPrimeAtLeast: self slowSize * 2 + 2!
David T. Lewis uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-dtl.100.mcz
==================== Summary ====================
Name: PreferenceBrowser-dtl.100
Author: dtl
Time: 16 February 2020, 12:35:11.729536 pm
UUID: 19d38706-4924-41f6-b2fc-dbffa58da38d
Ancestors: PreferenceBrowser-dtl.99
Use Installer rather than MCMcmUpdater for OSProcess/CommandShell installation
=============== Diff against PreferenceBrowser-dtl.99 ===============
Item was changed:
----- Method: PreferenceWizardMorph>>installOSProcess (in category 'actions - packages') -----
installOSProcess
+
+ Installer ss project: 'OSProcess'; install: 'OSProcess'.
+ Installer ss project: 'CommandShell'; install: 'CommandShell'.
- MCMcmUpdater
- updateFromRepository: 'http://www.squeaksource.com/OSProcess'
- baseName: 'update'
- interactive: false.
- MCMcmUpdater
- updateFromRepository: 'http://www.squeaksource.com/CommandShell'
- baseName: 'update'
- interactive: false
!
David T. Lewis uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-dtl.99.mcz
==================== Summary ====================
Name: PreferenceBrowser-dtl.99
Author: dtl
Time: 15 February 2020, 7:34:58.758991 pm
UUID: 88d9fcd6-debc-4796-9a31-f582b4b8d64a
Ancestors: PreferenceBrowser-mt.98
Update PreferenceWizardMorph>>installOSProcess to install OSProcess and CommandShell. Requires MonticelloConfigurations-dtl.158. Metacello is not required, just load the latest versions developed in and for Squeak.
=============== Diff against PreferenceBrowser-mt.98 ===============
Item was changed:
----- Method: PreferenceWizardMorph>>installOSProcess (in category 'actions - packages') -----
installOSProcess
+ MCMcmUpdater
+ updateFromRepository: 'http://www.squeaksource.com/OSProcess'
+ baseName: 'update'
+ interactive: false.
+ MCMcmUpdater
+ updateFromRepository: 'http://www.squeaksource.com/CommandShell'
+ baseName: 'update'
+ interactive: false
+ !
-
- Metacello new
- configuration: 'OSProcess';
- load.!
David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk:
http://source.squeak.org/trunk/MonticelloConfigurations-dtl.157.mcz
==================== Summary ====================
Name: MonticelloConfigurations-dtl.157
Author: dtl
Time: 13 February 2020, 7:48:03.886888 am
UUID: 89668850-fff1-457b-8e1a-f32d3397b935
Ancestors: MonticelloConfigurations-mt.156
Follow up on an old TODO reminder to remove an unused class var and its initialization. This was used during update stream conversion and is no longer relevant.
=============== Diff against MonticelloConfigurations-mt.156 ===============
Item was changed:
Object subclass: #MCMcmUpdater
instanceVariableNames: 'repository updateMapName lastUpdateMap'
+ classVariableNames: 'DefaultUpdateMap DefaultUpdateURL Registry SkipPackages UpdateFromServerAtStartup UpdateMissingPackages'
- classVariableNames: 'DefaultUpdateMap DefaultUpdateURL Registry SkipPackages UpdateFromServerAtStartup UpdateMissingPackages Updaters'
poolDictionaries: ''
category: 'MonticelloConfigurations'!
!MCMcmUpdater commentStamp: 'dtl 10/12/2015 19:45' prior: 0!
MCMcmUpdater provides utility methods for updating Monticello packages from Monticello configurations.
When Monticello configurations are stored in a repository (or repositories), MCMcmUpdater acts as an update stream. It first ensures that each configuration map has been loaded in sequence, then updates the last configuration map to the most recent version for each specified package, and finally loads these versions to produce a fully updated configuration.
Currently if a set of packages are unloaded from the image, using this class to reload them may cause problems, depending on what dependencies those classes have. Success is not assured. Removing packages via SmalltalkImage>>unloadAllKnownPackages will be successful, it flags the packages removed so that they are not loaded by this utility.
If you wish to not have MCMcmUpdater update packages, there are two ways to handle this:
1) To have MCMcmUpdater not update any packages not currently in the image set the UpdateMissingPackages preference to false:
MCMcmUpdater updateMissingPackages: false
Note that any new packages added to the repositories will not be picked up when this is turned off.
2) To have MCMcmUpdater not update a specific package, evaluate
MCMcmUpdater disableUpdatesOfPackage: <packageName>
Class Variables definitions:
DefaultUpdateURL - String: the URL that will be checked by default for updates. This would be set for a common standard location to check.
Repository - A registry of known MCMcmUpdater instances identified by repository URL and update map name.
SkipPackages - Set of Strings: names of packages to not update in MCMcmUpdater (empty by default).
UpdateMissingPackages - Boolean: if true (default), new packages in the update config map will be loaded unless they are in SkipPackages. If false, packages not currently loaded in the image will not be loaded by MCMcmUpdater. (This can be dangerous if packages are split - use at your own risk).
Instance Variables:
updateMapName - Base name of the files used for this updater, typically a name such as 'update' or 'update.spur'.
repository - URL of the repository in which the update maps are located.
lastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update.
!
Item was changed:
----- Method: MCMcmUpdater class>>initialize (in category 'class initialization') -----
initialize
"MCMcmUpdater initialize"
- self flag: #TODO. "remove Updaters class var after transition to Registry"
-
DefaultUpdateURL ifNil:[
DefaultUpdateURL := MCHttpRepository trunkUrlString.
DefaultUpdateMap := self defaultBaseName.
].
-
- Registry ifNil: [ "Migrate from Updaters class var to Registry"
- "Set new repository ivar in all existing instances"
- Updaters keysAndValuesDo: [ :k :v | v repository: k].
- "Populate the new registry"
- Updaters do: [:e | e register].
- "Set the default update map name to its prior value"
- self updateMapName:
- ((Updaters at: MCMcmUpdater defaultUpdateURL) updateMapName) ].
!