* BPlusTree is now using the TransactionListener mechanism to update its private

fHeader copy on failure.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35492 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2010-02-16 12:23:43 +00:00
parent fd91cf4d18
commit f7f996cc32
2 changed files with 48 additions and 3 deletions

View File

@ -198,6 +198,17 @@ CachedNode::SetToWritableHeader(Transaction& transaction)
Unset(); Unset();
InternalSetTo(&transaction, 0LL); InternalSetTo(&transaction, 0LL);
if (fNode != NULL && !fTree->fInTransaction) {
transaction.AddListener(fTree);
fTree->fInTransaction = true;
if (!transaction.GetVolume()->IsInitializing()) {
acquire_vnode(transaction.GetVolume()->FSVolume(),
fTree->fStream->ID());
}
}
return (bplustree_header*)fNode; return (bplustree_header*)fNode;
} }
@ -343,7 +354,8 @@ CachedNode::Allocate(Transaction& transaction, bplustree_node** _node,
BPlusTree::BPlusTree(Transaction& transaction, Inode* stream, int32 nodeSize) BPlusTree::BPlusTree(Transaction& transaction, Inode* stream, int32 nodeSize)
: :
fStream(NULL) fStream(NULL),
fInTransaction(false)
{ {
mutex_init(&fIteratorLock, "bfs b+tree iterator"); mutex_init(&fIteratorLock, "bfs b+tree iterator");
SetTo(transaction, stream); SetTo(transaction, stream);
@ -352,7 +364,8 @@ BPlusTree::BPlusTree(Transaction& transaction, Inode* stream, int32 nodeSize)
BPlusTree::BPlusTree(Inode* stream) BPlusTree::BPlusTree(Inode* stream)
: :
fStream(NULL) fStream(NULL),
fInTransaction(false)
{ {
mutex_init(&fIteratorLock, "bfs b+tree iterator"); mutex_init(&fIteratorLock, "bfs b+tree iterator");
SetTo(stream); SetTo(stream);
@ -364,6 +377,7 @@ BPlusTree::BPlusTree()
fStream(NULL), fStream(NULL),
fNodeSize(BPLUSTREE_NODE_SIZE), fNodeSize(BPLUSTREE_NODE_SIZE),
fAllowDuplicates(true), fAllowDuplicates(true),
fInTransaction(false),
fStatus(B_NO_INIT) fStatus(B_NO_INIT)
{ {
mutex_init(&fIteratorLock, "bfs b+tree iterator"); mutex_init(&fIteratorLock, "bfs b+tree iterator");
@ -559,6 +573,32 @@ BPlusTree::ModeToKeyType(mode_t mode)
} }
// #pragma mark - TransactionListener implementation
void
BPlusTree::TransactionDone(bool success)
{
if (!success) {
// update header from disk
CachedNode cached(this);
const bplustree_header* header = cached.SetToHeader();
if (header != NULL)
memcpy(&fHeader, header, sizeof(bplustree_header));
}
}
void
BPlusTree::RemovedFromTransaction()
{
fInTransaction = false;
if (!fStream->GetVolume()->IsInitializing())
put_vnode(fStream->GetVolume()->FSVolume(), fStream->ID());
}
// #pragma mark - // #pragma mark -

View File

@ -196,7 +196,7 @@ protected:
}; };
class BPlusTree { class BPlusTree : public TransactionListener {
public: public:
BPlusTree(Transaction& transaction, BPlusTree(Transaction& transaction,
Inode* stream, Inode* stream,
@ -246,6 +246,10 @@ public:
static int32 TypeCodeToKeyType(type_code code); static int32 TypeCodeToKeyType(type_code code);
static int32 ModeToKeyType(mode_t mode); static int32 ModeToKeyType(mode_t mode);
protected:
virtual void TransactionDone(bool success);
virtual void RemovedFromTransaction();
private: private:
BPlusTree(const BPlusTree& other); BPlusTree(const BPlusTree& other);
BPlusTree& operator=(const BPlusTree& other); BPlusTree& operator=(const BPlusTree& other);
@ -296,6 +300,7 @@ private:
bplustree_header fHeader; bplustree_header fHeader;
int32 fNodeSize; int32 fNodeSize;
bool fAllowDuplicates; bool fAllowDuplicates;
bool fInTransaction;
status_t fStatus; status_t fStatus;
mutex fIteratorLock; mutex fIteratorLock;
SinglyLinkedList<TreeIterator> fIterators; SinglyLinkedList<TreeIterator> fIterators;