class: Set
authorStefan Vogel <sv@exept.de>
Tue, 12 Nov 2013 19:14:08 +0100
changeset 15806 62bc6058e34f
parent 15805 799bc1a4f3af
child 15807 67f21e530e48
class: Set added: #findIdentical:ifAbsent: #removeIdentical:ifAbsent:
Set.st
--- a/Set.st	Tue Nov 12 19:10:56 2013 +0100
+++ b/Set.st	Tue Nov 12 19:14:08 2013 +0100
@@ -198,6 +198,7 @@
     "Created: / 24.10.1997 / 23:13:44 / cg"
 ! !
 
+
 !Set methodsFor:'Compatibility-ST80'!
 
 initialIndexFor:hashKey boundedBy:length
@@ -421,6 +422,55 @@
     "Modified: 12.4.1996 / 13:35:06 / cg"
 !
 
+removeIdentical:oldObjectArg ifAbsent:exceptionBlock
+    "remove oldObject from the collection and return it.
+     If it was not in the collection return the value of exceptionBlock.
+     Uses identity compare (==) to search for an occurrence.
+
+     WARNING: do not remove elements while iterating over the receiver.
+              See #saveRemove: to do this."
+
+    |oldObject index next|
+
+    oldObjectArg isNil ifTrue:[
+        oldObject := NilEntry.
+    ] ifFalse:[
+        oldObject := oldObjectArg.
+    ].
+
+    "first a quick check. 
+     There is a high possibility that objects, which are
+     equal are also identical"
+    index := self find:oldObject ifAbsent:0.
+    index ~~ 0 ifTrue:[
+        oldObject ~~ (keyArray basicAt:index) ifTrue:[
+            index := 0.
+        ]
+    ].
+    index == 0 ifTrue:[
+        "have to go the long and hard path..."
+        index := self findIdentical:oldObject ifAbsent:0.
+        index == 0 ifTrue:[^ exceptionBlock value].
+    ].
+
+    keyArray basicAt:index put:nil.
+    tally := tally - 1.
+    tally == 0 ifTrue:[
+        keyArray := self keyContainerOfSize:(self class goodSizeFrom:0). 
+    ] ifFalse:[
+        index == keyArray basicSize ifTrue:[
+            next := 1
+        ] ifFalse:[
+            next := index + 1.
+        ].
+        (keyArray basicAt:next) notNil ifTrue:[
+            keyArray basicAt:index put:DeletedEntry.
+        ].
+        self emptyCheck
+    ].
+    ^ oldObjectArg
+!
+
 saveRemove:oldObject 
     "remove the element, oldObject from the collection.
      Return the element 
@@ -800,6 +850,14 @@
     "Modified: / 03-02-2011 / 13:53:18 / sr"
 !
 
+findIdentical:key ifAbsent:aBlock
+    "Look for the key in the receiver.  If it is found, return
+     the index of the slot containing the key, otherwise
+     return the value of evaluating aBlock."
+
+    ^ keyArray identityIndexOf:key ifAbsent:aBlock
+!
+
 findKeyOrNil:key
     "Look for the key in the receiver.  
      If it is found, return the index of the first unused slot. 
@@ -1262,11 +1320,11 @@
 !Set class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.120 2013-04-03 09:10:55 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.121 2013-11-12 18:14:08 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.120 2013-04-03 09:10:55 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.121 2013-11-12 18:14:08 stefan Exp $'
 ! !