IdSet.st
changeset 1 a27a279701f8
child 3 24d81bf47225
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IdSet.st	Fri Jul 16 11:39:45 1993 +0200
@@ -0,0 +1,94 @@
+"
+ COPYRIGHT (c) 1993 by Claus Gittinger
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+
+Set subclass:#IdentitySet
+         instanceVariableNames:''
+         classVariableNames:''
+         poolDictionaries:''
+         category:'Collections-Unordered'
+!
+
+IdentitySet comment:'
+
+COPYRIGHT (c) 1993 by Claus Gittinger
+              All Rights Reserved
+
+same as a Set but compares elements using == (i.e. they must be identical
+- not just equal in structure).
+Since compare is on identity, hashing is also done via
+identityHash instead of hash.
+
+%W% %E%
+
+written jan 93 by claus
+'!
+
+!IdentitySet methodsFor:'private'!
+
+find: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.
+     Redefined to compare for identity instead of equality"
+
+    |index      "{ Class:SmallInteger }"
+     length     "{ Class:SmallInteger }"
+     startIndex "{ Class:SmallInteger }" 
+     probe |
+
+    length := contentsArray basicSize.
+    startIndex := key identityHash \\ length + 1.
+
+    index := startIndex.
+    [true] whileTrue:[
+        probe := (contentsArray basicAt:index).
+        probe == key ifTrue:[^ index].
+        probe isNil ifTrue:[^ aBlock value].
+
+        index == length ifTrue:[
+            index := 1
+        ] ifFalse:[
+	    index := index + 1
+	].
+        index == startIndex ifTrue:[
+            ^ aBlock value
+        ]
+    ]
+!
+
+findElementOrNil:key
+    "Look for the key in the receiver.  Redefined to compare for
+     identity instead of equality"
+
+    |index      "{ Class:SmallInteger }"
+     length     "{ Class:SmallInteger }"
+     startIndex "{ Class:SmallInteger }"
+     probe |
+
+    length := contentsArray basicSize.
+    startIndex := key identityHash \\ length + 1.
+
+    index := startIndex.
+    [true] whileTrue:[
+        probe := contentsArray basicAt:index.
+        (probe isNil or: [key == probe]) ifTrue:[^ index].
+
+        index == length ifTrue:[
+            index := 1
+        ] ifFalse:[
+	    index := index + 1
+	].
+        index == startIndex ifTrue: [
+            ^ self grow findElementOrNil:key
+        ]
+    ]
+! !