* _SeekDown() now checks if it has already reached the maximum tree

depth, and will bail out if it hasn't reached the leaf level then.
* This should at least avoid the crash of bug #1911; there is not much
  more I can do about that.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24411 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-03-16 16:26:05 +00:00
parent d89cda9ff7
commit 7a3ecb82ba

View File

@ -59,7 +59,7 @@ class NodeChecker {
// Since BFS supports block sizes of 1024 bytes or greater, and the node size
// is hard-coded to 1024 bytes, that's not an issue now.
void
void
CachedNode::UnsetUnchanged(Transaction &transaction)
{
if (fTree == NULL || fTree->fStream == NULL)
@ -75,7 +75,7 @@ CachedNode::UnsetUnchanged(Transaction &transaction)
}
void
void
CachedNode::Unset()
{
if (fTree == NULL || fTree->fStream == NULL)
@ -504,7 +504,7 @@ BPlusTree::InitCheck()
}
int32
int32
BPlusTree::TypeCodeToKeyType(type_code code)
{
switch (code) {
@ -530,7 +530,7 @@ BPlusTree::TypeCodeToKeyType(type_code code)
}
int32
int32
BPlusTree::ModeToKeyType(mode_t mode)
{
switch (mode & (S_STR_INDEX | S_INT_INDEX | S_UINT_INDEX | S_LONG_LONG_INDEX
@ -588,7 +588,7 @@ BPlusTree::_AddIterator(TreeIterator *iterator)
}
void
void
BPlusTree::_RemoveIterator(TreeIterator *iterator)
{
if (fIteratorLock.Lock() < B_OK)
@ -723,13 +723,18 @@ BPlusTree::_SeekDown(Stack<node_and_key> &stack, const uint8 *key,
if (status == B_ENTRY_NOT_FOUND && nextOffset == nodeAndKey.nodeOffset)
RETURN_ERROR(B_ERROR);
if ((uint32)stack.CountItems() > fHeader->MaxNumberOfLevels()) {
dprintf("BPlusTree::_SeekDown() node walked too deep.\n");
break;
}
// put the node offset & the correct keyIndex on the stack
stack.Push(nodeAndKey);
nodeAndKey.nodeOffset = nextOffset;
}
FATAL(("BPlusTree::SeekDown() could not open node %Ld\n",
FATAL(("BPlusTree::_SeekDown() could not open node %Ld\n",
nodeAndKey.nodeOffset));
return B_ERROR;
}
@ -814,7 +819,7 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
if (array->count < NUM_FRAGMENT_VALUES) {
array->Insert(value);
} else {
// test if the fragment will be empty if we remove this key's values
// test if the fragment will be empty if we remove this key's values
if (duplicate->FragmentsUsed(fNodeSize) < 2) {
// the node will be empty without our values, so let us
// reuse it as a duplicate node
@ -1353,7 +1358,7 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
otherOffset, &nodeAndKey.keyIndex, keyBuffer, &keyLength,
&value) < B_OK) {
// free root node & other node here
cachedOther.Free(transaction, otherOffset);
cachedOther.Free(transaction, otherOffset);
cachedNewRoot.Free(transaction, newRoot);
RETURN_ERROR(B_ERROR);
@ -1951,11 +1956,11 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
{
if (fTree == NULL)
return B_INTERRUPTED;
bool forward = direction == BPLUSTREE_FORWARD;
if (fCurrentNodeOffset == BPLUSTREE_NULL
&& Goto(forward ? BPLUSTREE_BEGIN : BPLUSTREE_END) < B_OK)
&& Goto(forward ? BPLUSTREE_BEGIN : BPLUSTREE_END) < B_OK)
RETURN_ERROR(B_ERROR);
// if the tree was emptied since the last call
@ -2089,7 +2094,7 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
sets the current position in the iterator, regardless of if the
key could be found or not.
*/
status_t
status_t
TreeIterator::Find(const uint8 *key, uint16 keyLength)
{
if (fTree == NULL)
@ -2126,14 +2131,14 @@ TreeIterator::Find(const uint8 *key, uint16 keyLength)
}
void
void
TreeIterator::SkipDuplicates()
{
fDuplicateNode = BPLUSTREE_NULL;
}
void
void
TreeIterator::Update(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 splitAt, int8 change)
{
if (offset != fCurrentNodeOffset)
@ -2157,7 +2162,7 @@ TreeIterator::Update(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 spl
}
void
void
TreeIterator::Stop()
{
fTree = NULL;
@ -2165,7 +2170,7 @@ TreeIterator::Stop()
#ifdef DEBUG
void
void
TreeIterator::Dump()
{
__out("TreeIterator at %p:\n", this);
@ -2183,7 +2188,7 @@ TreeIterator::Dump()
// #pragma mark -
void
void
bplustree_node::Initialize()
{
left_link = right_link = overflow_link = HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);