On Mon, 2007-06-11 at 13:39 +0200, Paolo Bonzini wrote:
> I don't especially like the patch, but given the current implementation 
> of WeakSets it's probably the best idea.  An alternative would be to 
> reimplement #findIndex: and #add: as in Dictionary (and add a few other 
> affected methods, like #rehashObjectsAfter:).  For now I'll keep yours.

Specifically, added #addWhileGrowing:, #shallowCopy, and #deepCopy as
well.

smalltalk--backstage--2.2--patch-34 against patch-395 (also attached)

-- 
;;; Stephen Compall ** http://scompall.nocandysw.com/blog **
"Peta" is Greek for fifth; a petabyte is 10 to the fifth power, as
well as fifth in line after kilo, mega, giga, and tera.
  -- Lee Gomes, performing every Wednesday in his tech column
     "Portals" on page B1 of The Wall Street Journal
2007-06-11  Stephen Compall  <[EMAIL PROTECTED]>

	* kernel/WeakObjects.st: Reimplement some private and public
	methods from HashedCollection for WeakSet, removing unneeded
	HomedAssociations.

	* kernel/HashedColl.st: Tweak #remove:ifAbsent:'s comment.


--- orig/kernel/HashedColl.st
+++ mod/kernel/HashedColl.st
@@ -103,8 +103,8 @@
 !HashedCollection methodsFor: 'removing'!
 
 remove: oldObject ifAbsent: anExceptionBlock
-    "Remove oldObject to the set. If it is found, answer oldObject.
-     Otherwise, evaluate anExceptionBlock and return its value."
+    "Remove oldObject from the set. If it is found, answer oldObject.
+     Otherwise, evaluate anExceptionBlock and answer its value."
 
     | index |
     index := self findIndexOrNil: oldObject.


--- orig/kernel/WeakObjects.st
+++ mod/kernel/WeakObjects.st
@@ -258,26 +258,16 @@
 add: anObject
     "Add newObject to the set, if and only if the set doesn't already contain
      an occurrence of it. Don't fail if a duplicate is found. Answer anObject"
-    super add: ((HomedAssociation key: anObject value: nil environment: self)
-	makeEphemeron;
-	yourself).
-    ^anObject
-!
-
-includes: anObject
-    "Answer whether I contain anObject."
-    ^super includes: (HomedAssociation key: anObject value: nil environment: self)
-!
-
-remove: anObject ifAbsent: aBlock
-    "Remove oldObject to the set. If it is found, answer oldObject.
-     Otherwise, evaluate aBlock and return its value."
-    | obj |
-    obj := super
-	remove: (HomedAssociation key: anObject value: nil environment: self)
-	ifAbsent: [ nil ].
-
-    obj isNil ifTrue: [ ^aBlock value ].
+    | index |
+    index := self findIndex: anObject ifAbsent: [ :index |
+	self incrementTally
+	    ifTrue: [ self findIndex: anObject ]
+	    ifFalse: [ index ]].
+
+    self primAt: index put:
+	((HomedAssociation key: anObject value: nil environment: self)
+	     makeEphemeron;
+	     yourself).
     ^anObject
 !
 
@@ -292,6 +282,36 @@
 
 
 
+!WeakSet methodsFor: 'copying'!
+
+shallowCopy
+    "Returns a shallow copy of the receiver (the instance variables are
+     not copied)"
+    | copy |
+    copy := self copyEmpty: self capacity.
+    self do: [:each | copy addWhileGrowing:
+			  ((HomedAssociation key: each value: nil
+					     environment: copy)
+			       makeEphemeron;
+			       yourself)].
+    ^copy
+!
+
+deepCopy
+    "Returns a deep copy of the receiver (the instance variables are
+     copies of the receiver's instance variables)"
+    | copy |
+    copy := self copyEmpty: self capacity.
+    self do: [ :each | copy addWhileGrowing:
+			   ((HomedAssociation key: each copy value: nil
+					      environment: copy)
+				makeEphemeron;
+				yourself) ].
+    ^copy
+! !
+
+
+
 !WeakSet methodsFor: 'private'!
 
 mourn: anObject
@@ -301,9 +321,34 @@
     super mourn: anObject key
 !
 
-hashFor: anObject
-    "Return an hash value for the item, anObject"
-    ^anObject key hash
+rehashObjectsAfter: index
+    "Private - Rehashes all the objects in the collection after index to
+    see if any of them hash to index.  If so, that object is copied to
+    index, and the process repeats with that object's index, until a nil
+    is encountered."
+    | i j size assoc |
+    i := index.
+    size := self primSize.
+    [   i = size ifTrue: [ i := 1 ] ifFalse: [ i := i + 1 ].
+	assoc := self primAt: i.
+	assoc notNil
+    ]   whileTrue: [
+	j := self findIndex: assoc key.
+	(self primAt: j) isNil ifTrue: [
+	    self primAt: j put: assoc.
+	    self primAt: i put: nil
+	]
+    ]
+!
+
+addWhileGrowing: association
+    "Private - Add the newObject association to the receiver. Don't check for
+     the set to be full - we want SPEED!."
+    self
+	primAt: (self findIndex: association key)
+	put: association.
+    tally := tally + 1.
+    ^association
 !
 
 findIndex: anObject
@@ -314,12 +359,12 @@
     self beConsistent.
 
     "Sorry for the lack of readability, but I want speed... :-)"
-    index := (anObject key hash scramble
+    index := (anObject hash scramble
                 bitAnd: (size := self primSize) - 1) + 1.
 
     [
         ((element := self primAt: index) isNil
-            or: [ element key = anObject key ])
+            or: [ element key = anObject ])
                 ifTrue: [ ^index ].
 
         index == size
@@ -487,7 +532,7 @@
 
 hashFor: anObject
     "Return an hash value for the item, anObject"
-    ^anObject key identityHash
+    ^anObject identityHash
 !
 
 findIndex: anObject
@@ -498,12 +543,12 @@
     self beConsistent.
 
     "Sorry for the lack of readability, but I want speed... :-)"
-    index := (anObject key identityHash scramble
+    index := (anObject identityHash scramble
                 bitAnd: (size := self primSize) - 1) + 1.
 
     [
         ((element := self primAt: index) isNil
-            or: [ element key == anObject key ])
+            or: [ element key == anObject ])
                 ifTrue: [ ^index ].
 
         index == size



Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
help-smalltalk mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

Reply via email to