|
Packit |
857059 |
/* BEGIN_ICS_COPYRIGHT6 ****************************************
|
|
Packit |
857059 |
|
|
Packit |
857059 |
Copyright (c) 2015, Intel Corporation
|
|
Packit |
857059 |
|
|
Packit |
857059 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
857059 |
modification, are permitted provided that the following conditions are met:
|
|
Packit |
857059 |
|
|
Packit |
857059 |
* Redistributions of source code must retain the above copyright notice,
|
|
Packit |
857059 |
this list of conditions and the following disclaimer.
|
|
Packit |
857059 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
857059 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
857059 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
857059 |
* Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
857059 |
may be used to endorse or promote products derived from this software
|
|
Packit |
857059 |
without specific prior written permission.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
857059 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
857059 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit |
857059 |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
Packit |
857059 |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
857059 |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
857059 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
Packit |
857059 |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit |
857059 |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
857059 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
** END_ICS_COPYRIGHT6 ****************************************/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#include "ibitvector.h"
|
|
Packit |
857059 |
#include "imemory.h"
|
|
Packit |
857059 |
#include "imath.h"
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Make a memory tag of 'ivec' for ivector.
|
|
Packit |
857059 |
#define VEC_MEM_TAG MAKE_MEM_TAG( i, v, e, c )
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// bit vector access methods
|
|
Packit |
857059 |
// These methods are an attempt to follow the functionality of the C++ STL.
|
|
Packit |
857059 |
// The names and behavior are obviously not exact matches, but hopefully,
|
|
Packit |
857059 |
// close enough to make those familiar with the ANSI standard comfortable.
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorInitState
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function performs basic bit vector initialization. This function cannot
|
|
Packit |
857059 |
// fail.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorInitState(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
MemoryClear( pBitVector, sizeof( BIT_VECTOR ) );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorInit
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function initializes the bit vector. New bits in the bit vector are
|
|
Packit |
857059 |
// initialized to 0.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
// InitialSize - prefered initial number of bits
|
|
Packit |
857059 |
// GrowSize - number of bits to allocate when incrementally growing
|
|
Packit |
857059 |
// the bit vector (will round up to multiple of processor
|
|
Packit |
857059 |
// word size)
|
|
Packit |
857059 |
// MaxSize - maximum number of bits in bit vector, 0 -> no limit
|
|
Packit |
857059 |
// Context - Context value passed to the callbacks.
|
|
Packit |
857059 |
// IsPageable - TRUE indicates the bit vector should use pageable memory
|
|
Packit |
857059 |
// FALSE indicates the bit vector should used non-paged memory
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINSUFFICIENT_MEMORY - bit vector is initialized to zero size
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
BitVectorInit(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN const uint32 InitialSize,
|
|
Packit |
857059 |
IN const uint32 GrowSize,
|
|
Packit |
857059 |
IN const uint32 MaxSize,
|
|
Packit |
857059 |
IN boolean IsPageable )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Status;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
ASSERT( GrowSize );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
BitVectorInitState( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pBitVector->m_GrowSize = ROUNDUPP2(GrowSize, _BIT_VECTOR_ENTRY_SIZE);
|
|
Packit |
857059 |
pBitVector->m_MaxSize = (MaxSize == 0)? IB_UINT32_MAX : MaxSize;
|
|
Packit |
857059 |
pBitVector->m_Pageable = IsPageable;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// get the storage needed by the user
|
|
Packit |
857059 |
Status = BitVectorSetSize( pBitVector, MIN(InitialSize, pBitVector->m_MaxSize) );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return( Status );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorDestroy
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function deallocates all allocated memory associated with the bit vector.
|
|
Packit |
857059 |
// The bit vector is left initialized to zero size. This function does not fail.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorDestroy(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Destroy the page bit vector.
|
|
Packit |
857059 |
if( pBitVector->m_pBitArray )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
MemoryDeallocate( pBitVector->m_pBitArray );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// reset internal state
|
|
Packit |
857059 |
pBitVector->m_Capacity = 0;
|
|
Packit |
857059 |
pBitVector->m_GrowSize = 0;
|
|
Packit |
857059 |
pBitVector->m_Size = 0;
|
|
Packit |
857059 |
pBitVector->m_pBitArray = NULL;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorAt
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function returns the bit at the specified index.
|
|
Packit |
857059 |
// Range checking is performed. Provides constant time access.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector.
|
|
Packit |
857059 |
// Index - Index of bit to get.
|
|
Packit |
857059 |
// pValue - Pointer to storage for the bit to be returned.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// pValue - Copy of the desired bit.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINVALID_SETTING Index out of range.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
BitVectorAt(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN const uint32 Index,
|
|
Packit |
857059 |
OUT uint8* pValue )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
ASSERT( pBitVector ); // Other asserts are in BitVectorGet
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Range check
|
|
Packit |
857059 |
if( Index >= pBitVector->m_Size )
|
|
Packit |
857059 |
return( FINVALID_PARAMETER );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
*pValue = BitVectorGet( pBitVector, Index );
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorSet
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function sets the bit at the specified index. The array grows as
|
|
Packit |
857059 |
// necessary.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector.
|
|
Packit |
857059 |
// Index - Index of bit to get.
|
|
Packit |
857059 |
// Value - value to set the bit to
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINSUFFICIENT_MEMORY The array could not be resized to accomodate the
|
|
Packit |
857059 |
// specified bit.
|
|
Packit |
857059 |
// FINSUFFICIENT_RESOURCES - would grow vector beyond max size
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
BitVectorSet(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN const uint32 Index,
|
|
Packit |
857059 |
IN const uint8 Value )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Status;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Determine if the bit vector has room for this bit.
|
|
Packit |
857059 |
if( Index >= pBitVector->m_Size )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// Resize to accomodate the given index.
|
|
Packit |
857059 |
Status = BitVectorSetSize( pBitVector, Index + 1 );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Check for failure on or before the given index.
|
|
Packit |
857059 |
if( (Status != FSUCCESS) && (pBitVector->m_Size <= Index) )
|
|
Packit |
857059 |
return( Status );
|
|
Packit |
857059 |
if (pBitVector->m_Size <= Index) {
|
|
Packit |
857059 |
return( FINSUFFICIENT_MEMORY );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// At this point, the array is guaranteed to be big enough
|
|
Packit |
857059 |
if (Value)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pBitVector->m_pBitArray[_BitVectorSubscript(Index)] |= _BitVectorMask(Index);
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
pBitVector->m_pBitArray[_BitVectorSubscript(Index)] &= ~_BitVectorMask(Index);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorSetCapacity
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function reserves capacity in the bit vector to the specified number of
|
|
Packit |
857059 |
// bits. This function can only fail if the new capacity is larger than
|
|
Packit |
857059 |
// the old capacity. If the new capacity is less than the old, no action
|
|
Packit |
857059 |
// is taken. When growing the capacity, new bits will have value 0.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
// NewCapacity - Number of bits reserved in the array
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINSUFFICIENT_MEMORY - bit vector is left unaltered
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
BitVectorSetCapacity(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN uint32 NewCapacity )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
unsigned *pNewBitArray;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (NewCapacity > pBitVector->m_MaxSize)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
NewCapacity = pBitVector->m_MaxSize;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Do we have to do anything here?
|
|
Packit |
857059 |
if( NewCapacity <= pBitVector->m_Capacity )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// Nope
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Allocate our bit array.
|
|
Packit |
857059 |
pNewBitArray = (unsigned*)MemoryAllocateAndClear( ((NewCapacity+_BIT_VECTOR_ENTRY_SIZE)/_BIT_VECTOR_ENTRY_SIZE) * sizeof( unsigned ),
|
|
Packit |
857059 |
pBitVector->m_Pageable, VEC_MEM_TAG );
|
|
Packit |
857059 |
if( !pNewBitArray )
|
|
Packit |
857059 |
return( FINSUFFICIENT_MEMORY );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if( pBitVector->m_pBitArray )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// Copy the old bit array into the new.
|
|
Packit |
857059 |
MemoryCopy( pNewBitArray, pBitVector->m_pBitArray,
|
|
Packit |
857059 |
((pBitVector->m_Capacity+_BIT_VECTOR_ENTRY_SIZE)/_BIT_VECTOR_ENTRY_SIZE) * sizeof( unsigned ) );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Free the old bit array.
|
|
Packit |
857059 |
MemoryDeallocate( pBitVector->m_pBitArray );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Set the new array.
|
|
Packit |
857059 |
pBitVector->m_pBitArray = pNewBitArray;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Update the bit vector with the new capacity.
|
|
Packit |
857059 |
pBitVector->m_Capacity = NewCapacity;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorSetSize
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function resizes the bit vector to the specified number of
|
|
Packit |
857059 |
// bits. This function can only fail if the new size is larger than
|
|
Packit |
857059 |
// the old capacity.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
// Size - new number of bits in the the array
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINSUFFICIENT_MEMORY - bit vector will have at least as many bits
|
|
Packit |
857059 |
// as prior to the call. Use BitVectorGetSize()
|
|
Packit |
857059 |
// to determine the number of bits
|
|
Packit |
857059 |
// FINSUFFICIENT_RESOURCES - would grow vector beyond max size
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
BitVectorSetSize(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN const uint32 Size )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Status;
|
|
Packit |
857059 |
uint32 NewCapacity;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if( Size == pBitVector->m_Size )
|
|
Packit |
857059 |
return( FSUCCESS ); // no change
|
|
Packit |
857059 |
if (Size > pBitVector->m_MaxSize)
|
|
Packit |
857059 |
return( FINSUFFICIENT_RESOURCES );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Determine if the bit vector has room.
|
|
Packit |
857059 |
if( Size >= pBitVector->m_Capacity )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// keep capacity as a multiple of GrowSize
|
|
Packit |
857059 |
NewCapacity = ROUNDUP(Size, pBitVector->m_GrowSize);
|
|
Packit |
857059 |
Status = BitVectorSetCapacity( pBitVector, NewCapacity );
|
|
Packit |
857059 |
if( Status != FSUCCESS )
|
|
Packit |
857059 |
return( Status );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pBitVector->m_Size = Size;
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorSetMinSize
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function resizes the bit vector to the specified number of
|
|
Packit |
857059 |
// bits only if the current number of bits in the array is fewer
|
|
Packit |
857059 |
// than the specified size.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - Pointer to bit vector
|
|
Packit |
857059 |
// MinSize - at least the number of bitbits needed in the array
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINSUFFICIENT_MEMORY - bit vector is left unaltered
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
FSTATUS BitVectorSetMinSize(
|
|
Packit |
857059 |
IN BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN const uint32 MinSize )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if( MinSize > pBitVector->m_Size )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// We have to resize the array
|
|
Packit |
857059 |
return( BitVectorSetSize( pBitVector, MinSize ) );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// We didn't have to do anything
|
|
Packit |
857059 |
return( FSUCCESS );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorApplyFunc
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function calls the user supplied function for each item in the bit vector.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// The called function has the form:
|
|
Packit |
857059 |
// void ApplyFunc( uint32 Index, uint8 Value, void *Context );
|
|
Packit |
857059 |
// where:
|
|
Packit |
857059 |
// Index = index of this bit
|
|
Packit |
857059 |
// Value = value of bit at this Index in the array
|
|
Packit |
857059 |
// Context = user supplied context
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// pfnCallback - callback called for each non-NULL bit
|
|
Packit |
857059 |
// Context - context to pass to callback function
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorApplyFunc(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN BITVEC_APPLY_FUNC pfnCallback,
|
|
Packit |
857059 |
IN void* const Context )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
return BitVectorApplyFuncRange(pBitVector, pfnCallback, Context,
|
|
Packit |
857059 |
0, pBitVector->m_Size);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorApplyFuncRange
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function calls the user supplied function for each item in the bit vector
|
|
Packit |
857059 |
// across the given range of indexes of the bit vector.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// The called function has the form:
|
|
Packit |
857059 |
// void ApplyFunc( uint32 Index, uint8 Value, void *Context );
|
|
Packit |
857059 |
// where:
|
|
Packit |
857059 |
// Index = index of this bit
|
|
Packit |
857059 |
// Value = value of bit at this Index in the array
|
|
Packit |
857059 |
// Context = user supplied context
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// pfnCallback - callback called for each non-NULL bit
|
|
Packit |
857059 |
// Context - context to pass to callback function
|
|
Packit |
857059 |
// StartIndex - Index to start at
|
|
Packit |
857059 |
// EndIndexP1 - Index to stop at (exclusive)
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorApplyFuncRange(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN BITVEC_APPLY_FUNC pfnCallback,
|
|
Packit |
857059 |
IN void* const Context,
|
|
Packit |
857059 |
IN uint32 StartIndex,
|
|
Packit |
857059 |
IN uint32 EndIndexP1 )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 i;
|
|
Packit |
857059 |
uint8 Value;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
ASSERT( pfnCallback );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
i = StartIndex;
|
|
Packit |
857059 |
if (EndIndexP1 > pBitVector->m_Size)
|
|
Packit |
857059 |
EndIndexP1 = pBitVector->m_Size;
|
|
Packit |
857059 |
for( ; i < EndIndexP1; ++i )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
Value = BitVectorGet( pBitVector, i );
|
|
Packit |
857059 |
pfnCallback( i, Value, Context );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorApplyFuncSelected
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function calls the user supplied function for each bit in the bit vector,
|
|
Packit |
857059 |
// which matches Value, starting from the beginning of the array.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// The called function has the form:
|
|
Packit |
857059 |
// void ApplyFunc( uint32 Index, uint8 Value, void *Context );
|
|
Packit |
857059 |
// where:
|
|
Packit |
857059 |
// Index = index of this bit
|
|
Packit |
857059 |
// Value = value of bit at this Index in the array
|
|
Packit |
857059 |
// Context = user supplied context
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// pfnCallback - callback called for each non-NULL bit
|
|
Packit |
857059 |
// Context - context to pass to callback function
|
|
Packit |
857059 |
// Value - Bit values to execute pfnCallback for
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorApplyFuncSelected(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN BITVEC_APPLY_FUNC pfnCallback,
|
|
Packit |
857059 |
IN void* const Context,
|
|
Packit |
857059 |
IN uint8 Value )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
return BitVectorApplyFuncSelectedRange(pBitVector, pfnCallback, Context,
|
|
Packit |
857059 |
Value, 0, pBitVector->m_Size);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorApplyFuncSelectedRange
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function calls the user supplied function for each bit in the bit vector,
|
|
Packit |
857059 |
// across the given range of indexes of the bit vector,
|
|
Packit |
857059 |
// which matches Value, starting from the beginning of the array.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// The called function has the form:
|
|
Packit |
857059 |
// void ApplyFunc( uint32 Index, uint8 Value, void *Context );
|
|
Packit |
857059 |
// where:
|
|
Packit |
857059 |
// Index = index of this bit
|
|
Packit |
857059 |
// Value = value of bit at this Index in the array
|
|
Packit |
857059 |
// Context = user supplied context
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// pfnCallback - callback called for each non-NULL bit
|
|
Packit |
857059 |
// Context - context to pass to callback function
|
|
Packit |
857059 |
// Value - Bit values to execute pfnCallback for
|
|
Packit |
857059 |
// StartIndex - Index to start at
|
|
Packit |
857059 |
// EndIndexP1 - Index to stop at (exclusive)
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
BitVectorApplyFuncSelectedRange(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN BITVEC_APPLY_FUNC pfnCallback,
|
|
Packit |
857059 |
IN void* const Context,
|
|
Packit |
857059 |
IN uint8 Value,
|
|
Packit |
857059 |
IN uint32 StartIndex,
|
|
Packit |
857059 |
IN uint32 EndIndexP1 )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 i;
|
|
Packit |
857059 |
uint8 Val;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
ASSERT( pfnCallback );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
i = StartIndex;
|
|
Packit |
857059 |
if (EndIndexP1 > pBitVector->m_Size)
|
|
Packit |
857059 |
EndIndexP1 = pBitVector->m_Size;
|
|
Packit |
857059 |
for( ; i < EndIndexP1; ++i )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
Val = BitVectorGet( pBitVector, i );
|
|
Packit |
857059 |
if (Value == Val)
|
|
Packit |
857059 |
pfnCallback( i, Value, Context );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorFindFromStart
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function searches the Bit Vector for the given value
|
|
Packit |
857059 |
// starting from the beginning of the bit vector, until a bit matching
|
|
Packit |
857059 |
// Value is found
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// Value - bit value to find
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// Index value where the first bit with the given value was found.
|
|
Packit |
857059 |
// If the callback given value was never found,
|
|
Packit |
857059 |
// then the return value = the size of the bit vector.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
uint32
|
|
Packit |
857059 |
BitVectorFindFromStart(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN uint8 Value )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
return BitVectorFindRange(pBitVector, Value, 0, pBitVector->m_Size);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorFindFromIndex
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function searches the Bit Vector for the given value
|
|
Packit |
857059 |
// starting from the given index of the bit vector, until a bit matching
|
|
Packit |
857059 |
// Value is found. Search proceeds forward (increasing indexes).
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// Value - bit value to find
|
|
Packit |
857059 |
// Index - Index to start at
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// Index value where the first bit with the given value was found.
|
|
Packit |
857059 |
// If the given value was never found,
|
|
Packit |
857059 |
// then the return value = the size of the bit vector.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
uint32
|
|
Packit |
857059 |
BitVectorFindFromIndex(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN uint8 Value,
|
|
Packit |
857059 |
IN uint32 Index )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
return BitVectorFindRange(pBitVector, Value, Index, pBitVector->m_Size);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorFindRange
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function searches the Bit Vector for the given value
|
|
Packit |
857059 |
// across the given range of indexes of the bit vector, until a bit matching
|
|
Packit |
857059 |
// Value is found. Search proceeds forward (increasing indexes).
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// Value - bit value to find
|
|
Packit |
857059 |
// StartIndex - Index to start at
|
|
Packit |
857059 |
// EndIndexP1 - Index to stop at (exclusive)
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// Index value where the first bit with the given value was found.
|
|
Packit |
857059 |
// If the given value was never found,
|
|
Packit |
857059 |
// then the return value = EndIndexP1
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
uint32
|
|
Packit |
857059 |
BitVectorFindRange(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN uint8 Value,
|
|
Packit |
857059 |
IN uint32 StartIndex,
|
|
Packit |
857059 |
IN uint32 EndIndexP1 )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 i;
|
|
Packit |
857059 |
uint32 *pEntry;
|
|
Packit |
857059 |
uint32 mask;
|
|
Packit |
857059 |
uint32 inc;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// for speed we unroll the Value test and do 32 bits at a time
|
|
Packit |
857059 |
i = StartIndex;
|
|
Packit |
857059 |
if (EndIndexP1 > pBitVector->m_Size)
|
|
Packit |
857059 |
EndIndexP1 = pBitVector->m_Size;
|
|
Packit |
857059 |
pEntry = &pBitVector->m_pBitArray[_BitVectorSubscript(i)];
|
|
Packit |
857059 |
// First word is special case with smaller mask and increment
|
|
Packit |
857059 |
inc = _BIT_VECTOR_ENTRY_SIZE-_BitVectorMaskShift(i);
|
|
Packit |
857059 |
mask = ~0<<_BitVectorMaskShift(i);
|
|
Packit |
857059 |
if (Value)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
while(i < EndIndexP1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// expect optimizes the looping case
|
|
Packit |
857059 |
if (IB_EXPECT_FALSE((*pEntry & mask) != 0))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// this is the entry with our bit
|
|
Packit |
857059 |
while(i < EndIndexP1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if (*pEntry & _BitVectorMask(i))
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
i++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
++pEntry;
|
|
Packit |
857059 |
i+=inc;
|
|
Packit |
857059 |
inc = _BIT_VECTOR_ENTRY_SIZE;
|
|
Packit |
857059 |
mask = ~0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
while(i < EndIndexP1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// expect optimizes the looping case
|
|
Packit |
857059 |
if (IB_EXPECT_FALSE((*pEntry & mask) != mask))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// this is the entry with our bit
|
|
Packit |
857059 |
while(i < EndIndexP1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if (0 == (*pEntry & _BitVectorMask(i)))
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
i++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
++pEntry;
|
|
Packit |
857059 |
i+=inc;
|
|
Packit |
857059 |
inc = _BIT_VECTOR_ENTRY_SIZE;
|
|
Packit |
857059 |
mask = ~0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
done:
|
|
Packit |
857059 |
// In case EndIndexP1 is not a multiple of 32, and we over incremented in the outer loop
|
|
Packit |
857059 |
if (i > EndIndexP1) i = EndIndexP1;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
DEBUG_ASSERT((EndIndexP1 == i) || (Value && BitVectorGet(pBitVector, i)) || (!Value && !BitVectorGet(pBitVector, i)));
|
|
Packit |
857059 |
return( i );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
// BitVectorFindFromEnd
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Description:
|
|
Packit |
857059 |
// This function searches the Bit Vector for the given value
|
|
Packit |
857059 |
// starting from the end of the bit vector, until a bit matching
|
|
Packit |
857059 |
// Value is found
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Inputs:
|
|
Packit |
857059 |
// pBitVector - pointer to bit vector to iterate through
|
|
Packit |
857059 |
// Value - bit value to find
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Outputs:
|
|
Packit |
857059 |
// None.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Returns:
|
|
Packit |
857059 |
// Index value where the first bit with the given value was found.
|
|
Packit |
857059 |
// If the callback given value was never found,
|
|
Packit |
857059 |
// then the return value = the size of the bit vector.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
857059 |
uint32
|
|
Packit |
857059 |
BitVectorFindFromEnd(
|
|
Packit |
857059 |
IN const BIT_VECTOR* const pBitVector,
|
|
Packit |
857059 |
IN uint8 Value )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 i;
|
|
Packit |
857059 |
uint32 *pEntry;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pBitVector );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// for speed we unroll the Value test and do 32 bits at a time
|
|
Packit |
857059 |
i = pBitVector->m_Size;
|
|
Packit |
857059 |
pEntry = &pBitVector->m_pBitArray[_BitVectorSubscript(i)];
|
|
Packit |
857059 |
if (Value)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
for( ; i; i-=32, --pEntry)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// expect optimizes the looping case
|
|
Packit |
857059 |
if (IB_EXPECT_FALSE(*pEntry))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// this is the entry with our bit
|
|
Packit |
857059 |
for (; i; --i)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if (*pEntry & _BitVectorMask(i))
|
|
Packit |
857059 |
goto found;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
goto notfound;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
for( ; i; i-=32, --pEntry)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// expect optimizes the looping case
|
|
Packit |
857059 |
if (IB_EXPECT_FALSE(*pEntry != 0xffffffff))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// this is the entry with our bit
|
|
Packit |
857059 |
for (; i; --i)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if (0 == (*pEntry & _BitVectorMask(i)))
|
|
Packit |
857059 |
goto found;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
goto notfound;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
notfound:
|
|
Packit |
857059 |
return (pBitVector->m_Size);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
found:
|
|
Packit |
857059 |
return( i );
|
|
Packit |
857059 |
}
|