[BUG][FIX] BTree>>removeKey:

Joshua Gargus schwa at fastmail.us
Tue Jan 18 04:29:27 UTC 2005


Hi Avi,

The attached changeset fixes the problem.  The cause appears to have 
been that #at: could modify the tree in a bad way if you give it a key 
smaller smaller than any already in the tree (and possibly in other 
cases; I'm not sure if these exist, what they are, and if this changeset 
addresses them).

I don't claim that this changeset provides optimal factoring of the 
code; it is just the simplest way that I thought of to fix the problem.  
I also haven't tested it extensively (I haven't even proven it correct ;-)

Sorry for not being more thorough; time is tight right now.
Josh



Joshua Gargus wrote:

> Oops, seems like there is still a problem.  Attached is some workspace 
> code with a logged sequence of adds/removes that causes an error.  I 
> don't have time to dig into it immediately, but will soon since I need 
> it working within a week.
>
> Josh
>
>
> Avi Bryant wrote:
>
>> On Thu, 23 Dec 2004 01:37:04 -0500, Joshua Gargus <schwa at fastmail.us> 
>> wrote:
>>  
>>
>>> Hi,
>>>
>>> The following code results in an error:
>>>
>>> | tree |
>>> tree := BTree new.
>>> 1 to: 15 do: [:i | tree at: i put: i].
>>> 1 to: 15 do: [:i | tree removeKey: i]
>>>   
>>
>>
>> Hi Josh,
>>
>> Sorry for the delay on this - I've integrated your (off list) fix and
>> put the result at http://beta4.com/mc/Collections-BTree-avi.43.mcz. 
>> Once SqueakMap comes back online I'll release it there too.
>>
>> Avi
>>
>>  
>>
>
>

-------------- next part --------------
'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 17 January 2005 at 11:16:13 pm'!
"Change Set:		BTree-fixes
Date:			17 January 2005
Author:			Joshua Gargus

#at:ifAbsent: was causing problems if you look for a key smaller than any other keys in the tree; in such a case, it would cause a change in the tree.  This changeset makes it so that #at:ifAbsent: does not change the tree at all, regardless of whether the key is found."!


!BTree methodsFor: 'accessing' stamp: 'jcg 1/17/2005 23:09'!
at: aMagnitude ifAbsent: errorBlock
	| leaf |
	leaf _ root existingLeafForKey: aMagnitude.
	leaf ifNil: [^ errorBlock value].
	^ leaf valueForKey: aMagnitude ifAbsent: errorBlock! !


!BTreeInteriorNode methodsFor: 'as yet unclassified' stamp: 'jcg 1/17/2005 22:59'!
existingChildForKey: aMagnitude
	"Unlike #childForKey:, this method looks for a child, but doesn't mess with the tree if it doesn't exist."
	| index |
	index _ keys findIndexForKey: aMagnitude.
	index = 0 
		ifTrue: [^ nil]
		ifFalse: [^ self at: index].! !

!BTreeInteriorNode methodsFor: 'as yet unclassified' stamp: 'jcg 1/17/2005 23:00'!
existingLeafForKey: aMagnitude
	"Unlike #leafForKey:, this method looks for a leaf but doesn't mess with the tree if it doesn't exist."
	| child |
	child _ self existingChildForKey: aMagnitude.
	^ child ifNotNil: [child existingLeafForKey: aMagnitude]! !


!BTreeLeafNode methodsFor: 'as yet unclassified' stamp: 'jcg 1/17/2005 23:08'!
existingLeafForKey: aMagnitude
	^ self! !



More information about the Squeak-dev mailing list