BTRFS: Fix node search slot

* Not handle traversing type correctly (looks for the graph).
* Reorder the codes because *slot is uninitialized if type is BTREE_EXACT.
* Incorrect return type: int32 -> status_t

Signed-off-by: Augustin Cavalier <[email protected]>
This commit is contained in:
hyche
2017-12-10 10:56:08 -05:00
committed by Augustin Cavalier
parent e715614613
commit 2ed88a489c
2 changed files with 25 additions and 15 deletions
+23 -13
View File
@@ -90,8 +90,9 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
} }
int32 status_t
BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type) const BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type)
const
{ {
//binary search for item slot in a node //binary search for item slot in a node
int entrySize = sizeof(btrfs_entry); int entrySize = sizeof(btrfs_entry);
@@ -100,14 +101,13 @@ BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type)
entrySize = sizeof(btrfs_index); entrySize = sizeof(btrfs_index);
} }
int low = 0;
int high = ItemCount(); int high = ItemCount();
int mid, comp; int low = 0, mid = 0, comp = 0;
int base = sizeof(btrfs_header); uint8* base = (uint8*)fNode + sizeof(btrfs_header);
const btrfs_key* other; const btrfs_key* other;
while (low < high) { while (low < high) {
mid = (low + high) / 2; mid = (low + high) / 2;
other = (const btrfs_key*)((uint8*)fNode + base + mid * entrySize); other = (const btrfs_key*)(base + mid * entrySize);
comp = key.Compare(*other); comp = key.Compare(*other);
if (comp < 0) if (comp < 0)
high = mid; high = mid;
@@ -119,15 +119,25 @@ BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type)
} }
} }
// |--item1--|--item2--|--item3--|--etc--|
// m-1 m m+1
// k : comp < 0
// k : comp > 0
if (type == BTREE_BACKWARD) {
*slot = mid - 1;
if (comp > 0)
*slot = mid;
} else if (type == BTREE_FORWARD) {
*slot = mid;
if (comp > 0)
*slot = mid + 1;
}
if (type == BTREE_EXACT || *slot < 0)
return B_ENTRY_NOT_FOUND;
TRACE("SearchSlot() found slot %" B_PRId32 " comp %" B_PRId32 "\n", TRACE("SearchSlot() found slot %" B_PRId32 " comp %" B_PRId32 "\n",
*slot, comp); *slot, comp);
if (type == BTREE_BACKWARD)
*slot = low - 1;
else if (type == BTREE_FORWARD)
*slot = low;
if (*slot < 0 || type == BTREE_EXACT)
return B_ENTRY_NOT_FOUND;
return B_OK; return B_OK;
} }
@@ -119,8 +119,8 @@ public:
off_t BlockNum() const { return fBlockNumber;} off_t BlockNum() const { return fBlockNumber;}
bool IsWritable() const { return fWritable; } bool IsWritable() const { return fWritable; }
int32 SearchSlot(const btrfs_key& key, int* slot, status_t SearchSlot(const btrfs_key& key, int* slot,
btree_traversing type) const; btree_traversing type) const;
private: private:
Node(const Node&); Node(const Node&);
Node& operator=(const Node&); Node& operator=(const Node&);