
/******************************************/
/*Title   : bisearch.h                    */
/*Descr   : BiSearch arithmetic implement */
/*Author  : Liu Wei                       */
/*Create  : 2006-12-13                    */
/*Version : R1V00_01                      */
/*Modify  : 2006-12-13                    */
/******************************************/
#include "memory.h"
#include "malloc.h"
#include "stdlib.h"
#include "./include/bisearch.h"

/*@ignore@*/

int BISearchReg ( BiSearchArray *pBSA, int nTotalSize , void *GetIdleNodeFunc )
{
    if( pBSA == NULL )
        exit(0);
    memset( pBSA , 0 , sizeof(BiSearchArray) );
    pBSA->nArrayCount = 0;
    pBSA->nArrayTotalLen = nTotalSize;
    pBSA->pBiArray = malloc( sizeof(BiSearch)*nTotalSize );
    memset ( pBSA->pBiArray, 0, BS_SIZE * nTotalSize );
    pBSA->GetIdleNodeFunc = (int (*)(int *))GetIdleNodeFunc;
    return 1;
}

int BISearchUnReg ( BiSearchArray * pBSA)
{
    if( pBSA !=NULL && pBSA->pBiArray != NULL )
    {
        free(pBSA->pBiArray);
        return 1;
    }
    return 0;
}

int BSearch ( BiSearchArray * pBSA, int nStart, int nEnd, LL llKey, int * nPosResult )
{
    BiSearch *pArray ;
    int  nPos = -1;
    
    if( pBSA == NULL ) 
    
    return 0;
    if( nStart < 0 || nEnd < 0 || nStart > nEnd || pBSA->nArrayCount < nStart  )
    {
        return 0;
    }
    
    pArray = pBSA->pBiArray;
    if( !pBSA->nArrayCount )
    	  return (*nPosResult = 0);
    if( nEnd > pBSA->nArrayCount-1 )
    	  nEnd = pBSA->nArrayCount-1;

    for ( nPos = nStart; nStart <= nEnd; nPos = ( nStart + nEnd ) / 2 )
    {
        if( pArray[nPos].llKey == llKey )
        {
            *nPosResult = nPos;
            return 1;
        }
        if( pArray[nPos].llKey > llKey )
        {
            nEnd = nPos - 1;
        }
        if( pArray[nPos].llKey < llKey )
        {
            nStart = nPos + 1;
        }
    }
    if( nPos != -1 && pArray[nPos].llKey < llKey )
    	  nPos++;
    *nPosResult = nPos;
    return 0;
}

int BSearchArray ( BiSearchArray * pBSA, LL llKey, int *nPosResult )
{
    if( pBSA == NULL )
        return 0;
        
    return BSearch ( pBSA, 0, (pBSA->nArrayCount > 0 ? pBSA->nArrayCount-1 : 0), llKey, nPosResult );
}

int BISInsert ( BiSearchArray * pBSA, LL llKey, int nDUPosIndex )
{
    int  nPos = -1;
    
    if( pBSA == NULL )
        return 0;
        
    //memery protect: Data Unit Index exceed Data Unit Array Length
    if( nDUPosIndex > pBSA->nArrayTotalLen || nDUPosIndex < 0)   
        return 0;

    if( pBSA->nArrayCount >= pBSA->nArrayTotalLen )     //Array Full 
        return 0;

    if( !BSearchArray ( pBSA , llKey, &nPos ) && nPos != -1 )
    {
        BiSearch *pBS = pBSA->pBiArray + nPos ;
        
        memmove ( pBS + 1, pBS , BS_SIZE * ( pBSA->nArrayCount - nPos ) );
        pBS->llKey = llKey;
        pBS->nDUPosIndex = nDUPosIndex;
        pBSA->nArrayCount++;
        return 1;

    }
    //The Key is existed, insert fail.
    return 0;
}

int BISDelete ( BiSearchArray * pBSA, LL llKey )
{
    int  nPos = -1;
    
    if( pBSA == NULL )
        return 0;

    if( pBSA->nArrayCount <= 0 )
        return 0;

    if( BSearchArray ( pBSA ,llKey, &nPos ) )
    {
        BiSearch *pBS = pBSA->pBiArray + nPos;

        memmove ( pBS, pBS + 1, BS_SIZE * ( pBSA->nArrayCount - nPos ) );
        memset ( pBSA->pBiArray + pBSA->nArrayCount, 0, BS_SIZE );
        pBSA->nArrayCount--;
        return 1;
    }
    return 0;
}

int BISSearch ( BiSearchArray * pBSA, LL llKey , int* nDUPosIndex)
{
    int nPos = -1;
    
    if( pBSA == NULL )
        return 0;
        
    if( BSearchArray ( pBSA ,llKey, &nPos ) )
    {
        *nDUPosIndex = pBSA->pBiArray[nPos].nDUPosIndex;
        if( *nDUPosIndex > pBSA->nArrayTotalLen )    
            return 0;
        return 1;
    }
    return 0;
}


int GetBISearchCount ( BiSearchArray * pBSA)
{
    if( pBSA == NULL )
        return 0;
        
    return pBSA->nArrayCount;
}

int GetDUIndex ( BiSearchArray * pBSA, int nBIIndex)
{
    if( pBSA == NULL )
        return 0;
        
    if( nBIIndex >=  pBSA->nArrayCount )
	return -1;
    else
	return pBSA->pBiArray[nBIIndex].nDUPosIndex;
}

int BISSearchMng( BiSearchArray * pBSA, BIS_OP mng_type,LL llkey, int* nDUIndex )
{
    switch( mng_type )
    {
      case BIS_INIT:
    	   return BISInsert( pBSA , llkey , *nDUIndex );
      case BIS_SEARCH:
    	   return BISSearch( pBSA , llkey ,  nDUIndex ); 
      case BIS_INSERT:
      	   if( pBSA->GetIdleNodeFunc != NULL && pBSA->GetIdleNodeFunc( nDUIndex ) )
      	       return BISInsert( pBSA , llkey , *nDUIndex );
    	   break;
      case BIS_DELETE:
      	   return BISDelete( pBSA, llkey);
    	   break;
      default:
      	   return 0;
    }
    return 1;
}

/*@end@*/

