2 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
3 * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
4 * This file may be used under the terms of the MIT License.
14 #define BTREE_NULL -1LL
15 #define BTREE_FREE -2LL
17 #define BTRFS_MAX_TREE_DEPTH 8
20 enum btree_traversing
{
30 // #pragma mark - in-memory structures
33 template<class T
> class Stack
;
37 // needed for searching (utilizing a stack)
49 BTree(Volume
* volume
);
51 btrfs_stream
* stream
);
56 status_t
FindExact(Path
* path
, btrfs_key
& key
,
57 void** _value
, uint32
* _size
= NULL
,
58 uint32
* _offset
= NULL
) const;
59 status_t
FindNext(Path
* path
, btrfs_key
& key
,
60 void** _value
, uint32
* _size
= NULL
,
61 uint32
* _offset
= NULL
) const;
62 status_t
FindPrevious(Path
* path
, btrfs_key
& key
,
63 void** _value
, uint32
* _size
= NULL
,
64 uint32
* _offset
= NULL
) const;
66 status_t
Traverse(btree_traversing type
, Path
* path
,
67 const btrfs_key
& key
) const;
69 status_t
PreviousLeaf(Path
* path
) const;
70 status_t
NextLeaf(Path
* path
) const;
72 Volume
* SystemVolume() const { return fVolume
; }
73 status_t
SetRoot(off_t logical
, fsblock_t
* block
);
74 fsblock_t
RootBlock() const { return fRootBlock
; }
75 off_t
LogicalRoot() const { return fLogicalRoot
; }
78 BTree(const BTree
& other
);
79 BTree
& operator=(const BTree
& other
);
82 status_t
_Find(Path
* path
, btrfs_key
& key
,
83 void** _value
, uint32
* _size
,
84 uint32
* _offset
, btree_traversing type
)
86 void _AddIterator(TreeIterator
* iterator
);
87 void _RemoveIterator(TreeIterator
* iterator
);
89 friend class TreeIterator
;
95 SinglyLinkedList
<TreeIterator
> fIterators
;
100 Node(Volume
* volume
);
101 Node(Volume
* volume
, off_t block
);
104 // just return from Header
105 uint64
LogicalAddress() const
106 { return fNode
->header
.LogicalAddress(); }
108 { return fNode
->header
.Flags(); }
109 uint64
Generation() const
110 { return fNode
->header
.Generation(); }
112 { return fNode
->header
.Owner(); }
113 uint32
ItemCount() const
114 { return fNode
->header
.ItemCount(); }
116 { return fNode
->header
.Level(); }
118 btrfs_index
* Index(uint32 i
) const
119 { return &fNode
->index
[i
]; }
121 btrfs_entry
* Item(uint32 i
) const
122 { return &fNode
->entries
[i
]; }
123 uint8
* ItemData(uint32 i
) const
124 { return (uint8
*)Item(0) + Item(i
)->Offset(); }
129 void SetTo(off_t block
);
130 void SetToWritable(off_t block
, int32 transactionId
, bool empty
);
132 off_t
BlockNum() const { return fBlockNumber
;}
133 bool IsWritable() const { return fWritable
; }
135 status_t
SearchSlot(const btrfs_key
& key
, int* slot
,
136 btree_traversing type
) const;
139 Node
& operator=(const Node
&);
154 Node
* GetNode(int level
, int* _slot
= NULL
) const;
155 Node
* SetNode(off_t block
, int slot
);
156 Node
* SetNode(const Node
* node
, int slot
);
157 status_t
GetCurrentEntry(btrfs_key
* _key
, void** _value
,
158 uint32
* _size
= NULL
, uint32
* _offset
= NULL
);
159 status_t
GetEntry(int slot
, btrfs_key
* _key
, void** _value
,
160 uint32
* _size
= NULL
, uint32
* _offset
= NULL
);
162 int Move(int level
, int step
);
164 BTree
* Tree() const { return fTree
; }
167 Path
operator=(const Path
&);
169 Node
* fNodes
[BTRFS_MAX_TREE_DEPTH
];
170 int fSlots
[BTRFS_MAX_TREE_DEPTH
];
177 class TreeIterator
: public SinglyLinkedListLinkImpl
<TreeIterator
> {
179 TreeIterator(BTree
* tree
, btrfs_key
& key
);
182 status_t
Traverse(btree_traversing direction
,
183 btrfs_key
& key
, void** value
,
184 uint32
* size
= NULL
);
185 status_t
Find(btrfs_key
& key
);
188 status_t
GetNextEntry(btrfs_key
& key
, void** value
,
189 uint32
* size
= NULL
);
190 status_t
GetPreviousEntry(btrfs_key
& key
, void** value
,
191 uint32
* size
= NULL
);
193 BTree
* Tree() const { return fTree
; }
203 btrfs_key fCurrentKey
;
207 // #pragma mark - BTree::Path inline functions
211 BTree::Path::GetCurrentEntry(btrfs_key
* _key
, void** _value
, uint32
* _size
,
214 return GetEntry(fSlots
[0], _key
, _value
, _size
, _offset
);
218 // #pragma mark - TreeIterator inline functions
222 TreeIterator::Rewind()
224 fCurrentKey
.SetOffset(BTREE_BEGIN
);
230 TreeIterator::GetNextEntry(btrfs_key
& key
, void** value
, uint32
* size
)
232 return Traverse(BTREE_FORWARD
, key
, value
, size
);
237 TreeIterator::GetPreviousEntry(btrfs_key
& key
, void** value
,
240 return Traverse(BTREE_BACKWARD
, key
, value
, size
);