[rucksack-devel] Fixed the btree stress-test bug
Arthur Lemmens
alemmens at xs4all.nl
Sun Aug 12 13:11:21 UTC 2007
Henrik Hjelte wrote:
> The patch bundle is from darcs, but it is easy to read.
Thanks a lot, I've commited your fixes to CVS now. See also my
comments below.
> hunk ./p-btrees.lisp 831
> - (remove-key leaf key)
> + (remove-key leaf (binding-key binding))
This is a bug fix that you'd sent earlier already, right?
It was in CVS already.
> hunk ./p-btrees.lisp 551
> - (unless (typep value (btree-key-type btree))
> + (unless (typep value (btree-value-type btree))
Yes, that looks like a copy & paste error. Thanks.
> I think it would be nice if rucksack signals error when I give
> a duplicated key to a unique slot.
>But then I noticed the following comment in do.txt:
> - Check that btrees actually signal an error for duplicate keys.
> Handle those errors correctly for slot indexes.
> Why does rucksack need to handle the errors?
It's been a while since I looked at this, but I suppose my reasoning was that
the btree errors may need to be signalled in a slightly different way at the
rucksack level.
> hunk ./rucksack.lisp 864
> - (index-insert index new-value id))))))
> + (index-insert index new-value id
> + :if-exists
> + (and (slot-unique slot) :error)))))))
I modified this fix a bit. If the slot may have duplicate values, your
version passes :IF-EXISTS NIL to INDEX-INSERT. But :IF-EXISTS is specified
to take either :OVERWRITE or :ERROR, not NIL.
> I think it would be nicer if rucksack signals error for me
> when I give an imcompatible value to a slot with a index.
> (e.g. giving string to :symbol-index.)
>Adding :key-type to index-spec definitions seems to accomplish
> it. But I'm not sure this is right.
>What do you think?
This sounds like a good idea to me. Thanks, I've incorporated
this.
> +(defun update-parents-for-deleted-key (btree parent-stack old-key new-key)
> + (when parent-stack
> + (let ((node (first parent-stack)))
> + (when node
> + (let ((position (key-position old-key node)))
> + (when position
> + (setf (binding-key (node-binding node position))
> + new-key)
> + (update-parents-for-deleted-key btree (rest parent-stack) old-key new-key)))))))
> +
> hunk ./p-btrees.lisp 874
> - (remove-key leaf (binding-key binding))
> - (unless (node-full-enough-p btree leaf)
> - (enlarge-node btree leaf parent-stack))))
> +
> + (let ((position (key-position key leaf))
> + (length (btree-node-index-count leaf))
> + (was-biggest-key-p nil))
> + (when (= position (1- length))
> + (setf was-biggest-key-p t))
> + + (remove-key leaf (binding-key binding))
> +
> + (unless (node-full-enough-p btree leaf)
> + (enlarge-node btree leaf parent-stack))
> + + (when was-biggest-key-p
> + (unless (= 0 (btree-node-index-count leaf))
> + (update-parents-for-deleted-key btree parent-stack key (biggest-key leaf)))))))
So this was the big bug, right? If we're deleting the biggest key from
a leaf, we should update the parents so they'll use the key that has now
become the biggest, right? Thanks a lot for finding and fixing this!
Arthur
More information about the rucksack-devel
mailing list