2007-06-11 Stephen Compall * 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