/*++ Copyright (c) 1991 Microsoft Corporation Module Name: blrange.h Abstract: This module declares ranges, rangelists and their methods. These can be used to keep track of cached ranges of a disk for instance. Author: Cenk Ergan (cenke) 11-Jan-2000 Revision History: --*/ #ifndef _BLRANGE_H #define _BLRANGE_H #include "bldr.h" // // Define range & range list data structures. // // // NOTE: BLCRANGE's Start is inclusive and End is exclusive. E.g. // 200-400 contains 200th but does not contain 400th byte, apple, // meter etc. This allows a single subtraction to determine the // number of elements in the range. // // // NOTE: BLCRANGE's Start should be less than or equal to its End. // // // Representing ranges with start and end instead of start and length // seems to simplify the code and remove a lot of addition and // subtractions. We could maybe use a ULONG Length, which would save 4 // bytes per range, but lists make it hard to have thousands of ranges // and even if you had 10 thousand ranges, you'd save only 40KB, which // seemed to be insignificant to the cons above when I began changing // the code to have Length instead of End. With both Start and End // ULONGLONG more data can be represented by ranges, e.g. 64bit // offsets [memory or disk] where 4GB Length may not be enough. // typedef struct _BLCRANGE { ULONGLONG Start; ULONGLONG End; } BLCRANGE, *PBLCRANGE; typedef struct _BLCRANGE_ENTRY { LIST_ENTRY Link; BLCRANGE Range; PVOID UserData; // UserData field is not used by range functions. LIST_ENTRY UserLink; // UserLink field is not used by range functions. } BLCRANGE_ENTRY, *PBLCRANGE_ENTRY; // // Define range entry merging routine type. This routine should // perform the necessary operations to merge the user controlled / // maintained Data field of the pSrcEntry to pDestEntry's Data // field. It should not manipulate any other BLCRANGE_ENTRT fields. It // should return FALSE if there was an error and it could not merge // the two Data fields, TRUE otherwise. If it returns FALSE, it should // undo its modifications to pDestEntry and pSrcEntry. // typedef BOOLEAN (*PBLCRANGE_MERGE_ROUTINE) ( PBLCRANGE_ENTRY pDestEntry, PBLCRANGE_ENTRY pSrcEntry ); // // Define range entry free'ing routine type. This routine should free // all the resources & memory allocated for a range entry. // typedef VOID (*PBLCRANGE_FREE_ROUTINE) ( PBLCRANGE_ENTRY pRangeEntry ); // // BLCRANGE_LIST maintains a sorted list of non-overlapping range // entries off its Head field. // typedef struct _BLCRANGE_LIST { LIST_ENTRY Head; ULONG NumEntries; PBLCRANGE_MERGE_ROUTINE MergeRoutine; PBLCRANGE_FREE_ROUTINE FreeRoutine; } BLCRANGE_LIST, *PBLCRANGE_LIST; // // Useful macros. Be mindful of expression reevaluation as with // all macros. // #define BLRGMIN(a,b) (((a) <= (b)) ? (a) : (b)) #define BLRGMAX(a,b) (((a) >= (b)) ? (a) : (b)) // // Range function prototypes. See ntos\boot\lib\blrange.c for comments // and implementation. // VOID BlRangeListInitialize ( PBLCRANGE_LIST pRangeList, OPTIONAL PBLCRANGE_MERGE_ROUTINE pMergeRoutine, OPTIONAL PBLCRANGE_FREE_ROUTINE pFreeRoutine ); BOOLEAN BlRangeListAddRange ( PBLCRANGE_LIST pRangeList, PBLCRANGE_ENTRY pRangeEntry ); BOOLEAN BlRangeListFindOverlaps ( PBLCRANGE_LIST pRangeList, PBLCRANGE pRange, PBLCRANGE_ENTRY *pOverlapsBuffer, ULONG OverlapsBufferSize, OUT ULONG *pNumOverlaps ); BOOLEAN BlRangeListFindDistinctRanges ( PBLCRANGE_LIST pRangeList, PBLCRANGE pRange, PBLCRANGE pDistinctRanges, ULONG BufferSize, OUT ULONG *pNumRanges ); VOID BlRangeListRemoveRange ( PBLCRANGE_LIST pRangeList, PBLCRANGE pRange ); VOID BlRangeListRemoveAllRanges ( PBLCRANGE_LIST pRangeList ); BOOLEAN BlRangeListMergeRangeEntries ( PBLCRANGE_LIST pRangeList, PBLCRANGE_ENTRY pDestEntry, PBLCRANGE_ENTRY pSrcEntry ); BOOLEAN BlRangeEntryMerge ( PBLCRANGE_ENTRY pDestEntry, PBLCRANGE_ENTRY pSrcEntry, OPTIONAL PBLCRANGE_MERGE_ROUTINE pMergeRoutine ); #endif // _BLRANGE_H