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
signature.asc
Description: This is a digitally signed message part
_______________________________________________ help-smalltalk mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-smalltalk
