A couple of endian fixes, inspired by Ingo - there might be some more left, though,
it's untested yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15693 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -737,14 +737,17 @@ BPlusTree::FindFreeDuplicateFragment(Transaction &transaction,
|
|||||||
{
|
{
|
||||||
off_t *values = node->Values();
|
off_t *values = node->Values();
|
||||||
for (int32 i = 0; i < node->NumKeys(); i++) {
|
for (int32 i = 0; i < node->NumKeys(); i++) {
|
||||||
|
off_t value = BFS_ENDIAN_TO_HOST_INT64(values[i]);
|
||||||
|
|
||||||
// does the value link to a duplicate fragment?
|
// does the value link to a duplicate fragment?
|
||||||
if (bplustree_node::LinkType(values[i]) != BPLUSTREE_DUPLICATE_FRAGMENT)
|
if (bplustree_node::LinkType(value) != BPLUSTREE_DUPLICATE_FRAGMENT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const bplustree_node *fragment = cached.SetTo(
|
const bplustree_node *fragment = cached.SetTo(
|
||||||
bplustree_node::FragmentOffset(values[i]), false);
|
bplustree_node::FragmentOffset(value), false);
|
||||||
if (fragment == NULL) {
|
if (fragment == NULL) {
|
||||||
FATAL(("Could not get duplicate fragment at %Ld\n", values[i]));
|
FATAL(("Could not get duplicate fragment at %Ld\n",
|
||||||
|
BFS_ENDIAN_TO_HOST_INT64(values[i])));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,7 +762,7 @@ BPlusTree::FindFreeDuplicateFragment(Transaction &transaction,
|
|||||||
if (*_fragment == NULL)
|
if (*_fragment == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
*_offset = bplustree_node::FragmentOffset(values[i]);
|
*_offset = bplustree_node::FragmentOffset(value);
|
||||||
*_index = j;
|
*_index = j;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -775,15 +778,14 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
|
|||||||
{
|
{
|
||||||
CachedNode cachedDuplicate(this);
|
CachedNode cachedDuplicate(this);
|
||||||
off_t *values = node->Values();
|
off_t *values = node->Values();
|
||||||
off_t oldValue = values[index];
|
off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]);
|
||||||
status_t status;
|
status_t status;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
|
|
||||||
if (bplustree_node::IsDuplicate(oldValue)) {
|
if (bplustree_node::IsDuplicate(oldValue)) {
|
||||||
//
|
|
||||||
// If it's a duplicate fragment, try to insert it into that, or if it
|
// If it's a duplicate fragment, try to insert it into that, or if it
|
||||||
// doesn't fit anymore, create a new duplicate node
|
// doesn't fit anymore, create a new duplicate node
|
||||||
//
|
|
||||||
if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) {
|
if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) {
|
||||||
bplustree_node *duplicate = cachedDuplicate.SetToWritable(transaction,
|
bplustree_node *duplicate = cachedDuplicate.SetToWritable(transaction,
|
||||||
bplustree_node::FragmentOffset(oldValue), false);
|
bplustree_node::FragmentOffset(oldValue), false);
|
||||||
@@ -816,7 +818,7 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
|
|||||||
array->Insert(value);
|
array->Insert(value);
|
||||||
} else {
|
} else {
|
||||||
// create a new duplicate node
|
// create a new duplicate node
|
||||||
|
|
||||||
cachedDuplicate.UnsetUnchanged(transaction);
|
cachedDuplicate.UnsetUnchanged(transaction);
|
||||||
// the old duplicate has not been touched, so we can reuse it
|
// the old duplicate has not been touched, so we can reuse it
|
||||||
|
|
||||||
@@ -831,7 +833,7 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
|
|||||||
memcpy(&newDuplicate->all_key_count, &array->values[0],
|
memcpy(&newDuplicate->all_key_count, &array->values[0],
|
||||||
array->count * sizeof(off_t));
|
array->count * sizeof(off_t));
|
||||||
memset(array, 0, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
|
memset(array, 0, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
|
||||||
|
|
||||||
array = newDuplicate->DuplicateArray();
|
array = newDuplicate->DuplicateArray();
|
||||||
array->Insert(value);
|
array->Insert(value);
|
||||||
}
|
}
|
||||||
@@ -840,7 +842,7 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
|
|||||||
if (cached.MakeWritable(transaction) == NULL)
|
if (cached.MakeWritable(transaction) == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
values[index] = bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_NODE, offset);
|
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_NODE, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -918,7 +920,7 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
|
|||||||
if (cached.MakeWritable(transaction) == NULL)
|
if (cached.MakeWritable(transaction) == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
values[index] = bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_FRAGMENT, offset, fragmentIndex);
|
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_FRAGMENT, offset, fragmentIndex));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -946,7 +948,7 @@ BPlusTree::InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyL
|
|||||||
memmove(newValues + index + 1, values + index, sizeof(off_t) * (node->NumKeys() - 1 - index));
|
memmove(newValues + index + 1, values + index, sizeof(off_t) * (node->NumKeys() - 1 - index));
|
||||||
memmove(newValues, values, sizeof(off_t) * index);
|
memmove(newValues, values, sizeof(off_t) * index);
|
||||||
|
|
||||||
newValues[index] = value;
|
newValues[index] = HOST_ENDIAN_TO_BFS_INT64(value);
|
||||||
|
|
||||||
// move and update key length index
|
// move and update key length index
|
||||||
for (uint16 i = node->NumKeys(); i-- > index + 1;)
|
for (uint16 i = node->NumKeys(); i-- > index + 1;)
|
||||||
@@ -1008,8 +1010,8 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
|
|||||||
}
|
}
|
||||||
out++;
|
out++;
|
||||||
|
|
||||||
if (round_up(sizeof(bplustree_node) + bytesBefore + bytesAfter + bytes) +
|
if (round_up(sizeof(bplustree_node) + bytesBefore + bytesAfter + bytes)
|
||||||
out * (sizeof(uint16) + sizeof(off_t)) >= size) {
|
+ out * (sizeof(uint16) + sizeof(off_t)) >= size) {
|
||||||
// we have found the number of keys in the new node!
|
// we have found the number of keys in the new node!
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1042,7 +1044,7 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
|
|||||||
// copy the newly inserted key
|
// copy the newly inserted key
|
||||||
memcpy(outKeys + bytesBefore, key, bytes);
|
memcpy(outKeys + bytesBefore, key, bytes);
|
||||||
outKeyLengths[keyIndex] = bytes + bytesBefore;
|
outKeyLengths[keyIndex] = bytes + bytesBefore;
|
||||||
outKeyValues[keyIndex] = *_value;
|
outKeyValues[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(*_value);
|
||||||
|
|
||||||
if (bytesAfter) {
|
if (bytesAfter) {
|
||||||
// copy the keys after the new key
|
// copy the keys after the new key
|
||||||
@@ -1171,7 +1173,7 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
|
|||||||
// finally, copy the newly inserted key (don't overwrite anything)
|
// finally, copy the newly inserted key (don't overwrite anything)
|
||||||
memcpy(inKeys + bytesBefore, key, bytes);
|
memcpy(inKeys + bytesBefore, key, bytes);
|
||||||
outKeyLengths[keyIndex] = bytes + bytesBefore;
|
outKeyLengths[keyIndex] = bytes + bytesBefore;
|
||||||
outKeyValues[keyIndex] = *_value;
|
outKeyValues[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(*_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the key that will be inserted in the parent node which
|
// Prepare the key that will be inserted in the parent node which
|
||||||
@@ -1334,7 +1336,7 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
|
|||||||
CachedNode &cached, uint16 index, off_t value)
|
CachedNode &cached, uint16 index, off_t value)
|
||||||
{
|
{
|
||||||
off_t *values = node->Values();
|
off_t *values = node->Values();
|
||||||
off_t oldValue = values[index];
|
off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]);
|
||||||
|
|
||||||
CachedNode cachedDuplicate(this);
|
CachedNode cachedDuplicate(this);
|
||||||
off_t duplicateOffset = bplustree_node::FragmentOffset(oldValue);
|
off_t duplicateOffset = bplustree_node::FragmentOffset(oldValue);
|
||||||
@@ -1379,14 +1381,13 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Remove value from a duplicate node!
|
// Remove value from a duplicate node!
|
||||||
//
|
|
||||||
|
|
||||||
duplicate_array *array = NULL;
|
duplicate_array *array = NULL;
|
||||||
|
|
||||||
if (duplicate->LeftLink() != BPLUSTREE_NULL) {
|
if (duplicate->LeftLink() != BPLUSTREE_NULL) {
|
||||||
FATAL(("invalid duplicate node: first left link points to %Ld!\n", duplicate->LeftLink()));
|
FATAL(("invalid duplicate node: first left link points to %Ld!\n",
|
||||||
|
duplicate->LeftLink()));
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1437,8 +1438,8 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
|
|||||||
values[index] = array->values[0];
|
values[index] = array->values[0];
|
||||||
} else {
|
} else {
|
||||||
// move the duplicate link to the next node
|
// move the duplicate link to the next node
|
||||||
values[index] = bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_NODE,
|
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
|
||||||
right);
|
BPLUSTREE_DUPLICATE_NODE, right));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1486,7 +1487,7 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
|
|||||||
// move to other node
|
// move to other node
|
||||||
duplicate_array *target = fragment->FragmentAt(fragmentIndex);
|
duplicate_array *target = fragment->FragmentAt(fragmentIndex);
|
||||||
memcpy(target, array, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
|
memcpy(target, array, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
|
||||||
|
|
||||||
cachedDuplicate.Free(transaction, duplicateOffset);
|
cachedDuplicate.Free(transaction, duplicateOffset);
|
||||||
duplicateOffset = offset;
|
duplicateOffset = offset;
|
||||||
} else {
|
} else {
|
||||||
@@ -1499,8 +1500,8 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
|
|||||||
if (cached.MakeWritable(transaction) == NULL)
|
if (cached.MakeWritable(transaction) == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
values[index] = bplustree_node::MakeLink(BPLUSTREE_DUPLICATE_FRAGMENT,
|
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
|
||||||
duplicateOffset, fragmentIndex);
|
BPLUSTREE_DUPLICATE_FRAGMENT, duplicateOffset, fragmentIndex));
|
||||||
}
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -1607,10 +1608,12 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
|
|||||||
next : BPLUSTREE_NULL, nodeAndKey.keyIndex, 0 , -1);
|
next : BPLUSTREE_NULL, nodeAndKey.keyIndex, 0 , -1);
|
||||||
|
|
||||||
// is this a duplicate entry?
|
// is this a duplicate entry?
|
||||||
if (bplustree_node::IsDuplicate(node->Values()[nodeAndKey.keyIndex])) {
|
if (bplustree_node::IsDuplicate(BFS_ENDIAN_TO_HOST_INT64(
|
||||||
if (fAllowDuplicates)
|
node->Values()[nodeAndKey.keyIndex]))) {
|
||||||
return RemoveDuplicate(transaction, node, cached, nodeAndKey.keyIndex, value);
|
if (fAllowDuplicates) {
|
||||||
else {
|
return RemoveDuplicate(transaction, node, cached,
|
||||||
|
nodeAndKey.keyIndex, value);
|
||||||
|
} else {
|
||||||
FATAL(("dupliate node found where no duplicates are allowed!\n"));
|
FATAL(("dupliate node found where no duplicates are allowed!\n"));
|
||||||
RETURN_ERROR(B_ERROR);
|
RETURN_ERROR(B_ERROR);
|
||||||
}
|
}
|
||||||
@@ -1705,7 +1708,7 @@ BPlusTree::Replace(Transaction &transaction, const uint8 *key, uint16 keyLength,
|
|||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
bplustree_node *writableNode = cached.MakeWritable(transaction);
|
bplustree_node *writableNode = cached.MakeWritable(transaction);
|
||||||
if (writableNode != NULL)
|
if (writableNode != NULL)
|
||||||
writableNode->Values()[keyIndex] = value;
|
writableNode->Values()[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(value);
|
||||||
else
|
else
|
||||||
status = B_IO_ERROR;
|
status = B_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user