ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bitmap.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS system libraries
00004  * FILE:            lib/rtl/bitmap.c
00005  * PURPOSE:         Bitmap functions
00006  * PROGRAMMER:      Timo Kreuzer (timo.kreuzer@reactos.org)
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include <rtl.h>
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 
00017 /* DATA *********************************************************************/
00018 
00019 /* Number of set bits per byte value */
00020 static const
00021 UCHAR
00022 BitCountTable[256] =
00023 {
00024     /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
00025        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 0x */
00026        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 1x */
00027        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 2x */
00028        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 3x */
00029        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 4x */
00030        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 5x */
00031        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 6c */
00032        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* 7x */
00033        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 8x */
00034        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 9x */
00035        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* Ax */
00036        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Bx */
00037        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* Cx */
00038        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Dx */
00039        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Ex */
00040        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8  /* Fx */
00041 };
00042 
00043 
00044 /* PRIVATE FUNCTIONS ********************************************************/
00045 
00046 static __inline
00047 ULONG
00048 RtlpGetLengthOfRunClear(
00049     IN PRTL_BITMAP BitMapHeader,
00050     IN ULONG StartingIndex,
00051     IN ULONG MaxLength)
00052 {
00053     ULONG Value, BitPos, Length;
00054     PULONG Buffer, MaxBuffer;
00055 
00056     /* Calculate positions */
00057     Buffer = BitMapHeader->Buffer + StartingIndex / 32;
00058     BitPos = StartingIndex & 31;
00059 
00060     /* Calculate the maximum length */
00061     MaxLength = min(MaxLength, BitMapHeader->SizeOfBitMap - StartingIndex);
00062     MaxBuffer = Buffer + (BitPos + MaxLength + 31) / 32;
00063 
00064     /* Clear the bits that don't belong to this run */
00065     Value = *Buffer++ >> BitPos << BitPos;
00066 
00067     /* Skip all clear ULONGs */
00068     while (Value == 0 && Buffer < MaxBuffer)
00069     {
00070         Value = *Buffer++;
00071     }
00072 
00073     /* Did we reach the end? */
00074     if (Value == 0)
00075     {
00076         /* Return maximum length */
00077         return MaxLength;
00078     }
00079 
00080     /* We hit a set bit, check how many clear bits are left */
00081     BitScanForward(&BitPos, Value);
00082 
00083     /* Calculate length up to where we read */
00084     Length = (ULONG)(Buffer - BitMapHeader->Buffer) * 32 - StartingIndex;
00085     Length += BitPos - 32;
00086 
00087     /* Make sure we don't go past the last bit */
00088     if (Length > BitMapHeader->SizeOfBitMap - StartingIndex)
00089         Length = BitMapHeader->SizeOfBitMap - StartingIndex;
00090 
00091     /* Return the result */
00092     return Length;
00093 }
00094 
00095 static __inline
00096 ULONG
00097 RtlpGetLengthOfRunSet(
00098     IN PRTL_BITMAP BitMapHeader,
00099     IN ULONG StartingIndex,
00100     IN ULONG MaxLength)
00101 {
00102     ULONG InvValue, BitPos, Length;
00103     PULONG Buffer, MaxBuffer;
00104 
00105     /* Calculate positions */
00106     Buffer = BitMapHeader->Buffer + StartingIndex / 32;
00107     BitPos = StartingIndex & 31;
00108 
00109     /* Calculate the maximum length */
00110     MaxLength = min(MaxLength, BitMapHeader->SizeOfBitMap - StartingIndex);
00111     MaxBuffer = Buffer + (BitPos + MaxLength + 31) / 32;
00112 
00113     /* Get the inversed value, clear bits that don't belong to the run */
00114     InvValue = ~(*Buffer++) >> BitPos << BitPos;
00115 
00116     /* Skip all set ULONGs */
00117     while (InvValue == 0 && Buffer < MaxBuffer)
00118     {
00119         InvValue = ~(*Buffer++);
00120     }
00121 
00122     /* Did we reach the end? */
00123     if (InvValue == 0)
00124     {
00125         /* Yes, return maximum */
00126         return MaxLength;
00127     }
00128 
00129     /* We hit a clear bit, check how many set bits are left */
00130     BitScanForward(&BitPos, InvValue);
00131 
00132     /* Calculate length up to where we read */
00133     Length = (ULONG)(Buffer - BitMapHeader->Buffer) * 32 - StartingIndex;
00134     Length += BitPos - 32;
00135 
00136     /* Make sure we don't go past the last bit */
00137     if (Length > BitMapHeader->SizeOfBitMap - StartingIndex)
00138         Length = BitMapHeader->SizeOfBitMap - StartingIndex;
00139 
00140     /* Return the result */
00141     return Length;
00142 }
00143 
00144 
00145 /* PUBLIC FUNCTIONS **********************************************************/
00146 
00147 CCHAR
00148 NTAPI
00149 RtlFindMostSignificantBit(ULONGLONG Value)
00150 {
00151     ULONG Position;
00152 
00153     if (BitScanReverse(&Position, Value >> 32))
00154     {
00155         return (CCHAR)(Position + 32);
00156     }
00157     else if (BitScanReverse(&Position, (ULONG)Value))
00158     {
00159         return (CCHAR)Position;
00160     }
00161 
00162     return -1;
00163 }
00164 
00165 CCHAR
00166 NTAPI
00167 RtlFindLeastSignificantBit(ULONGLONG Value)
00168 {
00169     ULONG Position;
00170 
00171     if (BitScanForward(&Position, (ULONG)Value))
00172     {
00173         return (CCHAR)Position;
00174     }
00175     else if (BitScanForward(&Position, Value >> 32))
00176     {
00177         return (CCHAR)(Position + 32);
00178     }
00179 
00180     return -1;
00181 }
00182 
00183 VOID
00184 NTAPI
00185 RtlInitializeBitMap(
00186     IN PRTL_BITMAP BitMapHeader,
00187     IN PULONG BitMapBuffer,
00188     IN ULONG SizeOfBitMap)
00189 {
00190     /* Setup the bitmap header */
00191     BitMapHeader->SizeOfBitMap = SizeOfBitMap;
00192     BitMapHeader->Buffer = BitMapBuffer;
00193 }
00194 
00195 VOID
00196 NTAPI
00197 RtlClearAllBits(
00198     IN OUT PRTL_BITMAP BitMapHeader)
00199 {
00200     ULONG LengthInUlongs;
00201 
00202     LengthInUlongs = (BitMapHeader->SizeOfBitMap + 31) >> 5;
00203     RtlFillMemoryUlong(BitMapHeader->Buffer, LengthInUlongs << 2, 0);
00204 }
00205 
00206 VOID
00207 NTAPI
00208 RtlSetAllBits(
00209     IN OUT PRTL_BITMAP BitMapHeader)
00210 {
00211     ULONG LengthInUlongs;
00212 
00213     LengthInUlongs = (BitMapHeader->SizeOfBitMap + 31) >> 5;
00214     RtlFillMemoryUlong(BitMapHeader->Buffer, LengthInUlongs << 2, ~0);
00215 }
00216 
00217 VOID
00218 NTAPI
00219 RtlClearBit(
00220     IN PRTL_BITMAP BitMapHeader,
00221     IN ULONG BitNumber)
00222 {
00223     ASSERT(BitNumber <= BitMapHeader->SizeOfBitMap);
00224     BitMapHeader->Buffer[BitNumber >> 5] &= ~(1 << (BitNumber & 31));
00225 }
00226 
00227 VOID
00228 NTAPI
00229 RtlSetBit(
00230     IN PRTL_BITMAP BitMapHeader,
00231     IN ULONG BitNumber)
00232 {
00233     ASSERT(BitNumber <= BitMapHeader->SizeOfBitMap);
00234     BitMapHeader->Buffer[BitNumber >> 5] |= (1 << (BitNumber & 31));
00235 }
00236 
00237 VOID
00238 NTAPI
00239 RtlClearBits(
00240     IN PRTL_BITMAP BitMapHeader,
00241     IN ULONG StartingIndex,
00242     IN ULONG NumberToClear)
00243 {
00244     ULONG Bits, Mask;
00245     PULONG Buffer;
00246 
00247     ASSERT(StartingIndex + NumberToClear <= BitMapHeader->SizeOfBitMap);
00248 
00249     /* Calculate buffer start and first bit index */
00250     Buffer = &BitMapHeader->Buffer[StartingIndex >> 5];
00251     Bits = StartingIndex & 31;
00252 
00253     /* Are we unaligned? */
00254     if (Bits)
00255     {
00256         /* Create an inverse mask by shifting MAXULONG */
00257         Mask = MAXULONG << Bits;
00258 
00259         /* This is what's left in the first ULONG */
00260         Bits = 32 - Bits;
00261 
00262         /* Even less bits to clear? */
00263         if (NumberToClear < Bits)
00264         {
00265             /* Calculate how many bits are left */
00266             Bits -= NumberToClear;
00267 
00268             /* Fixup the mask on the high side */
00269             Mask = Mask << Bits >> Bits;
00270 
00271             /* Clear bits and return */
00272             *Buffer &= ~Mask;
00273             return;
00274         }
00275 
00276         /* Clear bits */
00277         *Buffer &= ~Mask;
00278 
00279         /* Update buffer and left bits */
00280         Buffer++;
00281         NumberToClear -= Bits;
00282     }
00283 
00284     /* Clear all full ULONGs */
00285     RtlFillMemoryUlong(Buffer, NumberToClear >> 3, 0);
00286     Buffer += NumberToClear >> 5;
00287 
00288     /* Clear what's left */
00289     NumberToClear &= 31;
00290     Mask = MAXULONG << NumberToClear;
00291     *Buffer &= Mask;
00292 }
00293 
00294 VOID
00295 NTAPI
00296 RtlSetBits(
00297     IN PRTL_BITMAP BitMapHeader,
00298     IN ULONG StartingIndex,
00299     IN ULONG NumberToSet)
00300 {
00301     ULONG Bits, Mask;
00302     PULONG Buffer;
00303 
00304     ASSERT(StartingIndex + NumberToSet <= BitMapHeader->SizeOfBitMap);
00305 
00306     /* Calculate buffer start and first bit index */
00307     Buffer = &BitMapHeader->Buffer[StartingIndex >> 5];
00308     Bits = StartingIndex & 31;
00309 
00310     /* Are we unaligned? */
00311     if (Bits)
00312     {
00313         /* Create a mask by shifting MAXULONG */
00314         Mask = MAXULONG << Bits;
00315 
00316         /* This is what's left in the first ULONG */
00317         Bits = 32 - Bits;
00318 
00319         /* Even less bits to clear? */
00320         if (NumberToSet < Bits)
00321         {
00322             /* Calculate how many bits are left */
00323             Bits -= NumberToSet;
00324 
00325             /* Fixup the mask on the high side */
00326             Mask = Mask << Bits >> Bits;
00327 
00328             /* Set bits and return */
00329             *Buffer |= Mask;
00330             return;
00331         }
00332 
00333         /* Set bits */
00334         *Buffer |= Mask;
00335 
00336         /* Update buffer and left bits */
00337         Buffer++;
00338         NumberToSet -= Bits;
00339     }
00340 
00341     /* Set all full ULONGs */
00342     RtlFillMemoryUlong(Buffer, NumberToSet >> 3, MAXULONG);
00343     Buffer += NumberToSet >> 5;
00344 
00345     /* Set what's left */
00346     NumberToSet &= 31;
00347     Mask = MAXULONG << NumberToSet;
00348     *Buffer |= ~Mask;
00349 }
00350 
00351 BOOLEAN
00352 NTAPI
00353 RtlTestBit(
00354     IN PRTL_BITMAP BitMapHeader,
00355     IN ULONG BitNumber)
00356 {
00357     ASSERT(BitNumber < BitMapHeader->SizeOfBitMap);
00358     return (BitMapHeader->Buffer[BitNumber >> 5] >> (BitNumber & 31)) & 1;
00359 }
00360 
00361 BOOLEAN
00362 NTAPI
00363 RtlAreBitsClear(
00364     IN PRTL_BITMAP BitMapHeader,
00365     IN ULONG StartingIndex,
00366     IN ULONG Length)
00367 {
00368     /* Verify parameters */
00369     if ((StartingIndex + Length > BitMapHeader->SizeOfBitMap) ||
00370         (StartingIndex + Length <= StartingIndex))
00371         return FALSE;
00372 
00373     return RtlpGetLengthOfRunClear(BitMapHeader, StartingIndex, Length) >= Length;
00374 }
00375 
00376 BOOLEAN
00377 NTAPI
00378 RtlAreBitsSet(
00379     IN PRTL_BITMAP BitMapHeader,
00380     IN ULONG StartingIndex,
00381     IN ULONG Length)
00382 {
00383     /* Verify parameters */
00384     if ((StartingIndex + Length > BitMapHeader->SizeOfBitMap) ||
00385         (StartingIndex + Length <= StartingIndex))
00386         return FALSE;
00387 
00388     return RtlpGetLengthOfRunSet(BitMapHeader, StartingIndex, Length) >= Length;
00389 }
00390 
00391 ULONG
00392 NTAPI
00393 RtlNumberOfSetBits(
00394     IN PRTL_BITMAP BitMapHeader)
00395 {
00396     PUCHAR Byte, MaxByte;
00397     ULONG BitCount = 0;
00398 
00399     Byte = (PUCHAR)BitMapHeader->Buffer;
00400     MaxByte = Byte + (BitMapHeader->SizeOfBitMap + 7) / 8;
00401 
00402     do
00403     {
00404         BitCount += BitCountTable[*Byte++];
00405     }
00406     while (Byte <= MaxByte);
00407 
00408     return BitCount;
00409 }
00410 
00411 ULONG
00412 NTAPI
00413 RtlNumberOfClearBits(
00414     IN PRTL_BITMAP BitMapHeader)
00415 {
00416     /* Do some math */
00417     return BitMapHeader->SizeOfBitMap - RtlNumberOfSetBits(BitMapHeader);
00418 }
00419 
00420 ULONG
00421 NTAPI
00422 RtlFindClearBits(
00423     IN PRTL_BITMAP BitMapHeader,
00424     IN ULONG NumberToFind,
00425     IN ULONG HintIndex)
00426 {
00427     ULONG CurrentBit, Margin, CurrentLength;
00428 
00429     /* Check for valid parameters */
00430     if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap)
00431     {
00432         return MAXULONG;
00433     }
00434 
00435     /* Check for trivial case */
00436     if (NumberToFind == 0)
00437     {
00438         return HintIndex;
00439     }
00440 
00441     /* First margin is end of bitmap */
00442     Margin = BitMapHeader->SizeOfBitMap;
00443 
00444 retry:
00445     /* Start with hint index, length is 0 */
00446     CurrentBit = HintIndex;
00447 
00448     /* Loop until something is found or the end is reached */
00449     while (CurrentBit + NumberToFind < Margin)
00450     {
00451         /* Search for the next clear run, by skipping a set run */
00452         CurrentBit += RtlpGetLengthOfRunSet(BitMapHeader,
00453                                             CurrentBit,
00454                                             MAXULONG);
00455 
00456         /* Get length of the clear bit run */
00457         CurrentLength = RtlpGetLengthOfRunClear(BitMapHeader,
00458                                                 CurrentBit,
00459                                                 NumberToFind);
00460 
00461         /* Is this long enough? */
00462         if (CurrentLength >= NumberToFind)
00463         {
00464             /* It is */
00465             return CurrentBit;
00466         }
00467 
00468         CurrentBit += CurrentLength;
00469     }
00470 
00471     /* Did we start at a hint? */
00472     if (HintIndex)
00473     {
00474         /* Retry at the start */
00475         Margin = min(HintIndex + NumberToFind, BitMapHeader->SizeOfBitMap);
00476         HintIndex = 0;
00477         goto retry;
00478     }
00479 
00480     /* Nothing found */
00481     return MAXULONG;
00482 }
00483 
00484 ULONG
00485 NTAPI
00486 RtlFindSetBits(
00487     IN PRTL_BITMAP BitMapHeader,
00488     IN ULONG NumberToFind,
00489     IN ULONG HintIndex)
00490 {
00491     ULONG CurrentBit, Margin, CurrentLength;
00492 
00493     /* Check for valid parameters */
00494     if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap)
00495     {
00496         return MAXULONG;
00497     }
00498 
00499     /* Check for trivial case */
00500     if (NumberToFind == 0)
00501     {
00502         return HintIndex;
00503     }
00504 
00505     /* First margin is end of bitmap */
00506     Margin = BitMapHeader->SizeOfBitMap;
00507 
00508 retry:
00509     /* Start with hint index, length is 0 */
00510     CurrentBit = HintIndex;
00511 
00512     /* Loop until something is found or the end is reached */
00513     while (CurrentBit + NumberToFind <= Margin)
00514     {
00515         /* Search for the next set run, by skipping a clear run */
00516         CurrentBit += RtlpGetLengthOfRunClear(BitMapHeader,
00517                                               CurrentBit,
00518                                               MAXULONG);
00519 
00520         /* Get length of the set bit run */
00521         CurrentLength = RtlpGetLengthOfRunSet(BitMapHeader,
00522                                               CurrentBit,
00523                                               NumberToFind);
00524 
00525         /* Is this long enough? */
00526         if (CurrentLength >= NumberToFind)
00527         {
00528             /* It is */
00529             return CurrentBit;
00530         }
00531 
00532         CurrentBit += CurrentLength;
00533     }
00534 
00535     /* Did we start at a hint? */
00536     if (HintIndex)
00537     {
00538         /* Retry at the start */
00539         Margin = min(HintIndex + NumberToFind, BitMapHeader->SizeOfBitMap);
00540         HintIndex = 0;
00541         goto retry;
00542     }
00543 
00544     /* Nothing found */
00545     return MAXULONG;
00546 }
00547 
00548 ULONG
00549 NTAPI
00550 RtlFindClearBitsAndSet(
00551     PRTL_BITMAP BitMapHeader,
00552     ULONG NumberToFind,
00553     ULONG HintIndex)
00554 {
00555     ULONG Position;
00556 
00557     /* Try to find clear bits */
00558     Position = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex);
00559 
00560     /* Did we get something? */
00561     if (Position != MAXULONG)
00562     {
00563         /* Yes, set the bits */
00564         RtlSetBits(BitMapHeader, Position, NumberToFind);
00565     }
00566 
00567     /* Return what we found */
00568     return Position;
00569 }
00570 
00571 ULONG
00572 NTAPI
00573 RtlFindSetBitsAndClear(
00574     IN PRTL_BITMAP BitMapHeader,
00575     IN ULONG NumberToFind,
00576     IN ULONG HintIndex)
00577 {
00578     ULONG Position;
00579 
00580     /* Try to find set bits */
00581     Position = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex);
00582 
00583     /* Did we get something? */
00584     if (Position != MAXULONG)
00585     {
00586         /* Yes, clear the bits */
00587         RtlClearBits(BitMapHeader, Position, NumberToFind);
00588     }
00589 
00590     /* Return what we found */
00591     return Position;
00592 }
00593 
00594 ULONG
00595 NTAPI
00596 RtlFindNextForwardRunClear(
00597     IN PRTL_BITMAP BitMapHeader,
00598     IN ULONG FromIndex,
00599     IN PULONG StartingRunIndex)
00600 {
00601     ULONG Length;
00602 
00603     /* Assume a set run first, count it's length */
00604     Length = RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG);
00605     *StartingRunIndex = FromIndex + Length;
00606 
00607     /* Now return the length of the run */
00608     return RtlpGetLengthOfRunClear(BitMapHeader, FromIndex + Length, MAXULONG);
00609 }
00610 
00611 ULONG
00612 NTAPI
00613 RtlFindNextForwardRunSet(
00614     IN PRTL_BITMAP BitMapHeader,
00615     IN ULONG FromIndex,
00616     IN PULONG StartingRunIndex)
00617 {
00618     ULONG Length;
00619 
00620     /* Assume a clear run first, count it's length */
00621     Length = RtlpGetLengthOfRunClear(BitMapHeader, FromIndex, MAXULONG);
00622     *StartingRunIndex = FromIndex + Length;
00623 
00624     /* Now return the length of the run */
00625     return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG);
00626 }
00627 
00628 ULONG
00629 NTAPI
00630 RtlFindFirstRunClear(
00631     IN PRTL_BITMAP BitMapHeader,
00632     IN PULONG StartingIndex)
00633 {
00634     return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex);
00635 }
00636 
00637 ULONG
00638 NTAPI
00639 RtlFindLastBackwardRunClear(
00640     IN PRTL_BITMAP BitMapHeader,
00641     IN ULONG FromIndex,
00642     IN PULONG StartingRunIndex)
00643 {
00644     UNIMPLEMENTED;
00645     return 0;
00646 }
00647 
00648 
00649 ULONG
00650 NTAPI
00651 RtlFindClearRuns(
00652     IN PRTL_BITMAP BitMapHeader,
00653     IN PRTL_BITMAP_RUN RunArray,
00654     IN ULONG SizeOfRunArray,
00655     IN BOOLEAN LocateLongestRuns)
00656 {
00657     ULONG StartingIndex, NumberOfBits, Run, FromIndex = 0, SmallestRun = 0;
00658 
00659     /* Loop the runs */
00660     for (Run = 0; Run < SizeOfRunArray; Run++)
00661     {
00662         /* Look for a run */
00663         NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader,
00664                                                   FromIndex,
00665                                                   &StartingIndex);
00666 
00667         /* Nothing more found? Quit looping. */
00668         if (NumberOfBits == 0) break;
00669 
00670         /* Add another run */
00671         RunArray[Run].StartingIndex = StartingIndex;
00672         RunArray[Run].NumberOfBits = NumberOfBits;
00673 
00674         /* Update smallest run */
00675         if (NumberOfBits < RunArray[SmallestRun].NumberOfBits)
00676         {
00677             SmallestRun = Run;
00678         }
00679 
00680         /* Advance bits */
00681         FromIndex = StartingIndex + NumberOfBits;
00682     }
00683 
00684     /* Check if we are finished */
00685     if (Run < SizeOfRunArray || !LocateLongestRuns)
00686     {
00687         /* Return the number of found runs */
00688         return Run;
00689     }
00690 
00691     while (1)
00692     {
00693         /* Look for a run */
00694         NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader,
00695                                                   FromIndex,
00696                                                   &StartingIndex);
00697 
00698         /* Nothing more found? Quit looping. */
00699         if (NumberOfBits == 0) break;
00700 
00701         /* Check if we have something to update */
00702         if (NumberOfBits > RunArray[SmallestRun].NumberOfBits)
00703         {
00704             /* Update smallest run */
00705             RunArray[SmallestRun].StartingIndex = StartingIndex;
00706             RunArray[SmallestRun].NumberOfBits = NumberOfBits;
00707 
00708             /* Loop all runs */
00709             for (Run = 0; Run < SizeOfRunArray; Run++)
00710             {
00711                 /*Is this the new smallest run? */
00712                 if (NumberOfBits < RunArray[SmallestRun].NumberOfBits)
00713                 {
00714                     /* Set it as new smallest run */
00715                     SmallestRun = Run;
00716                 }
00717             }
00718         }
00719 
00720         /* Advance bits */
00721         FromIndex += NumberOfBits;
00722     }
00723 
00724     return Run;
00725 }
00726 
00727 ULONG
00728 NTAPI
00729 RtlFindLongestRunClear(
00730     IN PRTL_BITMAP BitMapHeader,
00731     IN PULONG StartingIndex)
00732 {
00733     ULONG NumberOfBits, Index, MaxNumberOfBits = 0, FromIndex = 0;
00734 
00735     while (1)
00736     {
00737         /* Look for a run */
00738         NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader,
00739                                                   FromIndex,
00740                                                   &Index);
00741 
00742         /* Nothing more found? Quit looping. */
00743         if (NumberOfBits == 0) break;
00744 
00745         /* Was that the longest run? */
00746         if (NumberOfBits > MaxNumberOfBits)
00747         {
00748             /* Update values */
00749             MaxNumberOfBits = NumberOfBits;
00750             *StartingIndex = Index;
00751         }
00752 
00753         /* Advance bits */
00754         FromIndex += NumberOfBits;
00755     }
00756 
00757     return MaxNumberOfBits;
00758 }
00759 
00760 ULONG
00761 NTAPI
00762 RtlFindLongestRunSet(
00763     IN PRTL_BITMAP BitMapHeader,
00764     IN PULONG StartingIndex)
00765 {
00766     ULONG NumberOfBits, Index, MaxNumberOfBits = 0, FromIndex = 0;
00767 
00768     while (1)
00769     {
00770         /* Look for a run */
00771         NumberOfBits = RtlFindNextForwardRunSet(BitMapHeader,
00772                                                 FromIndex,
00773                                                 &Index);
00774 
00775         /* Nothing more found? Quit looping. */
00776         if (NumberOfBits == 0) break;
00777 
00778         /* Was that the longest run? */
00779         if (NumberOfBits > MaxNumberOfBits)
00780         {
00781             /* Update values */
00782             MaxNumberOfBits = NumberOfBits;
00783             *StartingIndex = Index;
00784         }
00785 
00786         /* Advance bits */
00787         FromIndex += NumberOfBits;
00788     }
00789 
00790     return MaxNumberOfBits;
00791 }
00792 

Generated on Fri May 25 2012 04:15:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.