2 // lf_hfs_btrees_private.h
5 // Created by Yakov Ben Zaken on 22/03/2018.
8 #ifndef lf_hfs_btrees_private_h
9 #define lf_hfs_btrees_private_h
11 #include "lf_hfs_defs.h"
12 #include "lf_hfs_file_mgr_internal.h"
13 #include "lf_hfs_btrees_internal.h"
14 #include "lf_hfs_logger.h"
16 /////////////////////////////////// Constants ///////////////////////////////////
18 #define kBTreeVersion 1
19 #define kMaxTreeDepth 16
22 #define kHeaderNodeNum 0
23 #define kKeyDescRecord 1
26 // Header Node Record Offsets
28 kHeaderRecOffset
= 0x000E,
29 kKeyDescRecOffset
= 0x0078,
30 kHeaderMapRecOffset
= 0x00F8
33 #define kMinNodeSize (512)
35 #define kMinRecordSize (6)
36 // where is minimum record size enforced?
38 // miscellaneous BTree constants
49 // illegal string attribute bits set in mask
50 #define kBadStrAttribMask (0xCF)
54 //////////////////////////////////// Macros /////////////////////////////////////
56 #define M_NodesInMap(mapSize) ((mapSize) << 3)
58 #define M_ClearBitNum(integer,bitNumber) ((integer) &= (~(1<<(bitNumber))))
59 #define M_SetBitNum(integer,bitNumber) ((integer) |= (1<<(bitNumber)))
60 #define M_IsOdd(integer) (((integer) & 1) != 0)
61 #define M_IsEven(integer) (((integer) & 1) == 0)
63 #define M_MapRecordSize(nodeSize) (nodeSize - sizeof (BTNodeDescriptor) - 6)
64 #define M_HeaderMapRecordSize(nodeSize) (nodeSize - sizeof(BTNodeDescriptor) - sizeof(BTHeaderRec) - 128 - 8)
66 #define M_SWAP_BE16_ClearBitNum(integer,bitNumber) ((integer) &= SWAP_BE16(~(1<<(bitNumber))))
67 #define M_SWAP_BE16_SetBitNum(integer,bitNumber) ((integer) |= SWAP_BE16(1<<(bitNumber)))
69 ///////////////////////////////////// Types /////////////////////////////////////
71 typedef struct { // fields specific to BTree CBs
73 u_int8_t keyCompareType
; /* Key string Comparison Type */
76 FileReference fileRefNum
; // refNum of btree file
77 KeyCompareProcPtr keyCompareProc
;
79 u_int32_t leafRecords
;
80 u_int32_t firstLeafNode
;
81 u_int32_t lastLeafNode
;
83 u_int16_t maxKeyLength
;
87 u_int16_t reserved3
; // 4-byte alignment
91 u_int32_t flags
; // dynamic flags
92 u_int32_t attributes
; // persistent flags
94 u_int32_t lastfsync
; /* Last time that this was fsynced */
96 GetBlockProcPtr getBlockProc
;
97 ReleaseBlockProcPtr releaseBlockProc
;
98 SetEndOfForkProcPtr setEndOfForkProc
;
100 // statistical information
101 u_int32_t numGetNodes
;
102 u_int32_t numGetNewNodes
;
103 u_int32_t numReleaseNodes
;
104 u_int32_t numUpdateNodes
;
105 u_int32_t numMapNodesRead
; // map nodes beyond header node
106 u_int32_t numHintChecks
;
107 u_int32_t numPossibleHints
; // Looks like a formated hint
108 u_int32_t numValidHints
; // Hint used to find correct record.
109 u_int32_t reservedNodes
;
110 BTreeIterator iterator
; // useable when holding exclusive b-tree lock
113 void *madeDirtyBy
[2];
116 } BTreeControlBlock
, *BTreeControlBlockPtr
;
118 u_int32_t
CalcKeySize(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
119 #define CalcKeySize(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? ((key)->length16 + 2) : ((key)->length8 + 1) )
121 u_int32_t
KeyLength(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
122 #define KeyLength(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? (key)->length16 : (key)->length8 )
126 kBTHeaderDirty
= 0x00000001
129 static inline void M_BTreeHeaderDirty(BTreeControlBlock
*bt
) {
131 bt
->madeDirtyBy
[0] = __builtin_return_address(0);
132 bt
->madeDirtyBy
[1] = __builtin_return_address(1);
134 bt
->flags
|= kBTHeaderDirty
;
137 typedef int8_t *NodeBuffer
;
138 typedef BlockDescriptor NodeRec
, *NodePtr
; //remove this someday...
141 //// Tree Path Table - constructed by SearchTree, used by InsertTree and DeleteTree
144 u_int32_t node
; // node number
146 u_int16_t reserved
; // align size to a power of 2
148 } TreePathRecord
, *TreePathRecordPtr
;
150 typedef TreePathRecord TreePathTable
[kMaxTreeDepth
];
153 //// InsertKey - used by InsertTree, InsertLevel and InsertNode
160 Boolean replacingKey
;
164 //// For Notational Convenience
166 typedef BTNodeDescriptor
* NodeDescPtr
;
167 typedef u_int8_t
*RecordPtr
;
168 typedef BTreeKeyPtr KeyPtr
;
171 //////////////////////////////////// Globals ////////////////////////////////////
174 //////////////////////////////////// Macros /////////////////////////////////////
175 // Exit function on error
176 #define M_ExitOnError( result ) do { if ( ( result ) != noErr ) goto ErrorExit; } while(0)
178 // Test for passed condition and return if true
179 #define M_ReturnErrorIf( condition, error ) do { if ( condition ) return( error ); } while(0)
181 //////////////////////////////// Key Operations /////////////////////////////////
183 int32_t CompareKeys (BTreeControlBlockPtr btreePtr
,
187 //////////////////////////////// Map Operations /////////////////////////////////
189 OSStatus
AllocateNode (BTreeControlBlockPtr btreePtr
,
192 OSStatus
FreeNode (BTreeControlBlockPtr btreePtr
,
195 OSStatus
ExtendBTree (BTreeControlBlockPtr btreePtr
,
198 u_int32_t
CalcMapBits (BTreeControlBlockPtr btreePtr
);
201 void BTUpdateReserve (BTreeControlBlockPtr btreePtr
,
204 //////////////////////////////// Misc Operations ////////////////////////////////
206 u_int16_t
CalcKeyRecordSize (u_int16_t keySize
,
209 OSStatus
VerifyHeader (FCB
*filePtr
,
210 BTHeaderRec
*header
);
212 OSStatus
UpdateHeader (BTreeControlBlockPtr btreePtr
,
213 Boolean forceWrite
);
215 OSStatus
FindIteratorPosition (BTreeControlBlockPtr btreePtr
,
216 BTreeIteratorPtr iterator
,
217 BlockDescriptor
*left
,
218 BlockDescriptor
*middle
,
219 BlockDescriptor
*right
,
222 Boolean
*foundRecord
);
224 OSStatus
CheckInsertParams (FCB
*filePtr
,
225 BTreeIterator
*iterator
,
226 FSBufferDescriptor
*record
,
227 u_int16_t recordLen
);
229 OSStatus
TrySimpleReplace (BTreeControlBlockPtr btreePtr
,
231 BTreeIterator
*iterator
,
232 FSBufferDescriptor
*record
,
234 Boolean
*recordInserted
);
236 OSStatus
IsItAHint (BTreeControlBlockPtr btreePtr
,
237 BTreeIterator
*iterator
,
240 OSStatus
TreeIsDirty (BTreeControlBlockPtr btreePtr
);
242 //////////////////////////////// Node Operations ////////////////////////////////
246 OSStatus
GetNode (BTreeControlBlockPtr btreePtr
,
249 NodeRec
*returnNodePtr
);
251 /* Flags for GetNode() */
252 #define kGetNodeHint 0x1 /* If set, the node is being looked up using a hint */
254 OSStatus
GetLeftSiblingNode (BTreeControlBlockPtr btreePtr
,
258 #define GetLeftSiblingNode(btree,node,left) GetNode ((btree), ((NodeDescPtr)(node))->bLink, 0, (left))
260 OSStatus
GetRightSiblingNode (BTreeControlBlockPtr btreePtr
,
264 #define GetRightSiblingNode(btree,node,right) GetNode ((btree), ((NodeDescPtr)(node))->fLink, 0, (right))
267 OSStatus
GetNewNode (BTreeControlBlockPtr btreePtr
,
269 NodeRec
*returnNodePtr
);
271 OSStatus
ReleaseNode (BTreeControlBlockPtr btreePtr
,
274 OSStatus
TrashNode (BTreeControlBlockPtr btreePtr
,
277 OSStatus
UpdateNode (BTreeControlBlockPtr btreePtr
,
279 u_int32_t transactionID
,
282 //// Node Buffer Operations
284 void ClearNode (BTreeControlBlockPtr btreePtr
,
287 u_int16_t
GetNodeDataSize (BTreeControlBlockPtr btreePtr
,
290 u_int16_t
GetNodeFreeSize (BTreeControlBlockPtr btreePtr
,
294 //// Record Operations
296 Boolean
InsertRecord (BTreeControlBlockPtr btreePtr
,
302 Boolean
InsertKeyRecord (BTreeControlBlockPtr btreePtr
,
310 void DeleteRecord (BTreeControlBlockPtr btree
,
315 Boolean
SearchNode (BTreeControlBlockPtr btree
,
320 OSStatus
GetRecordByIndex (BTreeControlBlockPtr btree
,
325 u_int16_t
*dataSize
);
327 u_int8_t
* GetRecordAddress (BTreeControlBlockPtr btree
,
331 #define GetRecordAddress(btreePtr,node,index) ((u_int8_t *)(node) + (*(short *) ((u_int8_t *)(node) + (btreePtr)->nodeSize - ((index) << 1) - kOffsetSize)))
334 u_int16_t
GetRecordSize (BTreeControlBlockPtr btree
,
338 u_int32_t
GetChildNodeNum (BTreeControlBlockPtr btreePtr
,
342 void MoveRecordsLeft (u_int8_t
* src
,
344 u_int16_t bytesToMove
);
346 #define MoveRecordsLeft(src,dst,bytes) bcopy((src),(dst),(bytes))
348 void MoveRecordsRight (u_int8_t
* src
,
350 u_int16_t bytesToMove
);
352 #define MoveRecordsRight(src,dst,bytes) bcopy((src),(dst),(bytes))
355 //////////////////////////////// Tree Operations ////////////////////////////////
357 OSStatus
SearchTree (BTreeControlBlockPtr btreePtr
,
359 TreePathTable treePathTable
,
361 BlockDescriptor
*nodePtr
,
364 OSStatus
InsertTree (BTreeControlBlockPtr btreePtr
,
365 TreePathTable treePathTable
,
369 BlockDescriptor
*targetNode
,
372 Boolean replacingKey
,
373 u_int32_t
*insertNode
);
375 OSStatus
DeleteTree (BTreeControlBlockPtr btreePtr
,
376 TreePathTable treePathTable
,
377 BlockDescriptor
*targetNode
,
382 #endif /* lf_hfs_btrees_private_h */