Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbitmap.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
1.7.6.1
|