2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 Contains: Private interface file for the BTree Module.
33 Version: xxx put the technology version here xxx
35 Written by: Gordon Sheridan and Bill Bruffey
37 Copyright: © 1992-1999 by Apple Computer, Inc., all rights reserved.
43 Other Contact: Mark Day
45 Technology: File Systems
55 Change History (most recent first):
56 <MacOSX> 3/19/99 djb Disable MoveRecordsLeft/Right macros since bcopy is broken.
58 <MacOSX> 8/10/98 djb Removed unused BTreeIterator from BTreeControlBlock, fixed alignment.
60 <CS5> 9/4/97 djb Convert MoveRecordsLeft and GetLeftSiblingNode to macros.
61 <CS4> 7/24/97 djb Add macro for GetRecordAddress (was a function before).
62 <CS3> 7/21/97 msd GetRecordByIndex now returns an OSStatus.
63 <CS2> 7/16/97 DSH FilesInternal.i renamed FileMgrInternal.i to avoid name
65 <CS1> 4/23/97 djb first checked in
67 <HFS6> 3/17/97 DSH Added a refCon field to BTreeControlBlock, for DFA use, to point
68 to additional data. Fixed Panic macros for use with SC.
69 <HFS5> 2/19/97 djb Add InsertKey struct. Moved on-disk definitions to
71 <HFS4> 1/27/97 djb InsertTree and DeleteTree are now recursive and support variable
73 <HFS3> 1/15/97 djb Move GetFileRefNumFromFCB macro to FilesInternal.h. Added
74 kBTVariableIndexKeysMask.
75 <HFS2> 1/3/97 djb Added support for large keys.
76 <HFS1> 12/19/96 djb first checked in
78 History applicable to original Scarecrow Design:
80 <7> 10/25/96 ser Changing for new VFPI
81 <6> 10/18/96 ser Converting over VFPI changes
82 <5> 9/17/96 dkh More BTree statistics
83 <4> 9/16/96 dkh Revised BTree statistics
84 <3> 6/20/96 dkh Radar #1358740. Switch from using Pools to debug MemAllocators.
85 <2> 12/7/95 dkh D10E2 build. Changed usage of Ref data type to LogicalAddress.
86 <1> 10/18/95 rst Moved from Scarecrow project.
88 <19> 11/22/94 djb Add prototype for GetMapNode
89 <18> 11/16/94 prp Add IsItAHint routine prototype.
90 <17> 9/30/94 prp Get in sync with D2 interface changes.
91 <16> 7/25/94 wjk Eliminate usage of BytePtr in favor of UInt8 *.
92 <15> 7/22/94 wjk Convert to the new set of header files.
93 <14> 5/31/94 srs Moved Btree types to public interface
94 <13> 12/9/93 wjk Add 68k alignment pragma's around persistent structures.
95 <12> 11/30/93 wjk Move from Makefiles to BuildFiles. Fit into the ModernOS and
97 <11> 11/23/93 wjk Changes required to compile on the RS6000.
98 <10> 8/30/93 CH Removed the M_ExitOnError and M_ReturnErrorIf macros which were
99 already defined in FileSystemPriv.h (included here).
100 <9> 8/30/93 CH Added parens around the M_ReturnErrorIf macro.
101 <8> 5/21/93 gs Add kBadClose flag. Add some prototypes for internal routines.
102 <7> 5/10/93 gs Change Ptr to BytePtr. Move BTreeTypes to BTree.h. Add
103 DeleteTree prototype.
104 <6> 3/23/93 gs Remove mysterious "flags" field from HeaderRec structure. Move
105 prototypes of private functions to top of respective source
107 <5> 2/8/93 gs Update to use FSAgent.h Get/Release/SetEOF/SetBlockSize
108 procPtrs. Add UpdateNode routine.
109 <4> 12/10/92 gs Add Key Descriptor function declarations.
110 <3> 12/8/92 gs Add HeaderRec structure and incorporate review feedback.
111 <2> 12/2/92 gs Add GetNode and ReleaseNode callback procptrs to BTree CB, and
112 add internal function declarations.
113 <1> 11/15/92 gs first checked in
117 #ifndef __BTREESPRIVATE__
118 #define __BTREESPRIVATE__
120 #include <sys/appleapiopts.h>
123 #ifdef __APPLE_API_PRIVATE
125 #include "../../hfs_macos_defs.h"
127 #ifndef __FILEMGRINTERNAL__
128 #include "FileMgrInternal.h"
131 #ifndef __BTREESINTERNAL__
132 #include "BTreesInternal.h"
136 /////////////////////////////////// Constants ///////////////////////////////////
138 #define kBTreeVersion 1
139 #define kMaxTreeDepth 16
142 #define kHeaderNodeNum 0
143 #define kKeyDescRecord 1
146 // Header Node Record Offsets
148 kHeaderRecOffset
= 0x000E,
149 kKeyDescRecOffset
= 0x0078,
150 kHeaderMapRecOffset
= 0x00F8
153 #define kMinNodeSize 512
155 #define kMinRecordSize 6
156 // where is minimum record size enforced?
158 // miscellaneous BTree constants
169 // illegal string attribute bits set in mask
170 #define kBadStrAttribMask 0xCF
174 //////////////////////////////////// Macros /////////////////////////////////////
176 #define M_NodesInMap(mapSize) ((mapSize) << 3)
178 #define M_ClearBitNum(integer,bitNumber) ((integer) &= (~(1<<(bitNumber))))
179 #define M_SetBitNum(integer,bitNumber) ((integer) |= (1<<(bitNumber)))
180 #define M_IsOdd(integer) (((integer) & 1) != 0)
181 #define M_IsEven(integer) (((integer) & 1) == 0)
182 #define M_BTreeHeaderDirty(btreePtr) btreePtr->flags |= kBTHeaderDirty
184 #define M_MapRecordSize(nodeSize) (nodeSize - sizeof (BTNodeDescriptor) - 6)
185 #define M_HeaderMapRecordSize(nodeSize) (nodeSize - sizeof(BTNodeDescriptor) - sizeof(BTHeaderRec) - 128 - 8)
187 #define M_SWAP_BE16_ClearBitNum(integer,bitNumber) ((integer) &= SWAP_BE16(~(1<<(bitNumber))))
188 #define M_SWAP_BE16_SetBitNum(integer,bitNumber) ((integer) |= SWAP_BE16(1<<(bitNumber)))
190 ///////////////////////////////////// Types /////////////////////////////////////
192 typedef struct BTreeControlBlock
{ // fields specific to BTree CBs
194 u_int8_t keyCompareType
; /* Key string Comparison Type */
197 FileReference fileRefNum
; // refNum of btree file
198 KeyCompareProcPtr keyCompareProc
;
200 u_int32_t leafRecords
;
201 u_int32_t firstLeafNode
;
202 u_int32_t lastLeafNode
;
204 u_int16_t maxKeyLength
;
205 u_int32_t totalNodes
;
208 u_int16_t reserved3
; // 4-byte alignment
212 u_int32_t flags
; // dynamic flags
213 u_int32_t attributes
; // persistent flags
214 u_int32_t writeCount
;
215 u_int32_t lastfsync
; /* Last time that this was fsynced */
217 GetBlockProcPtr getBlockProc
;
218 ReleaseBlockProcPtr releaseBlockProc
;
219 SetEndOfForkProcPtr setEndOfForkProc
;
221 // statistical information
222 u_int32_t numGetNodes
;
223 u_int32_t numGetNewNodes
;
224 u_int32_t numReleaseNodes
;
225 u_int32_t numUpdateNodes
;
226 u_int32_t numMapNodesRead
; // map nodes beyond header node
227 u_int32_t numHintChecks
;
228 u_int32_t numPossibleHints
; // Looks like a formated hint
229 u_int32_t numValidHints
; // Hint used to find correct record.
230 u_int32_t reservedNodes
;
231 BTreeIterator iterator
; // useable when holding exclusive b-tree lock
232 } BTreeControlBlock
, *BTreeControlBlockPtr
;
235 u_int32_t
CalcKeySize(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
236 #define CalcKeySize(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? ((key)->length16 + 2) : ((key)->length8 + 1) )
238 u_int32_t
KeyLength(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
239 #define KeyLength(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? (key)->length16 : (key)->length8 )
244 kBTHeaderDirty
= 0x00000001
248 typedef int8_t *NodeBuffer
;
249 typedef BlockDescriptor NodeRec
, *NodePtr
; //\80\80 remove this someday...
254 //// Tree Path Table - constructed by SearchTree, used by InsertTree and DeleteTree
257 u_int32_t node
; // node number
259 u_int16_t reserved
; // align size to a power of 2
260 } TreePathRecord
, *TreePathRecordPtr
;
262 typedef TreePathRecord TreePathTable
[kMaxTreeDepth
];
265 //// InsertKey - used by InsertTree, InsertLevel and InsertNode
272 Boolean replacingKey
;
276 typedef struct InsertKey InsertKey
;
279 //// For Notational Convenience
281 typedef BTNodeDescriptor
* NodeDescPtr
;
282 typedef u_int8_t
*RecordPtr
;
283 typedef BTreeKeyPtr KeyPtr
;
286 //////////////////////////////////// Globals ////////////////////////////////////
289 //////////////////////////////////// Macros /////////////////////////////////////
292 #define Panic( message ) DebugStr( message )
293 #define PanicIf( condition, message ) do { if ( condition != 0 ) DebugStr( message ); } while(0)
295 #define Panic( message ) do { } while(0)
296 #define PanicIf( condition, message ) do { } while(0)
299 // Exit function on error
300 #define M_ExitOnError( result ) do { if ( ( result ) != noErr ) goto ErrorExit; } while(0)
302 // Test for passed condition and return if true
303 #define M_ReturnErrorIf( condition, error ) do { if ( condition ) return( error ); } while(0)
305 //////////////////////////////// Key Operations /////////////////////////////////
307 int32_t CompareKeys (BTreeControlBlockPtr btreePtr
,
311 //////////////////////////////// Map Operations /////////////////////////////////
313 OSStatus
AllocateNode (BTreeControlBlockPtr btreePtr
,
316 OSStatus
FreeNode (BTreeControlBlockPtr btreePtr
,
319 OSStatus
ExtendBTree (BTreeControlBlockPtr btreePtr
,
322 u_int32_t
CalcMapBits (BTreeControlBlockPtr btreePtr
);
325 void BTUpdateReserve (BTreeControlBlockPtr btreePtr
,
328 //////////////////////////////// Misc Operations ////////////////////////////////
330 u_int16_t
CalcKeyRecordSize (u_int16_t keySize
,
333 OSStatus
VerifyHeader (FCB
*filePtr
,
334 BTHeaderRec
*header
);
336 OSStatus
UpdateHeader (BTreeControlBlockPtr btreePtr
,
337 Boolean forceWrite
);
339 OSStatus
FindIteratorPosition (BTreeControlBlockPtr btreePtr
,
340 BTreeIteratorPtr iterator
,
341 BlockDescriptor
*left
,
342 BlockDescriptor
*middle
,
343 BlockDescriptor
*right
,
346 Boolean
*foundRecord
);
348 OSStatus
CheckInsertParams (FCB
*filePtr
,
349 BTreeIterator
*iterator
,
350 FSBufferDescriptor
*record
,
351 u_int16_t recordLen
);
353 OSStatus
TrySimpleReplace (BTreeControlBlockPtr btreePtr
,
355 BTreeIterator
*iterator
,
356 FSBufferDescriptor
*record
,
358 Boolean
*recordInserted
);
360 OSStatus
IsItAHint (BTreeControlBlockPtr btreePtr
,
361 BTreeIterator
*iterator
,
364 extern OSStatus
TreeIsDirty(BTreeControlBlockPtr btreePtr
);
366 //////////////////////////////// Node Operations ////////////////////////////////
370 OSStatus
GetNode (BTreeControlBlockPtr btreePtr
,
373 NodeRec
*returnNodePtr
);
375 /* Flags for GetNode() */
376 #define kGetNodeHint 0x1 /* If set, the node is being looked up using a hint */
378 OSStatus
GetLeftSiblingNode (BTreeControlBlockPtr btreePtr
,
382 #define GetLeftSiblingNode(btree,node,left) GetNode ((btree), ((NodeDescPtr)(node))->bLink, 0, (left))
384 OSStatus
GetRightSiblingNode (BTreeControlBlockPtr btreePtr
,
388 #define GetRightSiblingNode(btree,node,right) GetNode ((btree), ((NodeDescPtr)(node))->fLink, 0, (right))
391 OSStatus
GetNewNode (BTreeControlBlockPtr btreePtr
,
393 NodeRec
*returnNodePtr
);
395 OSStatus
ReleaseNode (BTreeControlBlockPtr btreePtr
,
398 OSStatus
TrashNode (BTreeControlBlockPtr btreePtr
,
401 OSStatus
UpdateNode (BTreeControlBlockPtr btreePtr
,
403 u_int32_t transactionID
,
406 //// Node Buffer Operations
408 void ClearNode (BTreeControlBlockPtr btreePtr
,
411 u_int16_t
GetNodeDataSize (BTreeControlBlockPtr btreePtr
,
414 u_int16_t
GetNodeFreeSize (BTreeControlBlockPtr btreePtr
,
418 //// Record Operations
420 Boolean
InsertRecord (BTreeControlBlockPtr btreePtr
,
426 Boolean
InsertKeyRecord (BTreeControlBlockPtr btreePtr
,
434 void DeleteRecord (BTreeControlBlockPtr btree
,
439 Boolean
SearchNode (BTreeControlBlockPtr btree
,
444 OSStatus
GetRecordByIndex (BTreeControlBlockPtr btree
,
449 u_int16_t
*dataSize
);
451 u_int8_t
* GetRecordAddress (BTreeControlBlockPtr btree
,
455 #define GetRecordAddress(btreePtr,node,index) ((u_int8_t *)(node) + (*(short *) ((u_int8_t *)(node) + (btreePtr)->nodeSize - ((index) << 1) - kOffsetSize)))
458 u_int16_t
GetRecordSize (BTreeControlBlockPtr btree
,
462 u_int32_t
GetChildNodeNum (BTreeControlBlockPtr btreePtr
,
466 void MoveRecordsLeft (u_int8_t
* src
,
468 u_int16_t bytesToMove
);
470 #define MoveRecordsLeft(src,dst,bytes) bcopy((src),(dst),(bytes))
472 void MoveRecordsRight (u_int8_t
* src
,
474 u_int16_t bytesToMove
);
476 #define MoveRecordsRight(src,dst,bytes) bcopy((src),(dst),(bytes))
479 //////////////////////////////// Tree Operations ////////////////////////////////
481 OSStatus
SearchTree (BTreeControlBlockPtr btreePtr
,
483 TreePathTable treePathTable
,
485 BlockDescriptor
*nodePtr
,
488 OSStatus
InsertTree (BTreeControlBlockPtr btreePtr
,
489 TreePathTable treePathTable
,
493 BlockDescriptor
*targetNode
,
496 Boolean replacingKey
,
497 u_int32_t
*insertNode
);
499 OSStatus
DeleteTree (BTreeControlBlockPtr btreePtr
,
500 TreePathTable treePathTable
,
501 BlockDescriptor
*targetNode
,
505 #endif /* __APPLE_API_PRIVATE */
507 #endif //__BTREESPRIVATE__