apiht.c

来自「用c/c++实现的一个CMPP API」· C语言 代码 · 共 1,753 行 · 第 1/4 页

C
1,753
字号
    {        if( pHTAddr->pBucket[i] == NULL )        {            continue;        }        /*哈希表的桶的首指针数组*/        fprintf( fD, "\tpBucket[%d][x]=%x\n", i, (int)pHTAddr->pBucket[i] );            vListChain( fp, pHTAddr->pBucket[i] );    }    /*空闲的内存管理队列*/    fprintf( fD, "RecFreeQ.nHead=%d\n", pHTAddr->RecFreeQ.nHead );     fprintf( fD, "RecFreeQ.nTail=%d\n", pHTAddr->RecFreeQ.nTail );      nMemCellSum = pHTAddr->RecFreeQ.nHead - pHTAddr->RecFreeQ.nTail;        nMemCellSum = (nMemCellSum>=0)? nMemCellSum: pHTAddr->nMsgMaxNum+nMemCellSum ;    /*内存管理队列空闲的数目*/    fprintf( fD, "FreeMemCell=%d\n", nMemCellSum );             /*内存管理队列使用的数目*/    fprintf( fD, "UsedMemCell=%d\n", pHTAddr->nMsgMaxNum-nMemCellSum-1 );       fprintf( fD, "----end of Queue Status----\n" );                     fflush( fD );       return ;            }/**描述:根据pKey的信息产生bucket的定位信息*输出:>=0 成功 , <0 失败 */static int  nMakeKey( void* pKey, int nLen, int nBucket ){    unsigned char* pChar;    int i;    int nSum;   /* 总和 */    int nRet;   /* 返回值 */    int     nCurValue;        if( pKey == NULL || nLen <= 0 )    return SHMHT_FAILED ;        pChar   = (unsigned char*)pKey;    nSum    = 0;    for( i=1; i<=nLen; i++ )    {        nCurValue = ((unsigned char)(*pChar)+1)*i*i*i;        nSum += nCurValue;        pChar++;    }    nRet = ( (unsigned int)nSum)%nBucket;    return nRet;}/**描述: 模拟malloc的功能,对固定内存区的内存队列管理                    (固定内存包)*输出: >0 成功 , NULL 失败*/static recHashCell*  pHTMalloc( recHTCell* pHTLink ){    int nTail;      /*内存管理队列的尾*/    recHashCell *pCell; /*要返回的指针*/        if( pHTLink == NULL )    return NULL;    /*已经空了,没有可用的空间*/    if( pHTLink->RecFreeQ.nTail == pHTLink->RecFreeQ.nHead )     {        return NULL;    }        /*空闲的队列*/    nTail = pHTLink->RecFreeQ.nTail;    /*尾增加*/    pHTLink->RecFreeQ.nTail = (pHTLink->RecFreeQ.nTail+1)%pHTLink->nMsgMaxNum;         pCell = (recHashCell*)pHTLink->RecFreeQ.pvAddr[nTail];    /*置位清空*/    //(recHashCell*)(pHTLink->RecFreeQ.pvAddr[nTail]) = NULL;         return (recHashCell*)pCell;}/**描述: 模拟free的功能,对固定内存区的内存队列管理*                 (固定内存包)*输出:SHMHT_OK 成功 , SHMHT_FAILED 失败 */static int   nHTFree( recHTCell* pHTLink, recHashCell* pCell ){    int nHead; /*内存管理队列的头*/        if( pHTLink == NULL || pCell == NULL )    return SHMHT_FAILED;        nHead = pHTLink->RecFreeQ.nHead;    nHead = (nHead+1)%pHTLink->nMsgMaxNum;    if( nHead == pHTLink->RecFreeQ.nTail )/*错误发生了 */    {        ErrMsg( "Error When nHTFree More Free Cell Than FIFO Max Number\n" );        return SHMHT_FAILED ;    }    /*    *清空包地址空间内容    */    //memset( pCell, 0, sizeof( recHashCell ) );    memset( pCell->pvPck, 0, pHTLink->nSize );    memset( pCell->pvKey, 0, pHTLink->nKeySize );    /*    *释放空间给 空闲的队列    */    pHTLink->RecFreeQ.pvAddr[nHead] = pCell;    /*头增加*/    pHTLink->RecFreeQ.nHead = (pHTLink->RecFreeQ.nHead+1)%pHTLink->nMsgMaxNum;         return SHMHT_OK;       }/**查找到和KEY匹配的包*返回 !=NULL 成功,NULL ,失败*/static recHashCell*   pCellSearchByKey(const recHTCell* pHTLink, int  nBucket,                                        void* pvKeyAddr,int  nKeySize ){    recHashCell* pMarkCell; /*哨兵结点*/    recHashCell* pCell;    /*变化的结点*/        if ( pHTLink == NULL || pvKeyAddr == NULL || nKeySize <= 0 )    return NULL;        pMarkCell = pHTLink->pBucket[nBucket];             if( pMarkCell == NULL )    return NULL;        pCell = pMarkCell->pPrev; /*从后往前查,保证先进先出*/        while( 1 )    {                    /*两个条件都满足*/        if ( pCell->nKeySize == nKeySize &&             memcmp( (void* )pCell->pvKey, pvKeyAddr, nKeySize ) == 0            )        return pCell;                /*从后往前查,保证先进先出*/        pCell = pCell->pPrev;                if( pCell == pMarkCell->pPrev )        break;        }    return NULL;} /**查找到和包内容匹配的包(在一个桶中)*返回 !=NULL 成功,NULL ,失败*/static recHashCell*     pCellSearchByPck( const recHTCell* pHTLink, int  nBucket,                                           void* pvPckAddr, int  nPckSize ){    recHashCell* pMarkCell; /*哨兵结点*/    recHashCell* pCell;    /*变化的结点*/        if ( pHTLink == NULL || pvPckAddr == NULL || nPckSize <= 0 )    return NULL;        pMarkCell = pHTLink->pBucket[nBucket];             if( pMarkCell == NULL )    return NULL;        pCell = pMarkCell->pPrev; /*从后往前查,保证先进先出*/        while( 1 )    {                /*两个条件都满足*/        if ( pCell->nPckSize == nPckSize &&             memcmp( (void* )pCell->pvPck, pvPckAddr, nPckSize ) == 0            )        return pCell;                /*从后往前查,保证先进先出*/        pCell = pCell->pPrev;                if( pCell == pMarkCell->pPrev )        break;        }    return NULL;    }/**查找到和包内容匹配的包(全部桶中)*返回 !=NULL 成功,NULL ,失败*/static recHashCell*     pCellSearchByPckInAllBucket(const recHTCell* pHTLink,                                                        void* pvPckAddr,                                                        int  nPckSize,                                                        int* pnBucket ){    int nBucket;    /*桶的变量*/    recHashCell*    pRetCell = NULL;/*返回的值*/        if ( pHTLink == NULL || pvPckAddr == NULL || nPckSize <= 0 )    return NULL;            for( nBucket=0; nBucket < pHTLink->nBucket; nBucket++ )    {        pRetCell = pCellSearchByPck( pHTLink, nBucket, pvPckAddr, nPckSize );        if( pRetCell != NULL ) /*找到一个匹配的包*/        {            break;        }    }    /*找到一个匹配的包将bucket输出*/    if( pRetCell != NULL && pnBucket != NULL )    {        *pnBucket = nBucket;    }       return pRetCell;    }/**描述: 检查输入参数合法性*输入: pHLink HT表句柄    nKeySize KEY 长度 nCellSize 包的长度。 *输出: *返回: SHMHT_OK 成功       SHMHT_FAILED 错误,*/int  nCheckInputSize( int nKeySize, int nCellSize, const recHTCell* pHTLink ){    if( pHTLink->nKeySize != nKeySize || pHTLink->nSize != nCellSize )     {        ErrMsg( " input nKeySize[%d], nCellSize[%d] != %d, %d \n",                       nKeySize, nCellSize, pHTLink->nKeySize,                       pHTLink->nSize );        return SHMHT_FAILED ;    }    else    {        return SHMHT_OK;    }}   /**描述: 删除HASH表内存一条记录(通过包内容)*输入: pHLink HT表句柄    pvCellAddr 删除的包指针,nCellSize 包的长度。 *输出: pvKeyAddr KEY值指针, nKeySize KEY长度*返回: SHMHT_OK 成功        SHMHT_FAILED 错误,*/int  nDelACellByPckApi( void* pvHTLink, void* pvKeyAddr,                     int nKeySize, void* pvCellAddr,                     int nCellSize ){    int nBucket; /*bucket的定位信息*/    //int nRet;    recHTCell* pHTLink;    recHashCell* pCell; /*包内存地址*/        if ( pvHTLink == NULL || pvCellAddr == NULL || nCellSize <= 0 )    return SHMHT_FAILED;        pHTLink = (recHTCell*)pvHTLink ;    /*    *定位bucket    */    /*    *查找到和KEY匹配的包    *返回 >0 成功,NULL ,失败    */    pCell = pCellSearchByPckInAllBucket( pHTLink, pvCellAddr, nCellSize, &nBucket );     if( pCell == NULL )    return SHMHT_FAILED;    /*    *在HASH表的一个bucket删除一个记录。    */    return  nDelABucketCell( pHTLink, nBucket, pCell, NULL, 0, pvKeyAddr, nKeySize );    }/**描述:查找HASH表内存一条记录*输入:pHLink HT表句柄,pvKeyAddr KEY值指针, nKeySize KEY长度,        nCellSize 包的长度。 *输出:pvCellAddr 查找的包指针*返回:SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOFOUND 没有该包,*/int  nSerACellApi( void* pvHTLink, void* pvKeyAddr, int nKeySize,                 void* pvCellAddr, int nCellSize ){    int nBucket; /*bucket的定位信息*/    int nRet;    recHTCell* pHTLink;    recHashCell* pCell; /*包内存地址*/        if ( pvHTLink == NULL || pvKeyAddr == NULL ||          nKeySize <= 0 || pvCellAddr == NULL ||          nCellSize <= 0 )    return SHMHT_FAILED;        pHTLink = (recHTCell*)pvHTLink ;        /*    *检查长度合法性    */    if( nCheckInputSize( nKeySize, nCellSize, pHTLink ) < 0 )    {        return SHMHT_FAILED;    }            /*    *定位bucket    */    nBucket = nMakeKey( pvKeyAddr, nKeySize, pHTLink->nBucket );        if ( nBucket < 0 )    {        ErrMsg( "Error when nMakeKey , nBucket = %d",                 nBucket );        return SHMHT_FAILED ;    }    /*    *查找到和KEY匹配的包    *返回 >0 成功,NULL ,失败    */        pCell = pCellSearchByKey( pHTLink, nBucket, pvKeyAddr, nKeySize );     if( pCell == NULL )    return SHMHT_NOFOUND;            /*    *在HASH表的一个bucket把内容复制出来    */    nRet = nSerABucketCell( pHTLink, nBucket, pCell, pvCellAddr, nCellSize );    if ( nRet < 0 )    {        ErrMsg( "Error when nSerABucketCell, nRet = %d", nRet );        return SHMHT_FAILED ;    }        return SHMHT_OK ;}/**描述:更新HASH表内存一条记录*输入:pHLink HT表句柄,pvKeyAddr KEY值指针, nKeySize KEY长度,        pvCellAddr 更新的包指针,nCellSize 包的长度。 *输出: 无*返回:SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOFOUND 没有该包,*/int  nUpdateACellApi( void* pvHTLink, void* pvKeyAddr,                   int nKeySize, void* pvCellAddr,                   int nCellSize ){    int nBucket; /*bucket的定位信息*/    //int nRet;    recHTCell* pHTLink;    recHashCell* pCell; /*包内存地址*/        if ( pvHTLink == NULL || pvKeyAddr == NULL ||           nKeySize <= 0 || pvCellAddr == NULL || nCellSize <= 0 )    return SHMHT_FAILED;        pHTLink = (recHTCell*)pvHTLink ;        /*    *检查长度合法性    */    if( nCheckInputSize( nKeySize, nCellSize, pHTLink ) < 0 )    {        return SHMHT_FAILED ;    }        /*    *定位bucket    */    nBucket = nMakeKey( pvKeyAddr, nKeySize, pHTLink->nBucket );    if ( nBucket < 0 )    {        ErrMsg( "Error when nMakeKey , nBucket = %d",                 nBucket );        return SHMHT_FAILED ;    }    /*    *查找到和KEY匹配的包    *返回 >0 成功,NULL ,失败    */    pCell = pCellSearchByKey( pHTLink, nBucket, pvKeyAddr, nKeySize );     if( pCell == NULL )    return SHMHT_NOFOUND;            /*    *在HASH表的一个bucket把内容更新    */    return  nUpdateABucketCell( pHTLink, nBucket, pCell, pvCellAddr, nCellSize );    }/**描述:通过函数指针更新HASH表一条记录, *                如果没有该KEY的包,添加进去*输入:pHLink HT表句柄,pvKeyAddr KEY值指针, nKeySize KEY长度,       int (*pfnPckFunc)( void*, size_t )更新函数的函数指针 void* 为包指针,       size_t为包的长度       注意 pfnPckFunc()为外部使用的更改内存内容的函数,                    可以任意修改内存中数据*输出: 无*返回:SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOSPACE 没有内存空间*/int  nAddOrUpdateACellByFunc( void* pvHTLink, void* pvKeyAddr, int nKeySize,                                 void* pvCellAddr, int nCellSize,                                int (*pfnPckFunc)( void*, size_t ) ){    int nRet;        nRet = nUpdateACellByFunc( pvHTLink, pvKeyAddr, nKeySize,                                pfnPckFunc   );                                    if( nRet != SHMHT_OK && nRet != SHMHT_NOFOUND )    {        ErrMsg( "Error When nUpdateACellByFunc " );        return SHMHT_FAILED ;    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?