* Removed unused code when USER is defined - the fs_shell no longer does this, but

provides a kernel emulation layer.
* Renamed all private BPlusTree methods to have the '_' prefix.
* Removed useless set_sem_owner() from Lock.h - all semaphores created in the kernel
  always belong to the system team automatically.
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21054 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-05-07 12:26:21 +00:00
parent 68f08f67f5
commit 3bef51f0ae
6 changed files with 345 additions and 293 deletions
+242 -181
View File
@@ -1,12 +1,13 @@
/* BPlusTree - BFS B+Tree implementation /*
* Copyright 2001-2007, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License.
* *
* Roughly based on 'btlib' written by Marcus J. Ranum - it shares * Roughly based on 'btlib' written by Marcus J. Ranum - it shares
* no code but achieves binary compatibility with the on disk format. * no code but achieves binary compatibility with the on disk format.
*
* Copyright 2001-2006, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License.
*/ */
//! B+Tree implementation
#include "Debug.h" #include "Debug.h"
#include "BPlusTree.h" #include "BPlusTree.h"
@@ -215,7 +216,8 @@ CachedNode::InternalSetTo(Transaction *transaction, off_t offset)
uint8 *block; uint8 *block;
if (transaction != NULL) { if (transaction != NULL) {
block = (uint8 *)block_cache_get_writable(volume->BlockCache(), fBlockNumber, transaction->ID()); block = (uint8 *)block_cache_get_writable(volume->BlockCache(),
fBlockNumber, transaction->ID());
fWritable = true; fWritable = true;
} else { } else {
block = (uint8 *)block_cache_get(volume->BlockCache(), fBlockNumber); block = (uint8 *)block_cache_get(volume->BlockCache(), fBlockNumber);
@@ -270,7 +272,8 @@ CachedNode::Free(Transaction &transaction, off_t offset)
status_t status_t
CachedNode::Allocate(Transaction &transaction, bplustree_node **_node, off_t *_offset) CachedNode::Allocate(Transaction &transaction, bplustree_node **_node,
off_t *_offset)
{ {
if (fTree == NULL || fTree->fHeader == NULL || fTree->fStream == NULL) if (fTree == NULL || fTree->fHeader == NULL || fTree->fStream == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
@@ -307,7 +310,8 @@ CachedNode::Allocate(Transaction &transaction, bplustree_node **_node, off_t *_o
// the maximum_size has to be changed before the call to SetTo() - or // the maximum_size has to be changed before the call to SetTo() - or
// else it will fail because the requested node is out of bounds // else it will fail because the requested node is out of bounds
off_t offset = header->MaximumSize(); off_t offset = header->MaximumSize();
header->maximum_size = HOST_ENDIAN_TO_BFS_INT64(header->MaximumSize() + fTree->fNodeSize); header->maximum_size = HOST_ENDIAN_TO_BFS_INT64(header->MaximumSize()
+ fTree->fNodeSize);
if (SetToWritable(transaction, offset, false) != NULL) { if (SetToWritable(transaction, offset, false) != NULL) {
fNode->Initialize(); fNode->Initialize();
@@ -318,7 +322,8 @@ CachedNode::Allocate(Transaction &transaction, bplustree_node **_node, off_t *_o
} }
// revert header size to old value // revert header size to old value
header->maximum_size = HOST_ENDIAN_TO_BFS_INT64(header->MaximumSize() - fTree->fNodeSize); header->maximum_size = HOST_ENDIAN_TO_BFS_INT64(header->MaximumSize()
- fTree->fNodeSize);
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
} }
@@ -374,8 +379,7 @@ BPlusTree::~BPlusTree()
} }
/** Create a new B+Tree on the specified stream */ /*! Create a new B+Tree on the specified stream */
status_t status_t
BPlusTree::SetTo(Transaction &transaction, Inode *stream, int32 nodeSize) BPlusTree::SetTo(Transaction &transaction, Inode *stream, int32 nodeSize)
{ {
@@ -460,13 +464,16 @@ BPlusTree::SetTo(Inode *stream)
fNodeSize = fHeader->NodeSize(); fNodeSize = fHeader->NodeSize();
{ {
uint32 toMode[] = {S_STR_INDEX, S_INT_INDEX, S_UINT_INDEX, S_LONG_LONG_INDEX, uint32 toMode[] = {S_STR_INDEX, S_INT_INDEX, S_UINT_INDEX,
S_ULONG_LONG_INDEX, S_FLOAT_INDEX, S_DOUBLE_INDEX}; S_LONG_LONG_INDEX, S_ULONG_LONG_INDEX, S_FLOAT_INDEX,
uint32 mode = stream->Mode() & (S_STR_INDEX | S_INT_INDEX | S_UINT_INDEX | S_LONG_LONG_INDEX S_DOUBLE_INDEX};
| S_ULONG_LONG_INDEX | S_FLOAT_INDEX | S_DOUBLE_INDEX); uint32 mode = stream->Mode() & (S_STR_INDEX | S_INT_INDEX
| S_UINT_INDEX | S_LONG_LONG_INDEX | S_ULONG_LONG_INDEX
| S_FLOAT_INDEX | S_DOUBLE_INDEX);
if (fHeader->DataType() > BPLUSTREE_DOUBLE_TYPE if (fHeader->DataType() > BPLUSTREE_DOUBLE_TYPE
|| (stream->Mode() & S_INDEX_DIR) && toMode[fHeader->DataType()] != mode || (stream->Mode() & S_INDEX_DIR)
&& toMode[fHeader->DataType()] != mode
|| !stream->IsContainer()) { || !stream->IsContainer()) {
D( dump_bplustree_header(fHeader); D( dump_bplustree_header(fHeader);
dump_inode(&stream->Node()); dump_inode(&stream->Node());
@@ -548,8 +555,8 @@ BPlusTree::ModeToKeyType(mode_t mode)
void void
BPlusTree::UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 splitAt, BPlusTree::_UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex,
int8 change) uint16 splitAt, int8 change)
{ {
// Although every iterator which is affected by this update currently // Although every iterator which is affected by this update currently
// waits on a semaphore, other iterators could be added/removed at // waits on a semaphore, other iterators could be added/removed at
@@ -566,7 +573,7 @@ BPlusTree::UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex, uint
void void
BPlusTree::AddIterator(TreeIterator *iterator) BPlusTree::_AddIterator(TreeIterator *iterator)
{ {
if (fIteratorLock.Lock() < B_OK) if (fIteratorLock.Lock() < B_OK)
return; return;
@@ -578,7 +585,7 @@ BPlusTree::AddIterator(TreeIterator *iterator)
void void
BPlusTree::RemoveIterator(TreeIterator *iterator) BPlusTree::_RemoveIterator(TreeIterator *iterator)
{ {
if (fIteratorLock.Lock() < B_OK) if (fIteratorLock.Lock() < B_OK)
return; return;
@@ -590,7 +597,8 @@ BPlusTree::RemoveIterator(TreeIterator *iterator)
int32 int32
BPlusTree::CompareKeys(const void *key1, int keyLength1, const void *key2, int keyLength2) BPlusTree::_CompareKeys(const void *key1, int keyLength1, const void *key2,
int keyLength2)
{ {
type_code type = 0; type_code type = 0;
switch (fHeader->data_type) { switch (fHeader->data_type) {
@@ -621,8 +629,8 @@ BPlusTree::CompareKeys(const void *key1, int keyLength1, const void *key2, int k
status_t status_t
BPlusTree::FindKey(const bplustree_node *node, const uint8 *key, uint16 keyLength, BPlusTree::_FindKey(const bplustree_node *node, const uint8 *key,
uint16 *_index, off_t *_next) uint16 keyLength, uint16 *_index, off_t *_next)
{ {
#ifdef DEBUG #ifdef DEBUG
NodeChecker checker(node, fNodeSize, "find"); NodeChecker checker(node, fNodeSize, "find");
@@ -645,13 +653,14 @@ BPlusTree::FindKey(const bplustree_node *node, const uint8 *key, uint16 keyLengt
uint16 searchLength; uint16 searchLength;
uint8 *searchKey = node->KeyAt(i, &searchLength); uint8 *searchKey = node->KeyAt(i, &searchLength);
if (searchKey + searchLength + sizeof(off_t) + sizeof(uint16) > (uint8 *)node + fNodeSize if (searchKey + searchLength + sizeof(off_t) + sizeof(uint16)
> (uint8 *)node + fNodeSize
|| searchLength > BPLUSTREE_MAX_KEY_LENGTH) { || searchLength > BPLUSTREE_MAX_KEY_LENGTH) {
fStream->GetVolume()->Panic(); fStream->GetVolume()->Panic();
RETURN_ERROR(B_BAD_DATA); RETURN_ERROR(B_BAD_DATA);
} }
int32 cmp = CompareKeys(key, keyLength, searchKey, searchLength); int32 cmp = _CompareKeys(key, keyLength, searchKey, searchLength);
if (cmp < 0) { if (cmp < 0) {
last = i - 1; last = i - 1;
saveIndex = i; saveIndex = i;
@@ -678,13 +687,14 @@ BPlusTree::FindKey(const bplustree_node *node, const uint8 *key, uint16 keyLengt
} }
/** Prepares the stack to contain all nodes that were passed while /*!
* following the key, from the root node to the leaf node that could Prepares the stack to contain all nodes that were passed while
* or should contain that key. following the key, from the root node to the leaf node that could
or should contain that key.
*/ */
status_t status_t
BPlusTree::SeekDown(Stack<node_and_key> &stack, const uint8 *key, uint16 keyLength) BPlusTree::_SeekDown(Stack<node_and_key> &stack, const uint8 *key,
uint16 keyLength)
{ {
// set the root node to begin with // set the root node to begin with
node_and_key nodeAndKey; node_and_key nodeAndKey;
@@ -703,7 +713,8 @@ BPlusTree::SeekDown(Stack<node_and_key> &stack, const uint8 *key, uint16 keyLeng
} }
off_t nextOffset; off_t nextOffset;
status_t status = FindKey(node, key, keyLength, &nodeAndKey.keyIndex, &nextOffset); status_t status = _FindKey(node, key, keyLength, &nodeAndKey.keyIndex,
&nextOffset);
if (status == B_ENTRY_NOT_FOUND && nextOffset == nodeAndKey.nodeOffset) if (status == B_ENTRY_NOT_FOUND && nextOffset == nodeAndKey.nodeOffset)
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
@@ -714,17 +725,18 @@ BPlusTree::SeekDown(Stack<node_and_key> &stack, const uint8 *key, uint16 keyLeng
nodeAndKey.nodeOffset = nextOffset; nodeAndKey.nodeOffset = nextOffset;
} }
FATAL(("BPlusTree::SeekDown() could not open node %Ld\n", nodeAndKey.nodeOffset)); FATAL(("BPlusTree::SeekDown() could not open node %Ld\n",
nodeAndKey.nodeOffset));
return B_ERROR; return B_ERROR;
} }
/** This will find a free duplicate fragment in the given bplustree_node. /*!
* The CachedNode will be set to the writable fragment on success. This will find a free duplicate fragment in the given bplustree_node.
The CachedNode will be set to the writable fragment on success.
*/ */
status_t status_t
BPlusTree::FindFreeDuplicateFragment(Transaction &transaction, BPlusTree::_FindFreeDuplicateFragment(Transaction &transaction,
const bplustree_node *node, CachedNode &cached, const bplustree_node *node, CachedNode &cached,
off_t *_offset, bplustree_node **_fragment, uint32 *_index) off_t *_offset, bplustree_node **_fragment, uint32 *_index)
{ {
@@ -765,7 +777,7 @@ BPlusTree::FindFreeDuplicateFragment(Transaction &transaction,
status_t status_t
BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached, BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
const bplustree_node *node, uint16 index, off_t value) const bplustree_node *node, uint16 index, off_t value)
{ {
CachedNode cachedDuplicate(this); CachedNode cachedDuplicate(this);
@@ -784,7 +796,8 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
if (duplicate == NULL) if (duplicate == NULL)
return B_IO_ERROR; return B_IO_ERROR;
duplicate_array *array = duplicate->FragmentAt(bplustree_node::FragmentIndex(oldValue)); duplicate_array *array = duplicate->FragmentAt(
bplustree_node::FragmentIndex(oldValue));
if (array->count > NUM_FRAGMENT_VALUES if (array->count > NUM_FRAGMENT_VALUES
|| array->count < 1) { || array->count < 1) {
FATAL(("insertDuplicate: Invalid array[%d] size in fragment %Ld == %Ld!\n", FATAL(("insertDuplicate: Invalid array[%d] size in fragment %Ld == %Ld!\n",
@@ -803,9 +816,10 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
// reuse it as a duplicate node // reuse it as a duplicate node
offset = bplustree_node::FragmentOffset(oldValue); offset = bplustree_node::FragmentOffset(oldValue);
memmove(duplicate->DuplicateArray(), array, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t)); memmove(duplicate->DuplicateArray(), array,
duplicate->left_link = duplicate->right_link = HOST_ENDIAN_TO_BFS_INT64( (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
(uint64)BPLUSTREE_NULL); duplicate->left_link = duplicate->right_link
= HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
array = duplicate->DuplicateArray(); array = duplicate->DuplicateArray();
array->Insert(value); array->Insert(value);
@@ -816,13 +830,15 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
// the old duplicate has not been touched, so we can reuse it // the old duplicate has not been touched, so we can reuse it
bplustree_node *newDuplicate; bplustree_node *newDuplicate;
status = cachedDuplicate.Allocate(transaction, &newDuplicate, &offset); status = cachedDuplicate.Allocate(transaction,
&newDuplicate, &offset);
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
// copy the array from the fragment node to the duplicate node // copy the array from the fragment node to the duplicate node
// and free the old entry (by zero'ing all values) // and free the old entry (by zero'ing all values)
newDuplicate->overflow_link = HOST_ENDIAN_TO_BFS_INT64(array->count); newDuplicate->overflow_link = HOST_ENDIAN_TO_BFS_INT64(
array->count);
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));
@@ -894,10 +910,11 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
uint32 fragmentIndex = 0; uint32 fragmentIndex = 0;
bplustree_node *fragment; bplustree_node *fragment;
if (FindFreeDuplicateFragment(transaction, node, cachedDuplicate, if (_FindFreeDuplicateFragment(transaction, node, cachedDuplicate,
&offset, &fragment, &fragmentIndex) != B_OK) { &offset, &fragment, &fragmentIndex) != B_OK) {
// allocate a new duplicate fragment node // allocate a new duplicate fragment node
if ((status = cachedDuplicate.Allocate(transaction, &fragment, &offset)) < B_OK) if ((status = cachedDuplicate.Allocate(transaction, &fragment,
&offset)) < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
memset(fragment, 0, fNodeSize); memset(fragment, 0, fNodeSize);
@@ -918,8 +935,8 @@ BPlusTree::InsertDuplicate(Transaction &transaction, CachedNode &cached,
void void
BPlusTree::InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyLength, BPlusTree::_InsertKey(bplustree_node *node, uint16 index, uint8 *key,
off_t value) uint16 keyLength, off_t value)
{ {
// should never happen, but who knows? // should never happen, but who knows?
if (index > node->NumKeys()) if (index > node->NumKeys())
@@ -930,13 +947,15 @@ BPlusTree::InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyL
uint8 *keys = node->Keys(); uint8 *keys = node->Keys();
node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(node->NumKeys() + 1); node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(node->NumKeys() + 1);
node->all_key_length = HOST_ENDIAN_TO_BFS_INT16(node->AllKeyLength() + keyLength); node->all_key_length = HOST_ENDIAN_TO_BFS_INT16(node->AllKeyLength()
+ keyLength);
off_t *newValues = node->Values(); off_t *newValues = node->Values();
uint16 *newKeyLengths = node->KeyLengths(); uint16 *newKeyLengths = node->KeyLengths();
// move values and copy new value into them // move values and copy new value into them
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] = HOST_ENDIAN_TO_BFS_INT64(value); newValues[index] = HOST_ENDIAN_TO_BFS_INT64(value);
@@ -950,7 +969,8 @@ BPlusTree::InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyL
int32 keyStart; int32 keyStart;
newKeyLengths[index] = HOST_ENDIAN_TO_BFS_INT16(keyLength newKeyLengths[index] = HOST_ENDIAN_TO_BFS_INT16(keyLength
+ (keyStart = index > 0 ? BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index - 1]) : 0)); + (keyStart = index > 0
? BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index - 1]) : 0));
// move keys and copy new key into them // move keys and copy new key into them
uint16 length = BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index]); uint16 length = BFS_ENDIAN_TO_HOST_INT16(newKeyLengths[index]);
@@ -962,14 +982,15 @@ BPlusTree::InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyL
} }
/** Splits the \a node into two halves - the other half will be put into \a other. /*!
* It also takes care to create a new overflow link if the node to split is an Splits the \a node into two halves - the other half will be put into \a other.
* index node. It also takes care to create a new overflow link if the node to split is an
index node.
*/ */
status_t status_t
BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *other, BPlusTree::_SplitNode(bplustree_node *node, off_t nodeOffset,
off_t otherOffset, uint16 *_keyIndex, uint8 *key, uint16 *_keyLength, off_t *_value) bplustree_node *other, off_t otherOffset, uint16 *_keyIndex, uint8 *key,
uint16 *_keyLength, off_t *_value)
{ {
if (*_keyIndex > node->NumKeys() + 1) if (*_keyIndex > node->NumKeys() + 1)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -992,14 +1013,18 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
size_t size = fNodeSize >> 1; size_t size = fNodeSize >> 1;
int32 out, in; int32 out, in;
for (in = out = 0; in < node->NumKeys() + 1;) { for (in = out = 0; in < node->NumKeys() + 1;) {
if (!bytes) if (!bytes) {
bytesBefore = in > 0 ? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0; bytesBefore = in > 0
? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0;
}
if (in == keyIndex && !bytes) { if (in == keyIndex && !bytes) {
bytes = *_keyLength; bytes = *_keyLength;
} else { } else {
if (keyIndex < out) if (keyIndex < out) {
bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in]) - bytesBefore; bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in])
- bytesBefore;
}
in++; in++;
} }
@@ -1022,7 +1047,8 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
other->left_link = node->left_link; other->left_link = node->left_link;
other->right_link = HOST_ENDIAN_TO_BFS_INT64(nodeOffset); other->right_link = HOST_ENDIAN_TO_BFS_INT64(nodeOffset);
other->all_key_length = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore + bytesAfter); other->all_key_length = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore
+ bytesAfter);
other->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out); other->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out);
uint16 *outKeyLengths = other->KeyLengths(); uint16 *outKeyLengths = other->KeyLengths();
@@ -1043,13 +1069,15 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
if (bytesAfter) { if (bytesAfter) {
// copy the keys after the new key // copy the keys after the new key
memcpy(outKeys + bytesBefore + bytes, inKeys + bytesBefore, bytesAfter); memcpy(outKeys + bytesBefore + bytes, inKeys + bytesBefore,
bytesAfter);
keys = out - keyIndex - 1; keys = out - keyIndex - 1;
for (int32 i = 0;i < keys;i++) { for (int32 i = 0;i < keys;i++) {
outKeyLengths[keyIndex + i + 1] = HOST_ENDIAN_TO_BFS_INT16( outKeyLengths[keyIndex + i + 1] = HOST_ENDIAN_TO_BFS_INT16(
BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[keyIndex + i]) + bytes); BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[keyIndex + i]) + bytes);
} }
memcpy(outKeyValues + keyIndex + 1, inKeyValues + keyIndex, keys * sizeof(off_t)); memcpy(outKeyValues + keyIndex + 1, inKeyValues + keyIndex,
keys * sizeof(off_t));
} }
} }
@@ -1080,7 +1108,8 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
// If a key is dropped (is not the new key), we have to copy // If a key is dropped (is not the new key), we have to copy
// it, because it would be lost if not. // it, because it would be lost if not.
uint8 *droppedKey = node->KeyAt(in, &newLength); uint8 *droppedKey = node->KeyAt(in, &newLength);
if (droppedKey + newLength + sizeof(off_t) + sizeof(uint16) > (uint8 *)node + fNodeSize if (droppedKey + newLength + sizeof(off_t) + sizeof(uint16)
> (uint8 *)node + fNodeSize
|| newLength > BPLUSTREE_MAX_KEY_LENGTH) { || newLength > BPLUSTREE_MAX_KEY_LENGTH) {
fStream->GetVolume()->Panic(); fStream->GetVolume()->Panic();
RETURN_ERROR(B_BAD_DATA); RETURN_ERROR(B_BAD_DATA);
@@ -1106,7 +1135,8 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
// it's enough to set bytesBefore once here, because we do // it's enough to set bytesBefore once here, because we do
// not need to know the exact length of all keys in this // not need to know the exact length of all keys in this
// loop // loop
bytesBefore = in > skip ? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0; bytesBefore = in > skip
? BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in - 1]) : 0;
bytes = *_keyLength; bytes = *_keyLength;
} else { } else {
if (in < node->NumKeys()) { if (in < node->NumKeys()) {
@@ -1132,9 +1162,10 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
} }
// adjust the byte counts (since we were a bit lazy in the loop) // adjust the byte counts (since we were a bit lazy in the loop)
if (keyIndex >= in && keyIndex - skip < out) if (keyIndex >= in && keyIndex - skip < out) {
bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in]) - bytesBefore - total; bytesAfter = BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[in])
else if (keyIndex < skip) - bytesBefore - total;
} else if (keyIndex < skip)
bytesBefore = node->AllKeyLength() - total; bytesBefore = node->AllKeyLength() - total;
if (bytesBefore < 0 || bytesAfter < 0) if (bytesBefore < 0 || bytesAfter < 0)
@@ -1142,7 +1173,8 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
node->left_link = HOST_ENDIAN_TO_BFS_INT64(otherOffset); node->left_link = HOST_ENDIAN_TO_BFS_INT64(otherOffset);
// right link, and overflow link can stay the same // right link, and overflow link can stay the same
node->all_key_length = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore + bytesAfter); node->all_key_length = HOST_ENDIAN_TO_BFS_INT16(bytes + bytesBefore
+ bytesAfter);
node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out - 1); node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(out - 1);
// array positions have changed // array positions have changed
@@ -1157,19 +1189,25 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
if (bytesBefore) if (bytesBefore)
memmove(inKeys, inKeys + total, bytesBefore); memmove(inKeys, inKeys + total, bytesBefore);
if (bytesAfter) if (bytesAfter) {
memmove(inKeys + bytesBefore + bytes, inKeys + total + bytesBefore, bytesAfter); memmove(inKeys + bytesBefore + bytes, inKeys + total + bytesBefore,
bytesAfter);
}
if (bytesBefore) if (bytesBefore)
memmove(outKeyLengths, inKeyLengths + skip, keys * sizeof(uint16)); memmove(outKeyLengths, inKeyLengths + skip, keys * sizeof(uint16));
in = out - keyIndex - 1; in = out - keyIndex - 1;
if (bytesAfter) if (bytesAfter) {
memmove(outKeyLengths + keyIndex + 1, inKeyLengths + skip + keyIndex, in * sizeof(uint16)); memmove(outKeyLengths + keyIndex + 1, inKeyLengths + skip + keyIndex,
in * sizeof(uint16));
}
if (bytesBefore) if (bytesBefore)
memmove(outKeyValues, inKeyValues + skip, keys * sizeof(off_t)); memmove(outKeyValues, inKeyValues + skip, keys * sizeof(off_t));
if (bytesAfter) if (bytesAfter) {
memmove(outKeyValues + keyIndex + 1, inKeyValues + skip + keyIndex, in * sizeof(off_t)); memmove(outKeyValues + keyIndex + 1, inKeyValues + skip + keyIndex,
in * sizeof(off_t));
}
if (bytes) { if (bytes) {
// finally, copy the newly inserted key (don't overwrite anything) // finally, copy the newly inserted key (don't overwrite anything)
@@ -1196,14 +1234,16 @@ BPlusTree::SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *oth
} }
/** This inserts a key into the tree. The changes made to the tree will /*!
* all be part of the \a transaction. This inserts a key into the tree. The changes made to the tree will
all be part of the \a transaction.
*/ */
status_t status_t
BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value) BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
off_t value)
{ {
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH || keyLength > BPLUSTREE_MAX_KEY_LENGTH) if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
#ifdef DEBUG #ifdef DEBUG
if (value < 0) if (value < 0)
@@ -1214,7 +1254,7 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
WriteLocked locked(fStream->Lock()); WriteLocked locked(fStream->Lock());
Stack<node_and_key> stack; Stack<node_and_key> stack;
if (SeekDown(stack, key, keyLength) != B_OK) if (_SeekDown(stack, key, keyLength) != B_OK)
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
uint8 keyBuffer[BPLUSTREE_MAX_KEY_LENGTH + 1]; uint8 keyBuffer[BPLUSTREE_MAX_KEY_LENGTH + 1];
@@ -1226,18 +1266,21 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
const bplustree_node *node; const bplustree_node *node;
CachedNode cached(this); CachedNode cached(this);
while (stack.Pop(&nodeAndKey) && (node = cached.SetTo(nodeAndKey.nodeOffset)) != NULL) { while (stack.Pop(&nodeAndKey)
&& (node = cached.SetTo(nodeAndKey.nodeOffset)) != NULL) {
#ifdef DEBUG #ifdef DEBUG
NodeChecker checker(node, fNodeSize, "insert"); NodeChecker checker(node, fNodeSize, "insert");
#endif #endif
if (node->IsLeaf()) { if (node->IsLeaf()) {
// first round, check for duplicate entries // first round, check for duplicate entries
status_t status = FindKey(node, key, keyLength, &nodeAndKey.keyIndex); status_t status = _FindKey(node, key, keyLength,
&nodeAndKey.keyIndex);
// is this a duplicate entry? // is this a duplicate entry?
if (status == B_OK) { if (status == B_OK) {
if (fAllowDuplicates) { if (fAllowDuplicates) {
status = InsertDuplicate(transaction, cached, node, nodeAndKey.keyIndex, value); status = _InsertDuplicate(transaction, cached, node,
nodeAndKey.keyIndex, value);
if (status != B_OK) if (status != B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
return B_OK; return B_OK;
@@ -1252,11 +1295,14 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
return B_IO_ERROR; return B_IO_ERROR;
// is the node big enough to hold the pair? // is the node big enough to hold the pair?
if (int32(round_up(sizeof(bplustree_node) + writableNode->AllKeyLength() + keyLength) if (int32(round_up(sizeof(bplustree_node)
+ (writableNode->NumKeys() + 1) * (sizeof(uint16) + sizeof(off_t))) < fNodeSize) + writableNode->AllKeyLength() + keyLength)
{ + (writableNode->NumKeys() + 1) * (sizeof(uint16)
InsertKey(writableNode, nodeAndKey.keyIndex, keyBuffer, keyLength, value); + sizeof(off_t))) < fNodeSize) {
UpdateIterators(nodeAndKey.nodeOffset, BPLUSTREE_NULL, nodeAndKey.keyIndex, 0, 1); _InsertKey(writableNode, nodeAndKey.keyIndex,
keyBuffer, keyLength, value);
_UpdateIterators(nodeAndKey.nodeOffset, BPLUSTREE_NULL,
nodeAndKey.keyIndex, 0, 1);
return B_OK; return B_OK;
} else { } else {
@@ -1268,7 +1314,8 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
off_t newRoot = BPLUSTREE_NULL; off_t newRoot = BPLUSTREE_NULL;
if (nodeAndKey.nodeOffset == fHeader->RootNode()) { if (nodeAndKey.nodeOffset == fHeader->RootNode()) {
bplustree_node *root; bplustree_node *root;
status_t status = cachedNewRoot.Allocate(transaction, &root, &newRoot); status_t status = cachedNewRoot.Allocate(transaction, &root,
&newRoot);
if (status < B_OK) { if (status < B_OK) {
// The tree is most likely corrupted! // The tree is most likely corrupted!
// But it's still sane at leaf level - we could set // But it's still sane at leaf level - we could set
@@ -1283,14 +1330,16 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
// reserve space for the other node // reserve space for the other node
bplustree_node *other; bplustree_node *other;
off_t otherOffset; off_t otherOffset;
status_t status = cachedOther.Allocate(transaction, &other, &otherOffset); status_t status = cachedOther.Allocate(transaction, &other,
&otherOffset);
if (status < B_OK) { if (status < B_OK) {
cachedNewRoot.Free(transaction, newRoot); cachedNewRoot.Free(transaction, newRoot);
RETURN_ERROR(status); RETURN_ERROR(status);
} }
if (SplitNode(writableNode, nodeAndKey.nodeOffset, other, otherOffset, if (_SplitNode(writableNode, nodeAndKey.nodeOffset, other,
&nodeAndKey.keyIndex, keyBuffer, &keyLength, &value) < B_OK) { otherOffset, &nodeAndKey.keyIndex, keyBuffer, &keyLength,
&value) < B_OK) {
// free root node & other node here // free root node & other node here
cachedOther.Free(transaction, otherOffset); cachedOther.Free(transaction, otherOffset);
cachedNewRoot.Free(transaction, newRoot); cachedNewRoot.Free(transaction, newRoot);
@@ -1302,11 +1351,12 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
NodeChecker otherChecker(other, fNodeSize, "insert split other"); NodeChecker otherChecker(other, fNodeSize, "insert split other");
#endif #endif
UpdateIterators(nodeAndKey.nodeOffset, otherOffset, nodeAndKey.keyIndex, _UpdateIterators(nodeAndKey.nodeOffset, otherOffset,
writableNode->NumKeys(), 1); nodeAndKey.keyIndex, writableNode->NumKeys(), 1);
// update the right link of the node in the left of the new node // update the right link of the node in the left of the new node
if ((other = cachedOther.SetToWritable(transaction, other->LeftLink())) != NULL) { if ((other = cachedOther.SetToWritable(transaction,
other->LeftLink())) != NULL) {
other->right_link = HOST_ENDIAN_TO_BFS_INT64(otherOffset); other->right_link = HOST_ENDIAN_TO_BFS_INT64(otherOffset);
} }
@@ -1314,16 +1364,20 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
if (newRoot != BPLUSTREE_NULL) { if (newRoot != BPLUSTREE_NULL) {
bplustree_node *root = cachedNewRoot.Node(); bplustree_node *root = cachedNewRoot.Node();
InsertKey(root, 0, keyBuffer, keyLength, writableNode->LeftLink()); _InsertKey(root, 0, keyBuffer, keyLength,
root->overflow_link = HOST_ENDIAN_TO_BFS_INT64(nodeAndKey.nodeOffset); writableNode->LeftLink());
root->overflow_link = HOST_ENDIAN_TO_BFS_INT64(
nodeAndKey.nodeOffset);
bplustree_header *header = fCachedHeader.MakeWritableHeader(transaction); bplustree_header *header
= fCachedHeader.MakeWritableHeader(transaction);
if (header == NULL) if (header == NULL)
return B_IO_ERROR; return B_IO_ERROR;
// finally, update header to point to the new root // finally, update header to point to the new root
header->root_node_pointer = HOST_ENDIAN_TO_BFS_INT64(newRoot); header->root_node_pointer = HOST_ENDIAN_TO_BFS_INT64(newRoot);
header->max_number_of_levels = HOST_ENDIAN_TO_BFS_INT32(header->MaxNumberOfLevels() + 1); header->max_number_of_levels = HOST_ENDIAN_TO_BFS_INT32(
header->MaxNumberOfLevels() + 1);
return B_OK; return B_OK;
} }
@@ -1333,13 +1387,14 @@ BPlusTree::Insert(Transaction &transaction, const uint8 *key, uint16 keyLength,
} }
/** Removes the duplicate index/value pair from the tree. /*!
* It's part of the private tree interface. Removes the duplicate index/value pair from the tree.
It's part of the private tree interface.
*/ */
status_t status_t
BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node, BPlusTree::_RemoveDuplicate(Transaction &transaction,
CachedNode &cached, uint16 index, off_t value) const bplustree_node *node, CachedNode &cached, uint16 index,
off_t value)
{ {
off_t *values = node->Values(); off_t *values = node->Values();
off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]); off_t oldValue = BFS_ENDIAN_TO_HOST_INT64(values[index]);
@@ -1353,7 +1408,8 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
// if it's a duplicate fragment, remove the entry from there // if it's a duplicate fragment, remove the entry from there
if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) { if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) {
duplicate_array *array = duplicate->FragmentAt(bplustree_node::FragmentIndex(oldValue)); duplicate_array *array = duplicate->FragmentAt(
bplustree_node::FragmentIndex(oldValue));
if (array->count > NUM_FRAGMENT_VALUES if (array->count > NUM_FRAGMENT_VALUES
|| array->count < 1) { || array->count < 1) {
@@ -1488,7 +1544,7 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
bplustree_node *fragment = NULL; bplustree_node *fragment = NULL;
uint32 fragmentIndex = 0; uint32 fragmentIndex = 0;
off_t offset; off_t offset;
if (FindFreeDuplicateFragment(transaction, node, cachedOther, if (_FindFreeDuplicateFragment(transaction, node, cachedOther,
&offset, &fragment, &fragmentIndex) == B_OK) { &offset, &fragment, &fragmentIndex) == B_OK) {
// move to other node // move to other node
duplicate_array *target = fragment->FragmentAt(fragmentIndex); duplicate_array *target = fragment->FragmentAt(fragmentIndex);
@@ -1514,14 +1570,14 @@ BPlusTree::RemoveDuplicate(Transaction &transaction, const bplustree_node *node,
} }
/** Removes the key with the given index from the specified node. /*!
* Since it has to get the key from the node anyway (to obtain it's Removes the key with the given index from the specified node.
* pointer), it's not needed to pass the key & its length, although Since it has to get the key from the node anyway (to obtain it's
* the calling method (BPlusTree::Remove()) have this data. pointer), it's not needed to pass the key & its length, although
the calling method (BPlusTree::Remove()) have this data.
*/ */
void void
BPlusTree::RemoveKey(bplustree_node *node, uint16 index) BPlusTree::_RemoveKey(bplustree_node *node, uint16 index)
{ {
// should never happen, but who knows? // should never happen, but who knows?
if (index > node->NumKeys() && node->NumKeys() > 0) { if (index > node->NumKeys() && node->NumKeys() > 0) {
@@ -1575,35 +1631,38 @@ BPlusTree::RemoveKey(bplustree_node *node, uint16 index)
} }
/** Removes the specified key from the tree. The "value" parameter is only used /*!
* for trees which allow duplicates, so you may safely ignore it. Removes the specified key from the tree. The "value" parameter is only used
* It's not an optional parameter, so at least you have to think about it. for trees which allow duplicates, so you may safely ignore it.
It's not an optional parameter, so at least you have to think about it.
*/ */
status_t status_t
BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value) BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
off_t value)
{ {
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH || keyLength > BPLUSTREE_MAX_KEY_LENGTH) if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
// lock access to stream // lock access to stream
WriteLocked locked(fStream->Lock()); WriteLocked locked(fStream->Lock());
Stack<node_and_key> stack; Stack<node_and_key> stack;
if (SeekDown(stack, key, keyLength) != B_OK) if (_SeekDown(stack, key, keyLength) != B_OK)
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
node_and_key nodeAndKey; node_and_key nodeAndKey;
const bplustree_node *node; const bplustree_node *node;
CachedNode cached(this); CachedNode cached(this);
while (stack.Pop(&nodeAndKey) && (node = cached.SetTo(nodeAndKey.nodeOffset)) != NULL) { while (stack.Pop(&nodeAndKey)
&& (node = cached.SetTo(nodeAndKey.nodeOffset)) != NULL) {
#ifdef DEBUG #ifdef DEBUG
NodeChecker checker(node, fNodeSize, "remove"); NodeChecker checker(node, fNodeSize, "remove");
#endif #endif
if (node->IsLeaf()) { if (node->IsLeaf()) {
// first round, check for duplicate entries // first round, check for duplicate entries
status_t status = FindKey(node, key, keyLength, &nodeAndKey.keyIndex); status_t status = _FindKey(node, key, keyLength, &nodeAndKey.keyIndex);
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
@@ -1611,15 +1670,16 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
// to the next node after the current - if there aren't any // to the next node after the current - if there aren't any
// more nodes, we need a way to prevent the TreeIterators to // more nodes, we need a way to prevent the TreeIterators to
// touch the old node again, we use BPLUSTREE_FREE for this // touch the old node again, we use BPLUSTREE_FREE for this
off_t next = node->RightLink() == BPLUSTREE_NULL ? BPLUSTREE_FREE : node->RightLink(); off_t next = node->RightLink() == BPLUSTREE_NULL
UpdateIterators(nodeAndKey.nodeOffset, node->NumKeys() == 1 ? ? BPLUSTREE_FREE : node->RightLink();
next : BPLUSTREE_NULL, nodeAndKey.keyIndex, 0 , -1); _UpdateIterators(nodeAndKey.nodeOffset, node->NumKeys() == 1
? next : BPLUSTREE_NULL, nodeAndKey.keyIndex, 0 , -1);
// is this a duplicate entry? // is this a duplicate entry?
if (bplustree_node::IsDuplicate(BFS_ENDIAN_TO_HOST_INT64( if (bplustree_node::IsDuplicate(BFS_ENDIAN_TO_HOST_INT64(
node->Values()[nodeAndKey.keyIndex]))) { node->Values()[nodeAndKey.keyIndex]))) {
if (fAllowDuplicates) { if (fAllowDuplicates) {
return RemoveDuplicate(transaction, node, cached, return _RemoveDuplicate(transaction, node, cached,
nodeAndKey.keyIndex, value); nodeAndKey.keyIndex, value);
} else { } else {
FATAL(("dupliate node found where no duplicates are allowed!\n")); FATAL(("dupliate node found where no duplicates are allowed!\n"));
@@ -1658,7 +1718,7 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
// the overflow link, so we have to drop the last key) // the overflow link, so we have to drop the last key)
if (writableNode->NumKeys() > 1 if (writableNode->NumKeys() > 1
|| !writableNode->IsLeaf() && writableNode->NumKeys() == 1) { || !writableNode->IsLeaf() && writableNode->NumKeys() == 1) {
RemoveKey(writableNode, nodeAndKey.keyIndex); _RemoveKey(writableNode, nodeAndKey.keyIndex);
return B_OK; return B_OK;
} }
@@ -1680,19 +1740,21 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
} }
/** Replaces the value for the key in the tree. /*!
* Returns B_OK if the key could be found and its value replaced, Replaces the value for the key in the tree.
* B_ENTRY_NOT_FOUND if the key couldn't be found, and other errors Returns B_OK if the key could be found and its value replaced,
* to indicate that something went terribly wrong. B_ENTRY_NOT_FOUND if the key couldn't be found, and other errors
* Note that this doesn't work with duplicates - it will just to indicate that something went terribly wrong.
* return B_BAD_TYPE if you call this function on a tree where Note that this doesn't work with duplicates - it will just
* duplicates are allowed. return B_BAD_TYPE if you call this function on a tree where
duplicates are allowed.
*/ */
status_t status_t
BPlusTree::Replace(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value) BPlusTree::Replace(Transaction &transaction, const uint8 *key,
uint16 keyLength, off_t value)
{ {
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH || keyLength > BPLUSTREE_MAX_KEY_LENGTH if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH
|| key == NULL) || key == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
@@ -1709,7 +1771,7 @@ BPlusTree::Replace(Transaction &transaction, const uint8 *key, uint16 keyLength,
while ((node = cached.SetTo(nodeOffset)) != NULL) { while ((node = cached.SetTo(nodeOffset)) != NULL) {
uint16 keyIndex = 0; uint16 keyIndex = 0;
off_t nextOffset; off_t nextOffset;
status_t status = FindKey(node, key, keyLength, &keyIndex, &nextOffset); status_t status = _FindKey(node, key, keyLength, &keyIndex, &nextOffset);
if (node->OverflowLink() == BPLUSTREE_NULL) { if (node->OverflowLink() == BPLUSTREE_NULL) {
if (status == B_OK) { if (status == B_OK) {
@@ -1730,22 +1792,23 @@ BPlusTree::Replace(Transaction &transaction, const uint8 *key, uint16 keyLength,
} }
/** Searches the key in the tree, and stores the offset found in /*!
* _value, if successful. Searches the key in the tree, and stores the offset found in
* It's very similar to BPlusTree::SeekDown(), but doesn't fill _value, if successful.
* a stack while it descends the tree. It's very similar to BPlusTree::SeekDown(), but doesn't fill
* Returns B_OK when the key could be found, B_ENTRY_NOT_FOUND a stack while it descends the tree.
* if not. It can also return other errors to indicate that Returns B_OK when the key could be found, B_ENTRY_NOT_FOUND
* something went wrong. if not. It can also return other errors to indicate that
* Note that this doesn't work with duplicates - it will just something went wrong.
* return B_BAD_TYPE if you call this function on a tree where Note that this doesn't work with duplicates - it will just
* duplicates are allowed. return B_BAD_TYPE if you call this function on a tree where
duplicates are allowed.
*/ */
status_t status_t
BPlusTree::Find(const uint8 *key, uint16 keyLength, off_t *_value) BPlusTree::Find(const uint8 *key, uint16 keyLength, off_t *_value)
{ {
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH || keyLength > BPLUSTREE_MAX_KEY_LENGTH if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH
|| key == NULL) || key == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
@@ -1766,7 +1829,7 @@ BPlusTree::Find(const uint8 *key, uint16 keyLength, off_t *_value)
while ((node = cached.SetTo(nodeOffset)) != NULL) { while ((node = cached.SetTo(nodeOffset)) != NULL) {
uint16 keyIndex = 0; uint16 keyIndex = 0;
off_t nextOffset; off_t nextOffset;
status_t status = FindKey(node, key, keyLength, &keyIndex, &nextOffset); status_t status = _FindKey(node, key, keyLength, &keyIndex, &nextOffset);
#ifdef DEBUG #ifdef DEBUG
levels++; levels++;
@@ -1799,14 +1862,14 @@ TreeIterator::TreeIterator(BPlusTree *tree)
fCurrentNodeOffset(BPLUSTREE_NULL), fCurrentNodeOffset(BPLUSTREE_NULL),
fNext(NULL) fNext(NULL)
{ {
tree->AddIterator(this); tree->_AddIterator(this);
} }
TreeIterator::~TreeIterator() TreeIterator::~TreeIterator()
{ {
if (fTree) if (fTree)
fTree->RemoveIterator(this); fTree->_RemoveIterator(this);
} }
@@ -1840,7 +1903,8 @@ TreeIterator::Goto(int8 to)
nextOffset = node->OverflowLink(); nextOffset = node->OverflowLink();
else { else {
if (node->AllKeyLength() > fTree->fNodeSize if (node->AllKeyLength() > fTree->fNodeSize
|| (uint32)node->Values() > (uint32)node + fTree->fNodeSize - 8 * node->NumKeys()) || (uint32)node->Values() > (uint32)node + fTree->fNodeSize
- 8 * node->NumKeys())
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
nextOffset = BFS_ENDIAN_TO_HOST_INT64(node->Values()[0]); nextOffset = BFS_ENDIAN_TO_HOST_INT64(node->Values()[0]);
@@ -1856,21 +1920,21 @@ TreeIterator::Goto(int8 to)
} }
/** Iterates through the tree in the specified direction. /*!
* When it iterates through duplicates, the "key" is only updated for the Iterates through the tree in the specified direction.
* first entry - if you need to know when this happens, use the "duplicate" When it iterates through duplicates, the "key" is only updated for the
* parameter which is 0 for no duplicate, 1 for the first, and 2 for all first entry - if you need to know when this happens, use the "duplicate"
* the other duplicates. parameter which is 0 for no duplicate, 1 for the first, and 2 for all
* That's not too nice, but saves the 256 bytes that would be needed to the other duplicates.
* store the last key - if this will ever become an issue, it will be That's not too nice, but saves the 256 bytes that would be needed to
* easy to change. store the last key - if this will ever become an issue, it will be
* The other advantage of this is, that the queries can skip all duplicates easy to change.
* at once when they are not relevant to them. The other advantage of this is, that the queries can skip all duplicates
at once when they are not relevant to them.
*/ */
status_t status_t
TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength, uint16 maxLength, TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
off_t *value, uint16 *duplicate) uint16 maxLength, off_t *value, uint16 *duplicate)
{ {
if (fTree == NULL) if (fTree == NULL)
return B_INTERRUPTED; return B_INTERRUPTED;
@@ -2007,11 +2071,11 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength, uint16 maxL
} }
/** This is more or less a copy of BPlusTree::Find() - but it just /*!
* sets the current position in the iterator, regardless of if the This is more or less a copy of BPlusTree::Find() - but it just
* key could be found or not. 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) TreeIterator::Find(const uint8 *key, uint16 keyLength)
{ {
@@ -2031,7 +2095,8 @@ TreeIterator::Find(const uint8 *key, uint16 keyLength)
while ((node = cached.SetTo(nodeOffset)) != NULL) { while ((node = cached.SetTo(nodeOffset)) != NULL) {
uint16 keyIndex = 0; uint16 keyIndex = 0;
off_t nextOffset; off_t nextOffset;
status_t status = fTree->FindKey(node, key, keyLength, &keyIndex, &nextOffset); status_t status = fTree->_FindKey(node, key, keyLength, &keyIndex,
&nextOffset);
if (node->OverflowLink() == BPLUSTREE_NULL) { if (node->OverflowLink() == BPLUSTREE_NULL) {
fCurrentNodeOffset = nodeOffset; fCurrentNodeOffset = nodeOffset;
@@ -2160,12 +2225,11 @@ bplustree_node::DuplicateAt(off_t offset, bool isFragment, int8 index) const
} }
/** Although the name suggests it, this function doesn't return the real /*! Although the name suggests it, this function doesn't return the real
* used fragment count; at least, it can only count to two: it returns used fragment count; at least, it can only count to two: it returns
* 0, if there is no fragment used, 1 if there is only one fragment 0, if there is no fragment used, 1 if there is only one fragment
* used, and 2 if there are at least 2 fragments used. used, and 2 if there are at least 2 fragments used.
*/ */
uint32 uint32
bplustree_node::FragmentsUsed(uint32 nodeSize) const bplustree_node::FragmentsUsed(uint32 nodeSize) const
{ {
@@ -2210,14 +2274,11 @@ bplustree_node::CheckIntegrity(uint32 nodeSize) const
int32 int32
compareKeys(type_code type, const void *key1, int keyLength1, const void *key2, int keyLength2) compareKeys(type_code type, const void *key1, int keyLength1,
const void *key2, int keyLength2)
{ {
// if one of the keys is NULL, bail out gracefully // if one of the keys is NULL, bail out gracefully
if (key1 == NULL || key2 == NULL) { if (key1 == NULL || key2 == NULL) {
//#if USER
// // that's here to see if it's reasonable to handle this case nicely at all
// DEBUGGER(("compareKeys() got NULL key!"));
//#endif
// even if it's most probably a bug in the calling code, we try to // even if it's most probably a bug in the calling code, we try to
// give a meaningful result // give a meaningful result
if (key1 == NULL && key2 != NULL) if (key1 == NULL && key2 != NULL)
+79 -60
View File
@@ -1,9 +1,5 @@
/* BPlusTree - BFS B+Tree implementation /*
* * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de.
* Roughly based on 'btlib' written by Marcus J. Ranum - it shares
* no code but achieves binary compatibility with the on disk format.
*
* Copyright 2001-2005, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef B_PLUS_TREE_H #ifndef B_PLUS_TREE_H
@@ -15,7 +11,7 @@
#include "Chain.h" #include "Chain.h"
//****************** on-disk structures ******************** // #pragma mark - on-disk structures
struct bplustree_node; struct bplustree_node;
@@ -37,7 +33,8 @@ struct bplustree_header {
off_t RootNode() const { return BFS_ENDIAN_TO_HOST_INT64(root_node_pointer); } off_t RootNode() const { return BFS_ENDIAN_TO_HOST_INT64(root_node_pointer); }
off_t FreeNode() const { return BFS_ENDIAN_TO_HOST_INT64(free_node_pointer); } off_t FreeNode() const { return BFS_ENDIAN_TO_HOST_INT64(free_node_pointer); }
off_t MaximumSize() const { return BFS_ENDIAN_TO_HOST_INT64(maximum_size); } off_t MaximumSize() const { return BFS_ENDIAN_TO_HOST_INT64(maximum_size); }
uint32 MaxNumberOfLevels() const { return BFS_ENDIAN_TO_HOST_INT32(max_number_of_levels); } uint32 MaxNumberOfLevels() const
{ return BFS_ENDIAN_TO_HOST_INT32(max_number_of_levels); }
inline bool CheckNode(bplustree_node *node) const; inline bool CheckNode(bplustree_node *node) const;
inline bool IsValidLink(off_t link) const; inline bool IsValidLink(off_t link) const;
@@ -119,7 +116,7 @@ enum bplustree_traversing {
}; };
//****************** in-memory structures ******************** // #pragma mark - in-memory structures
template<class T> class Stack; template<class T> class Stack;
class BPlusTree; class BPlusTree;
@@ -134,8 +131,6 @@ struct node_and_key {
}; };
//***** Cache handling *****
class CachedNode { class CachedNode {
public: public:
CachedNode(BPlusTree *tree) CachedNode(BPlusTree *tree)
@@ -159,7 +154,8 @@ class CachedNode {
} }
const bplustree_node *SetTo(off_t offset, bool check = true); const bplustree_node *SetTo(off_t offset, bool check = true);
bplustree_node *SetToWritable(Transaction &transaction, off_t offset, bool check = true); bplustree_node *SetToWritable(Transaction &transaction, off_t offset,
bool check = true);
bplustree_node *MakeWritable(Transaction &transaction); bplustree_node *MakeWritable(Transaction &transaction);
const bplustree_header *SetToHeader(); const bplustree_header *SetToHeader();
bplustree_header *SetToWritableHeader(Transaction &transaction); bplustree_header *SetToWritableHeader(Transaction &transaction);
@@ -169,7 +165,8 @@ class CachedNode {
void Unset(); void Unset();
status_t Free(Transaction &transaction, off_t offset); status_t Free(Transaction &transaction, off_t offset);
status_t Allocate(Transaction &transaction, bplustree_node **node, off_t *offset); status_t Allocate(Transaction &transaction, bplustree_node **node,
off_t *offset);
bool IsWritable() const { return fWritable; } bool IsWritable() const { return fWritable; }
bplustree_node *Node() const { return fNode; } bplustree_node *Node() const { return fNode; }
@@ -185,27 +182,31 @@ class CachedNode {
}; };
//******** B+tree class *********
class BPlusTree { class BPlusTree {
public: public:
BPlusTree(Transaction &transaction, Inode *stream, int32 nodeSize = BPLUSTREE_NODE_SIZE); BPlusTree(Transaction &transaction, Inode *stream,
int32 nodeSize = BPLUSTREE_NODE_SIZE);
BPlusTree(Inode *stream); BPlusTree(Inode *stream);
BPlusTree(); BPlusTree();
~BPlusTree(); ~BPlusTree();
status_t SetTo(Transaction &transaction, Inode *stream, int32 nodeSize = BPLUSTREE_NODE_SIZE); status_t SetTo(Transaction &transaction, Inode *stream,
int32 nodeSize = BPLUSTREE_NODE_SIZE);
status_t SetTo(Inode *stream); status_t SetTo(Inode *stream);
status_t SetStream(Inode *stream); status_t SetStream(Inode *stream);
status_t InitCheck(); status_t InitCheck();
status_t Validate(); status_t Validate();
status_t Remove(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value); status_t Remove(Transaction &transaction, const uint8 *key,
status_t Insert(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value); uint16 keyLength, off_t value);
status_t Insert(Transaction &transaction, const uint8 *key,
uint16 keyLength, off_t value);
status_t Remove(Transaction &transaction, const char *key, off_t value); status_t Remove(Transaction &transaction, const char *key,
status_t Insert(Transaction &transaction, const char *key, off_t value); off_t value);
status_t Insert(Transaction &transaction, const char *key,
off_t value);
status_t Insert(Transaction &transaction, int32 key, off_t value); status_t Insert(Transaction &transaction, int32 key, off_t value);
status_t Insert(Transaction &transaction, uint32 key, off_t value); status_t Insert(Transaction &transaction, uint32 key, off_t value);
status_t Insert(Transaction &transaction, int64 key, off_t value); status_t Insert(Transaction &transaction, int64 key, off_t value);
@@ -213,7 +214,8 @@ class BPlusTree {
status_t Insert(Transaction &transaction, float key, off_t value); status_t Insert(Transaction &transaction, float key, off_t value);
status_t Insert(Transaction &transaction, double key, off_t value); status_t Insert(Transaction &transaction, double key, off_t value);
status_t Replace(Transaction &transaction, const uint8 *key, uint16 keyLength, off_t value); status_t Replace(Transaction &transaction, const uint8 *key,
uint16 keyLength, off_t value);
status_t Find(const uint8 *key, uint16 keyLength, off_t *value); status_t Find(const uint8 *key, uint16 keyLength, off_t *value);
static int32 TypeCodeToKeyType(type_code code); static int32 TypeCodeToKeyType(type_code code);
@@ -224,30 +226,37 @@ class BPlusTree {
BPlusTree &operator=(const BPlusTree &); BPlusTree &operator=(const BPlusTree &);
// no implementation // no implementation
int32 CompareKeys(const void *key1, int keylength1, const void *key2, int keylength2); int32 _CompareKeys(const void *key1, int keylength1,
status_t FindKey(const bplustree_node *node, const uint8 *key, uint16 keyLength, const void *key2, int keylength2);
uint16 *index = NULL, off_t *next = NULL); status_t _FindKey(const bplustree_node *node, const uint8 *key,
status_t SeekDown(Stack<node_and_key> &stack, const uint8 *key, uint16 keyLength); uint16 keyLength, uint16 *index = NULL,
off_t *next = NULL);
status_t _SeekDown(Stack<node_and_key> &stack, const uint8 *key,
uint16 keyLength);
status_t FindFreeDuplicateFragment(Transaction &transaction, status_t _FindFreeDuplicateFragment(Transaction &transaction,
const bplustree_node *node, CachedNode &cached, const bplustree_node *node, CachedNode &cached,
off_t *_offset, bplustree_node **_fragment, uint32 *_index); off_t *_offset, bplustree_node **_fragment,
status_t InsertDuplicate(Transaction &transaction, CachedNode &cached, uint32 *_index);
const bplustree_node *node, uint16 index, off_t value); status_t _InsertDuplicate(Transaction &transaction,
void InsertKey(bplustree_node *node, uint16 index, uint8 *key, uint16 keyLength, CachedNode &cached, const bplustree_node *node,
off_t value); uint16 index, off_t value);
status_t SplitNode(bplustree_node *node, off_t nodeOffset, bplustree_node *other, void _InsertKey(bplustree_node *node, uint16 index, uint8 *key,
off_t otherOffset, uint16 *_keyIndex, uint8 *key, uint16 *_keyLength, uint16 keyLength, off_t value);
status_t _SplitNode(bplustree_node *node, off_t nodeOffset,
bplustree_node *other, off_t otherOffset,
uint16 *_keyIndex, uint8 *key, uint16 *_keyLength,
off_t *_value); off_t *_value);
status_t RemoveDuplicate(Transaction &transaction, const bplustree_node *node, status_t _RemoveDuplicate(Transaction &transaction,
CachedNode &cached, uint16 keyIndex, off_t value); const bplustree_node *node, CachedNode &cached,
void RemoveKey(bplustree_node *node, uint16 index); uint16 keyIndex, off_t value);
void _RemoveKey(bplustree_node *node, uint16 index);
void UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex, void _UpdateIterators(off_t offset, off_t nextOffset,
uint16 splitAt, int8 change); uint16 keyIndex, uint16 splitAt, int8 change);
void AddIterator(TreeIterator *iterator); void _AddIterator(TreeIterator *iterator);
void RemoveIterator(TreeIterator *iterator); void _RemoveIterator(TreeIterator *iterator);
private: private:
friend class TreeIterator; friend class TreeIterator;
@@ -264,7 +273,7 @@ class BPlusTree {
}; };
//***** helper classes/functions ***** // #pragma mark - helper classes/functions
extern int32 compareKeys(type_code type, const void *key1, int keyLength1, extern int32 compareKeys(type_code type, const void *key1, int keyLength1,
const void *key2, int keyLength2); const void *key2, int keyLength2);
@@ -275,15 +284,17 @@ class TreeIterator {
~TreeIterator(); ~TreeIterator();
status_t Goto(int8 to); status_t Goto(int8 to);
status_t Traverse(int8 direction, void *key, uint16 *keyLength, uint16 maxLength, status_t Traverse(int8 direction, void *key, uint16 *keyLength,
off_t *value, uint16 *duplicate = NULL); uint16 maxLength, off_t *value,
uint16 *duplicate = NULL);
status_t Find(const uint8 *key, uint16 keyLength); status_t Find(const uint8 *key, uint16 keyLength);
status_t Rewind(); status_t Rewind();
status_t GetNextEntry(void *key, uint16 *keyLength, uint16 maxLength, status_t GetNextEntry(void *key, uint16 *keyLength, uint16 maxLength,
off_t *value, uint16 *duplicate = NULL); off_t *value, uint16 *duplicate = NULL);
status_t GetPreviousEntry(void *key, uint16 *keyLength, uint16 maxLength, status_t GetPreviousEntry(void *key, uint16 *keyLength,
off_t *value, uint16 *duplicate = NULL); uint16 maxLength, off_t *value,
uint16 *duplicate = NULL);
void SkipDuplicates(); void SkipDuplicates();
#ifdef DEBUG #ifdef DEBUG
@@ -303,12 +314,16 @@ class TreeIterator {
friend class Chain<TreeIterator>; friend class Chain<TreeIterator>;
friend class BPlusTree; friend class BPlusTree;
void Update(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 splitAt, int8 change); void Update(off_t offset, off_t nextOffset, uint16 keyIndex,
uint16 splitAt, int8 change);
void Stop(); void Stop();
TreeIterator *fNext; TreeIterator *fNext;
}; };
// BPlusTree's inline functions (most of them may not be needed)
// #pragma mark - BPlusTree's inline functions
// (most of them may not be needed)
inline status_t inline status_t
BPlusTree::Remove(Transaction &transaction, const char *key, off_t value) BPlusTree::Remove(Transaction &transaction, const char *key, off_t value)
@@ -375,8 +390,8 @@ BPlusTree::Insert(Transaction &transaction, double key, off_t value)
} }
/************************ TreeIterator inline functions ************************/ // #pragma mark - TreeIterator inline functions
// #pragma mark -
inline status_t inline status_t
TreeIterator::Rewind() TreeIterator::Rewind()
@@ -398,8 +413,8 @@ TreeIterator::GetPreviousEntry(void *key, uint16 *keyLength, uint16 maxLength,
return Traverse(BPLUSTREE_BACKWARD, key, keyLength, maxLength, value, duplicate); return Traverse(BPLUSTREE_BACKWARD, key, keyLength, maxLength, value, duplicate);
} }
/************************ bplustree_header inline functions ************************/
// #pragma mark - // #pragma mark - bplustree_header inline functions
inline bool inline bool
@@ -420,14 +435,14 @@ bplustree_header::IsValidLink(off_t link) const
} }
/************************ bplustree_node inline functions ************************/ // #pragma mark - bplustree_node inline functions
// #pragma mark -
inline uint16 * inline uint16 *
bplustree_node::KeyLengths() const bplustree_node::KeyLengths() const
{ {
return (uint16 *)(((char *)this) + round_up(sizeof(bplustree_node) + AllKeyLength())); return (uint16 *)(((char *)this) + round_up(sizeof(bplustree_node)
+ AllKeyLength()));
} }
@@ -448,7 +463,8 @@ bplustree_node::Keys() const
inline int32 inline int32
bplustree_node::Used() const bplustree_node::Used() const
{ {
return round_up(sizeof(bplustree_node) + AllKeyLength()) + NumKeys() * (sizeof(uint16) + sizeof(off_t)); return round_up(sizeof(bplustree_node) + AllKeyLength()) + NumKeys()
* (sizeof(uint16) + sizeof(off_t));
} }
@@ -462,7 +478,8 @@ bplustree_node::IsLeaf() const
inline duplicate_array * inline duplicate_array *
bplustree_node::FragmentAt(int8 index) const bplustree_node::FragmentAt(int8 index) const
{ {
return (duplicate_array *)((off_t *)this + index * (NUM_FRAGMENT_VALUES + 1)); return (duplicate_array *)((off_t *)this
+ index * (NUM_FRAGMENT_VALUES + 1));
} }
@@ -483,14 +500,16 @@ bplustree_node::LinkType(off_t link)
inline off_t inline off_t
bplustree_node::MakeLink(uint8 type, off_t link, uint32 fragmentIndex) bplustree_node::MakeLink(uint8 type, off_t link, uint32 fragmentIndex)
{ {
return ((off_t)type << 62) | (link & 0x3ffffffffffffc00LL) | (fragmentIndex & 0x3ff); return ((off_t)type << 62) | (link & 0x3ffffffffffffc00LL)
| (fragmentIndex & 0x3ff);
} }
inline bool inline bool
bplustree_node::IsDuplicate(off_t link) bplustree_node::IsDuplicate(off_t link)
{ {
return (LinkType(link) & (BPLUSTREE_DUPLICATE_NODE | BPLUSTREE_DUPLICATE_FRAGMENT)) > 0; return (LinkType(link)
& (BPLUSTREE_DUPLICATE_NODE | BPLUSTREE_DUPLICATE_FRAGMENT)) > 0;
} }
@@ -514,4 +533,4 @@ bplustree_node::MaxFragments(uint32 nodeSize)
return nodeSize / ((NUM_FRAGMENT_VALUES + 1) * sizeof(off_t)); return nodeSize / ((NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
} }
#endif /* B_PLUS_TREE_H */ #endif // B_PLUS_TREE_H
@@ -15,10 +15,6 @@
#include "system_dependencies.h" #include "system_dependencies.h"
#ifdef USER
# define spawn_kernel_thread spawn_thread
#endif
// Things the BlockAllocator should do: // Things the BlockAllocator should do:
+6 -14
View File
@@ -1,6 +1,5 @@
/* Debug - debug stuff /*
* * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de.
* Some code is based on work previously done by Marcus Overhagen. * Some code is based on work previously done by Marcus Overhagen.
* *
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
@@ -242,13 +241,11 @@ dump_bplustree_node(const bplustree_node *node, const bplustree_header *header,
// #pragma mark - // #pragma mark -
#ifndef USER
static int static int
dbg_inode(int argc, char **argv) debug_inode(int argc, char **argv)
{ {
if (argc < 2) { if (argc < 2) {
kprintf("usage: bfsinode ptr-to-inode\n"); kprintf("usage: bfsinode <ptr-to-inode>\n");
return 0; return 0;
} }
@@ -258,22 +255,17 @@ dbg_inode(int argc, char **argv)
return B_OK; return B_OK;
} }
#endif
void void
remove_debugger_commands() remove_debugger_commands()
{ {
#ifndef USER remove_debugger_command("bfsinode", debug_inode);
remove_debugger_command("bfsinode", dbg_inode);
#endif
} }
void void
add_debugger_commands() add_debugger_commands()
{ {
#ifndef USER add_debugger_command("bfsinode", debug_inode, "dump an Inode object");
add_debugger_command("bfsinode", dbg_inode, "dump an Inode object");
#endif
} }
@@ -16,12 +16,10 @@
// Configure here if and when real benaphores should be used // Configure here if and when real benaphores should be used
#define USE_BENAPHORE #define USE_BENAPHORE
// if defined, benaphores are used for the Semaphore/RecursiveLock classes // if defined, benaphores are used for the Semaphore/RecursiveLock classes
#ifdef USER
//# define FAST_LOCK //# define FAST_LOCK
// the ReadWriteLock class uses a second Semaphore to // the ReadWriteLock class uses a second Semaphore to
// speed up locking - only makes sense if USE_BENAPHORE // speed up locking - only makes sense if USE_BENAPHORE
// is defined, too. // is defined, too.
#endif
#ifdef FAST_LOCK #ifdef FAST_LOCK
# error implement recursive write locking first # error implement recursive write locking first
#endif #endif
@@ -37,9 +35,6 @@ class Semaphore {
fSemaphore(create_sem(1, name)) fSemaphore(create_sem(1, name))
#endif #endif
{ {
#ifndef USER
set_sem_owner(fSemaphore, B_SYSTEM_TEAM);
#endif
} }
~Semaphore() ~Semaphore()
@@ -126,9 +121,6 @@ class RecursiveLock {
#endif #endif
fOwner(-1) fOwner(-1)
{ {
#ifndef USER
set_sem_owner(fSemaphore, B_SYSTEM_TEAM);
#endif
} }
status_t LockWithTimeout(bigtime_t timeout) status_t LockWithTimeout(bigtime_t timeout)
@@ -276,9 +268,6 @@ class ReadWriteLock {
{ {
fSemaphore = create_sem(0, name); fSemaphore = create_sem(0, name);
fCount = MAX_READERS; fCount = MAX_READERS;
#ifndef USER
set_sem_owner(fSemaphore, B_SYSTEM_TEAM);
#endif
return fSemaphore; return fSemaphore;
} }
@@ -360,9 +349,6 @@ class ReadWriteLock {
status_t Initialize(const char *name = "bfs r/w lock") status_t Initialize(const char *name = "bfs r/w lock")
{ {
fSemaphore = create_sem(MAX_READERS, name); fSemaphore = create_sem(MAX_READERS, name);
#ifndef USER
set_sem_owner(fSemaphore, B_SYSTEM_TEAM);
#endif
return fSemaphore; return fSemaphore;
} }
@@ -273,9 +273,7 @@ Volume::Panic()
{ {
FATAL(("we have to panic... switch to read-only mode!\n")); FATAL(("we have to panic... switch to read-only mode!\n"));
fFlags |= VOLUME_READ_ONLY; fFlags |= VOLUME_READ_ONLY;
#ifdef USER #ifdef DEBUG
debugger("BFS panics!");
#elif defined(DEBUG)
kernel_debugger("BFS panics!"); kernel_debugger("BFS panics!");
#endif #endif
} }