#OTHER by stefan
class: PluggableDictionary
added: #findKeyOrNilOrDeletedEntry:
comment/format in: #examples
changed:
#emptyCollectionForKeys
#find:ifAbsent:
#findKeyOrNil:
Make it work
--- a/PluggableDictionary.st Tue Aug 09 12:43:08 2016 +0200
+++ b/PluggableDictionary.st Thu Aug 11 15:20:12 2016 +0200
@@ -11,6 +11,8 @@
"
"{ Package: 'stx:libbasic2' }"
+"{ NameSpace: Smalltalk }"
+
Dictionary subclass:#PluggableDictionary
instanceVariableNames:'hashFunction compareFunction'
classVariableNames:''
@@ -48,7 +50,7 @@
|s|
s := PluggableDictionary
- hashWith:[:k | k size]
+ hashWith:[:k | k asLowercase hash]
compareWith:[:a :b | a notNil and:[b notNil and:[a asLowercase = b asLowercase]]].
s at:'hello' put:123.
s at:'world' put:222.
@@ -88,11 +90,11 @@
emptyCollectionForKeys
"return an empty collection used for keys.
- Here, an IdentitySet is returned.
- Made a separate method to allow redefinition for different kind of
- containers in subclasses."
+ Here, an PluggableSet is returned."
- ^ PluggableSet new:(self size) hashWith:hashFunction compareWith:compareFunction
+ ^ (PluggableSet new:self size)
+ hashWith:hashFunction compareWith:compareFunction;
+ youself.
!
find:key ifAbsent:aBlock
@@ -120,12 +122,16 @@
startIndex := index := self initialIndexForKey:key.
- [true] whileTrue:[
+ [
probe := keyArray basicAt:index.
- probe notNil ifTrue:[
- (compareFunction value:probe value:key) ifTrue:[^ index]. "<<<< == is different from inherited"
+ probe isNil ifTrue:[
+ ^ aBlock value.
].
- (self slotIsEmpty:probe) ifTrue:[^ aBlock value].
+
+ (probe ~~ DeletedEntry
+ and:[compareFunction value:probe value:key]) ifTrue:[ "<<<< == is different from inherited"
+ ^ index
+ ].
index == length ifTrue:[
index := 1
@@ -133,7 +139,7 @@
index := index + 1
].
index == startIndex ifTrue:[^ aBlock value]
- ]
+ ] loop.
!
findKeyOrNil:key
@@ -151,21 +157,17 @@
length := keyArray basicSize.
startIndex := index := self initialIndexForKey:key.
- [true] whileTrue:[
+ [
probe := keyArray basicAt:index.
- probe notNil ifTrue:[
- (compareFunction value:probe value:key) ifTrue:[^ index].
- ].
- (self slotIsEmpty:probe) ifTrue:[
+ probe isNil ifTrue:[
delIndex == 0 ifTrue:[^ index].
keyArray basicAt:delIndex put:nil.
^ delIndex
].
-
- probe == DeletedEntry ifTrue:[
- delIndex == 0 ifTrue:[
- delIndex := index
- ]
+ (probe == DeletedEntry and:[delIndex == 0]) ifTrue:[
+ delIndex := index.
+ ] ifFalse:[
+ (compareFunction value:probe value:key) ifTrue:[^ index]
].
index == length ifTrue:[
@@ -178,9 +180,54 @@
keyArray basicAt:delIndex put:nil.
^ delIndex
].
- ^ self grow findKeyOrNil:key
+ self grow.
+ length := keyArray basicSize.
+ startIndex := index := self initialIndexForKey:key.
].
- ]
+ ] loop.
+!
+
+findKeyOrNilOrDeletedEntry:key
+ "Look for the key in the receiver.
+ If it is found, return return the index of the first unused slot.
+ Grow the receiver, if key was not found, and no unused slots were present"
+
+ |index "{ Class:SmallInteger }"
+ length "{ Class:SmallInteger }"
+ startIndex probe
+ delIndex "{ Class:SmallInteger }" |
+
+ delIndex := 0.
+
+ length := keyArray basicSize.
+ startIndex := index := self initialIndexForKey:key.
+
+ [
+ probe := keyArray basicAt:index.
+ probe isNil ifTrue:[
+ delIndex == 0 ifTrue:[^ index].
+ ^ delIndex
+ ].
+ (probe == DeletedEntry and:[delIndex == 0]) ifTrue:[
+ delIndex := index.
+ ] ifFalse:[
+ (compareFunction value:probe value:key) ifTrue:[^ index]
+ ].
+
+ index == length ifTrue:[
+ index := 1
+ ] ifFalse:[
+ index := index + 1
+ ].
+ index == startIndex ifTrue:[
+ delIndex ~~ 0 ifTrue:[
+ ^ delIndex
+ ].
+ self grow.
+ length := keyArray basicSize.
+ startIndex := index := self initialIndexForKey:key.
+ ].
+ ] loop.
!
hashFor:aKey
@@ -210,10 +257,10 @@
!PluggableDictionary class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/PluggableDictionary.st,v 1.2 2014-02-18 21:21:01 cg Exp $'
+ ^ '$Header$'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/PluggableDictionary.st,v 1.2 2014-02-18 21:21:01 cg Exp $'
+ ^ '$Header$'
! !