"====================================================================== | | MethodDictionary Method Definitions | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Paolo Bonzini. | | This file is part of the GNU Smalltalk class library. | | The GNU Smalltalk class library is free software; you can redistribute it | and/or modify it under the terms of the GNU Lesser General Public License | as published by the Free Software Foundation; either version 2.1, or (at | your option) any later version. | | The GNU Smalltalk class library is distributed in the hope that it will be | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | General Public License for more details. | | You should have received a copy of the GNU Lesser General Public License | along with the GNU Smalltalk class library; see the file COPYING.LESSER. | If not, write to the Free Software Foundation, 59 Temple Place - Suite | 330, Boston, MA 02111-1307, USA. | ======================================================================" IdentityDictionary variableSubclass: #MethodDictionary instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Language-Implementation' ! IdentityDictionary comment: 'I am similar to an IdentityDictionary, except that removal and rehashing operations inside my instances look atomic to the interpreter.' ! !MethodDictionary methodsFor: 'adding'! at: key put: value "Store value as associated to the given key" super at: key put: value. Behavior flushCache. ^value ! ! !MethodDictionary methodsFor: 'removing'! removeAssociation: anAssociation "Remove anAssociation's key from the dictionary" "The interpreter might be using this MethodDictionary while this method is running!! Therefore we perform the removal in a copy, and then atomically become that copy" | copy result | (self includesKey: anAssociation key) ifFalse: [ ^self error: 'key not found' ]. copy := self copy. result := copy dangerouslyRemoveAssociation: anAssociation. self become: copy. Behavior flushCache. ^result ! removeKey: anElement ifAbsent: aBlock "Remove the passed key from the dictionary, answer the result of evaluating aBlock if it is not found" "The interpreter might be using this MethodDictionary while this method is running!! Therefore we perform the removal in a copy, and then atomically become that copy" | copy result | (self includesKey: anElement) ifFalse: [ ^aBlock value ]. copy := self copy. result := copy dangerouslyRemoveKey: anElement ifAbsent: aBlock. self become: copy. Behavior flushCache. ^result ! ! !MethodDictionary methodsFor: 'rehashing'! rehash "Rehash the receiver" "The interpreter might be using this MethodDictionary while this method is running!! Therefore we create a copy that has correct hashing (it is built on the fly), then atomically become that copy" self growBy: 0 ! ! !MethodDictionary methodsFor: 'private methods'! dangerouslyRemoveAssociation: anAssociation "This is not really dangerous. But if normal removal were done WHILE a MethodDictionary were being used, the system might crash. So instead we make a copy, then do this operation (which is NOT dangerous in a copy that is not being used), and then use the copy after the removal." ^super removeAssociation: anAssociation ! dangerouslyRemoveKey: anElement ifAbsent: aBlock "This is not really dangerous. But if normal removal were done WHILE a MethodDictionary were being used, the system might crash. So instead we make a copy, then do this operation (which is NOT dangerous in a copy that is not being used), and then use the copy after the removal." ^super removeKey: anElement ifAbsent: aBlock ! !