2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 Contains: Private interface file for the BTree Module.
30 Version: xxx put the technology version here xxx
32 Written by: Gordon Sheridan and Bill Bruffey
34 Copyright: © 1992-1999 by Apple Computer, Inc., all rights reserved.
40 Other Contact: Mark Day
42 Technology: File Systems
52 Change History (most recent first):
53 <MacOSX> 3/19/99 djb Disable MoveRecordsLeft/Right macros since bcopy is broken.
55 <MacOSX> 8/10/98 djb Removed unused BTreeIterator from BTreeControlBlock, fixed alignment.
57 <CS5> 9/4/97 djb Convert MoveRecordsLeft and GetLeftSiblingNode to macros.
58 <CS4> 7/24/97 djb Add macro for GetRecordAddress (was a function before).
59 <CS3> 7/21/97 msd GetRecordByIndex now returns an OSStatus.
60 <CS2> 7/16/97 DSH FilesInternal.i renamed FileMgrInternal.i to avoid name
62 <CS1> 4/23/97 djb first checked in
64 <HFS6> 3/17/97 DSH Added a refCon field to BTreeControlBlock, for DFA use, to point
65 to additional data. Fixed Panic macros for use with SC.
66 <HFS5> 2/19/97 djb Add InsertKey struct. Moved on-disk definitions to
68 <HFS4> 1/27/97 djb InsertTree and DeleteTree are now recursive and support variable
70 <HFS3> 1/15/97 djb Move GetFileRefNumFromFCB macro to FilesInternal.h. Added
71 kBTVariableIndexKeysMask.
72 <HFS2> 1/3/97 djb Added support for large keys.
73 <HFS1> 12/19/96 djb first checked in
75 History applicable to original Scarecrow Design:
77 <7> 10/25/96 ser Changing for new VFPI
78 <6> 10/18/96 ser Converting over VFPI changes
79 <5> 9/17/96 dkh More BTree statistics
80 <4> 9/16/96 dkh Revised BTree statistics
81 <3> 6/20/96 dkh Radar #1358740. Switch from using Pools to debug MemAllocators.
82 <2> 12/7/95 dkh D10E2 build. Changed usage of Ref data type to LogicalAddress.
83 <1> 10/18/95 rst Moved from Scarecrow project.
85 <19> 11/22/94 djb Add prototype for GetMapNode
86 <18> 11/16/94 prp Add IsItAHint routine prototype.
87 <17> 9/30/94 prp Get in sync with D2 interface changes.
88 <16> 7/25/94 wjk Eliminate usage of BytePtr in favor of UInt8 *.
89 <15> 7/22/94 wjk Convert to the new set of header files.
90 <14> 5/31/94 srs Moved Btree types to public interface
91 <13> 12/9/93 wjk Add 68k alignment pragma's around persistent structures.
92 <12> 11/30/93 wjk Move from Makefiles to BuildFiles. Fit into the ModernOS and
94 <11> 11/23/93 wjk Changes required to compile on the RS6000.
95 <10> 8/30/93 CH Removed the M_ExitOnError and M_ReturnErrorIf macros which were
96 already defined in FileSystemPriv.h (included here).
97 <9> 8/30/93 CH Added parens around the M_ReturnErrorIf macro.
98 <8> 5/21/93 gs Add kBadClose flag. Add some prototypes for internal routines.
99 <7> 5/10/93 gs Change Ptr to BytePtr. Move BTreeTypes to BTree.h. Add
100 DeleteTree prototype.
101 <6> 3/23/93 gs Remove mysterious "flags" field from HeaderRec structure. Move
102 prototypes of private functions to top of respective source
104 <5> 2/8/93 gs Update to use FSAgent.h Get/Release/SetEOF/SetBlockSize
105 procPtrs. Add UpdateNode routine.
106 <4> 12/10/92 gs Add Key Descriptor function declarations.
107 <3> 12/8/92 gs Add HeaderRec structure and incorporate review feedback.
108 <2> 12/2/92 gs Add GetNode and ReleaseNode callback procptrs to BTree CB, and
109 add internal function declarations.
110 <1> 11/15/92 gs first checked in
114 #ifndef __BTREESPRIVATE__
115 #define __BTREESPRIVATE__
117 #include <sys/appleapiopts.h>
120 #ifdef __APPLE_API_PRIVATE
122 #include "../../hfs_macos_defs.h"
124 #ifndef __FILEMGRINTERNAL__
125 #include "FileMgrInternal.h"
128 #ifndef __BTREESINTERNAL__
129 #include "BTreesInternal.h"
133 /////////////////////////////////// Constants ///////////////////////////////////
135 #define kBTreeVersion 1
136 #define kMaxTreeDepth 16
139 #define kHeaderNodeNum 0
140 #define kKeyDescRecord 1
143 // Header Node Record Offsets
145 kHeaderRecOffset
= 0x000E,
146 kKeyDescRecOffset
= 0x0078,
147 kHeaderMapRecOffset
= 0x00F8
150 #define kMinNodeSize 512
152 #define kMinRecordSize 6
153 // where is minimum record size enforced?
155 // miscellaneous BTree constants
166 // illegal string attribute bits set in mask
167 #define kBadStrAttribMask 0xCF
171 //////////////////////////////////// Macros /////////////////////////////////////
173 #define M_NodesInMap(mapSize) ((mapSize) << 3)
175 #define M_ClearBitNum(integer,bitNumber) ((integer) &= (~(1<<(bitNumber))))
176 #define M_SetBitNum(integer,bitNumber) ((integer) |= (1<<(bitNumber)))
177 #define M_IsOdd(integer) (((integer) & 1) != 0)
178 #define M_IsEven(integer) (((integer) & 1) == 0)
179 #define M_BTreeHeaderDirty(btreePtr) btreePtr->flags |= kBTHeaderDirty
181 #define M_MapRecordSize(nodeSize) (nodeSize - sizeof (BTNodeDescriptor) - 6)
182 #define M_HeaderMapRecordSize(nodeSize) (nodeSize - sizeof(BTNodeDescriptor) - sizeof(BTHeaderRec) - 128 - 8)
184 #define M_SWAP_BE16_ClearBitNum(integer,bitNumber) ((integer) &= SWAP_BE16(~(1<<(bitNumber))))
185 #define M_SWAP_BE16_SetBitNum(integer,bitNumber) ((integer) |= SWAP_BE16(1<<(bitNumber)))
187 ///////////////////////////////////// Types /////////////////////////////////////
189 typedef struct BTreeControlBlock
{ // fields specific to BTree CBs
191 UInt8 reserved1
; // keep for alignment with old style fields
194 FileReference fileRefNum
; // refNum of btree file
195 KeyCompareProcPtr keyCompareProc
;
198 UInt32 firstLeafNode
;
205 UInt16 reserved3
; // 4-byte alignment
209 UInt32 flags
; // dynamic flags
210 UInt32 attributes
; // persistent flags
212 UInt32 lastfsync
; /* Last time that this was fsynced */
214 GetBlockProcPtr getBlockProc
;
215 ReleaseBlockProcPtr releaseBlockProc
;
216 SetEndOfForkProcPtr setEndOfForkProc
;
218 // statistical information
220 UInt32 numGetNewNodes
;
221 UInt32 numReleaseNodes
;
222 UInt32 numUpdateNodes
;
223 UInt32 numMapNodesRead
; // map nodes beyond header node
224 UInt32 numHintChecks
;
225 UInt32 numPossibleHints
; // Looks like a formated hint
226 UInt32 numValidHints
; // Hint used to find correct record.
228 } BTreeControlBlock
, *BTreeControlBlockPtr
;
231 UInt32
CalcKeySize(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
232 #define CalcKeySize(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? ((key)->length16 + 2) : ((key)->length8 + 1) )
234 UInt32
KeyLength(const BTreeControlBlock
*btcb
, const BTreeKey
*key
);
235 #define KeyLength(btcb, key) ( ((btcb)->attributes & kBTBigKeysMask) ? (key)->length16 : (key)->length8 )
240 kBTHeaderDirty
= 0x00000001
244 typedef SInt8
*NodeBuffer
;
245 typedef BlockDescriptor NodeRec
, *NodePtr
; //\80\80 remove this someday...
250 //// Tree Path Table - constructed by SearchTree, used by InsertTree and DeleteTree
253 UInt32 node
; // node number
255 UInt16 reserved
; // align size to a power of 2
256 } TreePathRecord
, *TreePathRecordPtr
;
258 typedef TreePathRecord TreePathTable
[kMaxTreeDepth
];
261 //// InsertKey - used by InsertTree, InsertLevel and InsertNode
268 Boolean replacingKey
;
272 typedef struct InsertKey InsertKey
;
275 //// For Notational Convenience
277 typedef BTNodeDescriptor
* NodeDescPtr
;
278 typedef UInt8
*RecordPtr
;
279 typedef BTreeKeyPtr KeyPtr
;
282 //////////////////////////////////// Globals ////////////////////////////////////
285 //////////////////////////////////// Macros /////////////////////////////////////
288 #define Panic( message ) DebugStr( (ConstStr255Param) message )
289 #define PanicIf( condition, message ) if ( condition != 0 ) DebugStr( message )
291 #define Panic( message )
292 #define PanicIf( condition, message )
295 // Exit function on error
296 #define M_ExitOnError( result ) if ( ( result ) != noErr ) goto ErrorExit; else ;
298 // Test for passed condition and return if true
299 #define M_ReturnErrorIf( condition, error ) if ( condition ) return( error )
301 //////////////////////////////// Key Operations /////////////////////////////////
303 SInt32
CompareKeys (BTreeControlBlockPtr btreePtr
,
307 //////////////////////////////// Map Operations /////////////////////////////////
309 OSStatus
AllocateNode (BTreeControlBlockPtr btreePtr
,
312 OSStatus
FreeNode (BTreeControlBlockPtr btreePtr
,
315 OSStatus
ExtendBTree (BTreeControlBlockPtr btreePtr
,
318 UInt32
CalcMapBits (BTreeControlBlockPtr btreePtr
);
321 //////////////////////////////// Misc Operations ////////////////////////////////
323 UInt16
CalcKeyRecordSize (UInt16 keySize
,
326 OSStatus
VerifyHeader (FCB
*filePtr
,
327 BTHeaderRec
*header
);
329 OSStatus
UpdateHeader (BTreeControlBlockPtr btreePtr
,
330 Boolean forceWrite
);
332 OSStatus
FindIteratorPosition (BTreeControlBlockPtr btreePtr
,
333 BTreeIteratorPtr iterator
,
334 BlockDescriptor
*left
,
335 BlockDescriptor
*middle
,
336 BlockDescriptor
*right
,
339 Boolean
*foundRecord
);
341 OSStatus
CheckInsertParams (FCB
*filePtr
,
342 BTreeIterator
*iterator
,
343 FSBufferDescriptor
*record
,
346 OSStatus
TrySimpleReplace (BTreeControlBlockPtr btreePtr
,
348 BTreeIterator
*iterator
,
349 FSBufferDescriptor
*record
,
351 Boolean
*recordInserted
);
353 OSStatus
IsItAHint (BTreeControlBlockPtr btreePtr
,
354 BTreeIterator
*iterator
,
357 //////////////////////////////// Node Operations ////////////////////////////////
361 OSStatus
GetNode (BTreeControlBlockPtr btreePtr
,
363 NodeRec
*returnNodePtr
);
365 OSStatus
GetLeftSiblingNode (BTreeControlBlockPtr btreePtr
,
369 #define GetLeftSiblingNode(btree,node,left) GetNode ((btree), ((NodeDescPtr)(node))->bLink, (left))
371 OSStatus
GetRightSiblingNode (BTreeControlBlockPtr btreePtr
,
375 #define GetRightSiblingNode(btree,node,right) GetNode ((btree), ((NodeDescPtr)(node))->fLink, (right))
378 OSStatus
GetNewNode (BTreeControlBlockPtr btreePtr
,
380 NodeRec
*returnNodePtr
);
382 OSStatus
ReleaseNode (BTreeControlBlockPtr btreePtr
,
385 OSStatus
TrashNode (BTreeControlBlockPtr btreePtr
,
389 void ModifyBlockStart(FileReference vp
, BlockDescPtr blockPtr
);
392 OSStatus
UpdateNode (BTreeControlBlockPtr btreePtr
,
394 UInt32 transactionID
,
397 OSStatus
GetMapNode (BTreeControlBlockPtr btreePtr
,
398 BlockDescriptor
*nodePtr
,
402 //// Node Buffer Operations
404 OSStatus
CheckNode (BTreeControlBlockPtr btreePtr
,
407 void ClearNode (BTreeControlBlockPtr btreePtr
,
410 UInt16
GetNodeDataSize (BTreeControlBlockPtr btreePtr
,
413 UInt16
GetNodeFreeSize (BTreeControlBlockPtr btreePtr
,
417 //// Record Operations
419 Boolean
InsertRecord (BTreeControlBlockPtr btreePtr
,
425 Boolean
InsertKeyRecord (BTreeControlBlockPtr btreePtr
,
433 void DeleteRecord (BTreeControlBlockPtr btree
,
438 Boolean
SearchNode (BTreeControlBlockPtr btree
,
443 OSStatus
GetRecordByIndex (BTreeControlBlockPtr btree
,
450 UInt8
* GetRecordAddress (BTreeControlBlockPtr btree
,
454 #define GetRecordAddress(btreePtr,node,index) ((UInt8 *)(node) + (*(short *) ((UInt8 *)(node) + (btreePtr)->nodeSize - ((index) << 1) - kOffsetSize)))
457 UInt16
GetRecordSize (BTreeControlBlockPtr btree
,
461 UInt32
GetChildNodeNum (BTreeControlBlockPtr btreePtr
,
465 void MoveRecordsLeft (UInt8
* src
,
467 UInt16 bytesToMove
);
469 #define MoveRecordsLeft(src,dst,bytes) bcopy((src),(dst),(bytes))
471 void MoveRecordsRight (UInt8
* src
,
473 UInt16 bytesToMove
);
475 #define MoveRecordsRight(src,dst,bytes) bcopy((src),(dst),(bytes))
478 //////////////////////////////// Tree Operations ////////////////////////////////
480 OSStatus
SearchTree (BTreeControlBlockPtr btreePtr
,
482 TreePathTable treePathTable
,
484 BlockDescriptor
*nodePtr
,
487 OSStatus
InsertTree (BTreeControlBlockPtr btreePtr
,
488 TreePathTable treePathTable
,
492 BlockDescriptor
*targetNode
,
495 Boolean replacingKey
,
496 UInt32
*insertNode
);
498 OSStatus
DeleteTree (BTreeControlBlockPtr btreePtr
,
499 TreePathTable treePathTable
,
500 BlockDescriptor
*targetNode
,
504 #endif /* __APPLE_API_PRIVATE */
506 #endif //__BTREESPRIVATE__