WeakIdentityDictionary.st
changeset 2315 a9ff2fda8bae
parent 2306 3851fc553893
child 2329 937fc97d5544
--- a/WeakIdentityDictionary.st	Wed Jan 29 22:05:45 1997 +0100
+++ b/WeakIdentityDictionary.st	Wed Jan 29 22:10:56 1997 +0100
@@ -189,6 +189,79 @@
 
 !WeakIdentityDictionary methodsFor:'private'!
 
+findKeyOrNil: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 }" 
+     wasBlocked|
+
+    wasBlocked := OperatingSystem blockInterrupts.
+    wasBlocked ifFalse:[
+        "/ may never be entered with interrupts enabled
+        self error:'oops - unblocked call of findKeyOrNil'
+    ].
+
+    [
+        delIndex := 0.
+
+        length := keyArray basicSize.
+        index := key identityHash.
+        index < 16r1FFFFFFF ifTrue:[
+            index := index * 2
+        ].
+        index := index \\ length + 1.
+        startIndex := index.
+
+        [true] whileTrue:[
+            probe := keyArray basicAt:index.
+            key == probe ifTrue:[^ index].
+            probe isNil ifTrue:[
+                delIndex == 0 ifTrue:[^ index].
+                keyArray basicAt:delIndex put:nil.
+                ^ delIndex
+            ].
+
+            probe == 0 ifTrue:[
+                probe := DeletedEntry.
+                keyArray basicAt:index put:probe.
+                valueArray basicAt:index put:nil.
+                tally := tally - 1.
+            ].
+
+            delIndex == 0 ifTrue:[
+                probe == DeletedEntry ifTrue:[
+                    delIndex := index
+                ]
+            ].
+
+            index == length ifTrue:[
+                index := 1
+            ] ifFalse:[
+                index := index + 1
+            ].
+            index == startIndex ifTrue:[
+                delIndex ~~ 0 ifTrue:[
+                    keyArray basicAt:delIndex put:nil.
+                    ^ delIndex
+                ].
+                ^ self grow findKeyOrNil:key
+            ].
+        ]
+    ] valueNowOrOnUnwindDo:[
+        wasBlocked ifFalse:[
+            OperatingSystem unblockInterrupts
+        ]
+    ]
+
+    "Created: 29.1.1997 / 21:46:25 / cg"
+    "Modified: 29.1.1997 / 22:09:51 / cg"
+!
+
 grow:newSize
     "grow the receiver.
      Redefined to block interrupts, to avoid trouble when dependencies
@@ -272,5 +345,5 @@
 !WeakIdentityDictionary class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/WeakIdentityDictionary.st,v 1.27 1997-01-29 15:30:52 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/WeakIdentityDictionary.st,v 1.28 1997-01-29 21:10:56 cg Exp $'
 ! !