[squeak-dev] The Trunk: Collections-ct.972.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Dec 27 00:20:17 UTC 2021


Christoph Thiede uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ct.972.mcz

==================== Summary ====================

Name: Collections-ct.972
Author: ct
Time: 27 December 2021, 1:19:57.212181 am
UUID: f740e1ad-4410-0745-b615-2986366b7e75
Ancestors: Collections-tonyg.971

Adds PluggableWeakKeyDictionary, the logical combination of PluggableDictionary and WeakKeyDictionary. All methods are copied literally from PluggableDictionary, but the class inherits from WeakKeyDictionary rather than from Dictionary.

I do not like all the duplication myself but cannot think of a better solution without using composition (slow, breaking design change) or traits (breaking design change).

=============== Diff against Collections-tonyg.971 ===============

Item was added:
+ WeakKeyDictionary subclass: #PluggableWeakKeyDictionary
+ 	instanceVariableNames: 'hashBlock equalBlock'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Collections-Weak'!
+ 
+ !PluggableWeakKeyDictionary commentStamp: 'ct 12/27/2021 01:07' prior: 0!
+ I combine the features of PluggableDictionary and WeakKeyDictionary, i.e., clients can supply custom blocks for comparing and hasing my keys, and I hold weakly on my keys.!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary class>>integerDictionary (in category 'instance creation') -----
+ integerDictionary
+ 	^ self new hashBlock: [:integer | integer hash \\ 1064164 * 1009]!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>= (in category 'comparing') -----
+ = anObject
+ 	"Two dictionaries are equal if
+ 	 (a) they are the same 'kind' of thing.
+ 	 (b) they have the same set of keys.
+ 	 (c) for each (common) key, they have the same value"
+ 
+ 	self == anObject ifTrue: [ ^true ].
+ 	self species == anObject species ifFalse: [ ^false ].
+ 	hashBlock = anObject hashBlock ifFalse: [ ^false ].
+ 	equalBlock = anObject equalBlock ifFalse: [ ^false ].
+ 	self size = anObject size ifFalse: [ ^false ].
+ 	self associationsDo: [ :association |
+ 		(anObject at: association key ifAbsent: [ ^false ]) = association value
+ 			ifFalse: [ ^false ] ].
+ 	^true!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>collect: (in category 'enumerating') -----
+ collect: aBlock 
+ 	"Evaluate aBlock with each of my values as the argument.  Collect the resulting values into a collection that is like me. Answer with the new collection."
+ 	
+ 	| newCollection |
+ 	newCollection := (self species new: self size)
+ 		hashBlock: hashBlock;
+ 		equalBlock: equalBlock;
+ 		yourself.
+ 	self associationsDo: [ :each |
+ 		newCollection at: each key put: (aBlock value: each value) ].
+ 	^newCollection
+ 
+ !

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>copyEmpty (in category 'copying') -----
+ copyEmpty
+ 
+ 	^super copyEmpty
+ 		hashBlock: hashBlock;
+ 		equalBlock: equalBlock;
+ 		yourself!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>equalBlock (in category 'accessing') -----
+ equalBlock
+ 	"Return the block used for comparing the elements in the receiver."
+ 	^equalBlock!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>equalBlock: (in category 'accessing') -----
+ equalBlock: aBlock
+ 	"Set a new equality block. The block must accept two arguments and return true if the argumets are considered to be equal, false otherwise"
+ 	equalBlock := aBlock.!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>hashBlock (in category 'accessing') -----
+ hashBlock
+ 	"Return the block used for hashing the elements in the receiver."
+ 	^hashBlock!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>hashBlock: (in category 'accessing') -----
+ hashBlock: aBlock
+ 	"Set a new hash block. The block must accept one argument and must return the hash value of the given argument."
+ 	hashBlock := aBlock.!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>scanFor: (in category 'private') -----
+ scanFor: anObject 
+ 	"Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or raise an error if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements."
+ 	
+ 	| index start size |
+ 	index := start := (hashBlock
+ 		ifNil: [ anObject hash ]
+ 		ifNotNil: [ hashBlock value: anObject ]) \\ (size := array size) + 1.
+ 	[ 
+ 		| element |
+ 		((element := array at: index) == nil or: [
+ 			equalBlock
+ 				ifNil: [ element key = anObject ]
+ 				ifNotNil: [ equalBlock value: element key value: anObject ] ])
+ 			ifTrue: [ ^index ].
+ 		(index := index \\ size + 1) = start ] whileFalse.
+ 	self errorNoFreeSpace!

Item was added:
+ ----- Method: PluggableWeakKeyDictionary>>scanForEmptySlotFor: (in category 'private') -----
+ scanForEmptySlotFor: anObject
+ 	"Scan the key array for the first slot containing an empty slot (indicated by a nil). Answer the index of that slot. This method will be overridden in various subclasses that have different interpretations for matching elements."
+ 	
+ 	| index start size |
+ 	index := start := (hashBlock
+ 		ifNil: [ anObject hash ]
+ 		ifNotNil: [ hashBlock value: anObject ]) \\ (size := array size) + 1.
+ 	[ 
+ 		(array at: index) ifNil: [ ^index ].
+ 		(index := index \\ size + 1) = start ] whileFalse.
+ 	self errorNoFreeSpace!



More information about the Squeak-dev mailing list