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
{
33 // #pragma mark - in-memory structures
36 template<class T
> class Stack
;
40 // needed for searching (utilizing a stack)
53 BTree(Volume
* volume
);
55 btrfs_stream
* stream
);
60 status_t
FindExact(Path
* path
, btrfs_key
& key
,
61 void** _value
, uint32
* _size
= NULL
,
62 uint32
* _offset
= NULL
) const;
63 status_t
FindNext(Path
* path
, btrfs_key
& key
,
64 void** _value
, uint32
* _size
= NULL
,
65 uint32
* _offset
= NULL
) const;
66 status_t
FindPrevious(Path
* path
, btrfs_key
& key
,
67 void** _value
, uint32
* _size
= NULL
,
68 uint32
* _offset
= NULL
) const;
70 status_t
Traverse(btree_traversing type
, Path
* path
,
71 const btrfs_key
& key
) const;
73 status_t
PreviousLeaf(Path
* path
) const;
74 status_t
NextLeaf(Path
* path
) const;
75 status_t
MakeEntries(Transaction
& transaction
,
76 Path
* path
, const btrfs_key
& startKey
,
78 status_t
InsertEntries(Transaction
& transaction
,
79 Path
* path
, btrfs_entry
* entries
,
80 void** data
, int num
);
81 status_t
RemoveEntries(Transaction
& transaction
,
82 Path
* path
, const btrfs_key
& startKey
,
83 void** _data
, int num
);
85 Volume
* SystemVolume() const { return fVolume
; }
86 status_t
SetRoot(off_t logical
, fsblock_t
* block
);
87 void SetRoot(Node
* root
);
88 fsblock_t
RootBlock() const { return fRootBlock
; }
89 off_t
LogicalRoot() const { return fLogicalRoot
; }
90 uint8
RootLevel() const { return fRootLevel
; }
93 BTree(const BTree
& other
);
94 BTree
& operator=(const BTree
& other
);
97 status_t
_Find(Path
* path
, btrfs_key
& key
,
98 void** _value
, uint32
* _size
,
99 uint32
* _offset
, btree_traversing type
)
101 void _AddIterator(TreeIterator
* iterator
);
102 void _RemoveIterator(TreeIterator
* iterator
);
104 friend class TreeIterator
;
106 fsblock_t fRootBlock
;
111 SinglyLinkedList
<TreeIterator
> fIterators
;
116 Node(Volume
* volume
);
117 Node(Volume
* volume
, off_t block
);
120 // just return from Header
121 uint64
LogicalAddress() const
122 { return fNode
->header
.LogicalAddress(); }
124 { return fNode
->header
.Flags(); }
125 uint64
Generation() const
126 { return fNode
->header
.Generation(); }
128 { return fNode
->header
.Owner(); }
129 uint32
ItemCount() const
130 { return fNode
->header
.ItemCount(); }
132 { return fNode
->header
.Level(); }
133 void SetLogicalAddress(uint64 address
)
134 { fNode
->header
.SetLogicalAddress(address
); }
135 void SetGeneration(uint64 generation
)
136 { fNode
->header
.SetGeneration(generation
); }
137 void SetItemCount(uint32 itemCount
)
138 { fNode
->header
.SetItemCount(itemCount
); }
140 btrfs_index
* Index(uint32 i
) const
141 { return &fNode
->index
[i
]; }
143 btrfs_entry
* Item(uint32 i
) const
144 { return &fNode
->entries
[i
]; }
145 uint8
* ItemData(uint32 i
) const
146 { return (uint8
*)Item(0) + Item(i
)->Offset(); }
151 void SetTo(off_t block
);
152 void SetToWritable(off_t block
, int32 transactionId
, bool empty
);
153 int SpaceUsed() const;
154 int SpaceLeft() const;
156 off_t
BlockNum() const { return fBlockNumber
;}
157 bool IsWritable() const { return fWritable
; }
158 status_t
Copy(const Node
* origin
, uint32 start
, uint32 end
,
160 status_t
MoveEntries(uint32 start
, uint32 end
, int length
) const;
162 status_t
SearchSlot(const btrfs_key
& key
, int* slot
,
163 btree_traversing type
) const;
166 Node
& operator=(const Node
&);
169 void _Copy(const Node
* origin
, uint32 at
, uint32 from
, uint32 to
,
171 status_t
_SpaceCheck(int length
) const;
172 int _CalculateSpace(uint32 from
, uint32 to
, uint8 type
= 1) const;
186 Node
* GetNode(int level
, int* _slot
= NULL
) const;
187 Node
* SetNode(off_t block
, int slot
);
188 Node
* SetNode(const Node
* node
, int slot
);
189 status_t
GetCurrentEntry(btrfs_key
* _key
, void** _value
,
190 uint32
* _size
= NULL
, uint32
* _offset
= NULL
);
191 status_t
GetEntry(int slot
, btrfs_key
* _key
, void** _value
,
192 uint32
* _size
= NULL
, uint32
* _offset
= NULL
);
193 status_t
SetEntry(int slot
, const btrfs_entry
& entry
, void* value
);
195 int Move(int level
, int step
);
197 status_t
CopyOnWrite(Transaction
& transaction
, int level
,
198 uint32 start
, int num
, int length
);
199 status_t
InternalCopy(Transaction
& transaction
, int level
);
201 BTree
* Tree() const { return fTree
; }
204 Path
operator=(const Path
&);
206 Node
* fNodes
[BTRFS_MAX_TREE_DEPTH
];
207 int fSlots
[BTRFS_MAX_TREE_DEPTH
];
214 class TreeIterator
: public SinglyLinkedListLinkImpl
<TreeIterator
> {
216 TreeIterator(BTree
* tree
, const btrfs_key
& key
);
219 void Rewind(bool inverse
= false);
220 status_t
Find(const btrfs_key
& key
);
221 status_t
GetNextEntry(void** _value
,
222 uint32
* _size
= NULL
,
223 uint32
* _offset
= NULL
);
224 status_t
GetPreviousEntry(void** _value
,
225 uint32
* _size
= NULL
,
226 uint32
* _offset
= NULL
);
228 BTree
* Tree() const { return fTree
; }
229 btrfs_key
Key() const { return fKey
; }
234 status_t
_Traverse(btree_traversing direction
);
235 status_t
_Find(btree_traversing type
, btrfs_key
& key
,
237 status_t
_GetEntry(btree_traversing type
, void** _value
,
238 uint32
* _size
, uint32
* _offset
);
246 status_t fIteratorStatus
;
250 // #pragma mark - BTree::Path inline functions
254 BTree::Path::GetCurrentEntry(btrfs_key
* _key
, void** _value
, uint32
* _size
,
257 return GetEntry(fSlots
[0], _key
, _value
, _size
, _offset
);
261 // #pragma mark - TreeIterator inline functions
265 TreeIterator::GetNextEntry(void** _value
, uint32
* _size
, uint32
* _offset
)
267 return _GetEntry(BTREE_FORWARD
, _value
, _size
, _offset
);
272 TreeIterator::GetPreviousEntry(void** _value
, uint32
* _size
, uint32
* _offset
)
274 return _GetEntry(BTREE_BACKWARD
, _value
, _size
, _offset
);