#OTHER by stefan
authorStefan Vogel <sv@exept.de>
Thu, 11 Aug 2016 15:20:12 +0200
changeset 4021 12a732f6d443
parent 4019 9d2225af7229
child 4022 bbe200de665c
#OTHER by stefan class: PluggableDictionary added: #findKeyOrNilOrDeletedEntry: comment/format in: #examples changed: #emptyCollectionForKeys #find:ifAbsent: #findKeyOrNil: Make it work
PluggableDictionary.st
--- 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$'
 ! !