apiht.c

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

C
1,753
字号
        if( nRet == SHMHT_NOFOUND ) /* Hash Table 没有以该KEY的记录,就添加进去 */    {        nRet = nAddACellApi( pvHTLink, pvKeyAddr,  nKeySize,  pvCellAddr,  nCellSize );        if( nRet != SHMHT_OK  && nRet != SHMHT_NOSPACE )        {            ErrMsg( "Error When nAddACellApi , nRet = %d ", nRet );            return SHMHT_FAILED;        }        return nRet;    /* 0 or -3 */    }        return SHMHT_OK;       }                            /**描述:通过函数指针更新HASH表一条记录*输入:pHLink HT表句柄,pvKeyAddr KEY值指针, nKeySize KEY长度,       int (*pfnPckFunc)( void*, size_t )更新函数的函数指针 void* 为包指针,       size_t为包的长度       注意 pfnPckFunc()为外部使用的更改内存内容的函数,       可以任意修改内存中数据*输出: 无*返回:SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOFOUND 没有该包,*/int  nUpdateACellByFunc( void* pvHTLink, void* pvKeyAddr, int nKeySize,                        int (*pfnPckFunc)( void*, size_t ) ){    int nBucket; /*bucket的定位信息*/    int nRet;    recHTCell* pHTLink;    recHashCell* pCell; /*包内存地址*/        if ( pvHTLink == NULL || pvKeyAddr == NULL || nKeySize <= 0   )    return SHMHT_FAILED;        pHTLink = (recHTCell*)pvHTLink ;        /*    *检查长度合法性    */    if( pHTLink->nKeySize != nKeySize ) /* input parameter unvalid */    {        ErrMsg( " input nKeySize[%d], invalid != %d \n", nKeySize ,                 pHTLink->nKeySize );        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;        /*    *调用 函数指针把内容更新    */    nRet = pfnPckFunc( pCell->pvPck, pHTLink->nSize );    if ( nRet != 0 )    {        ErrMsg( "Error When pfnPckFunc, nRet = %d", nRet );           return SHMHT_FAILED ;    }    return SHMHT_OK ;}/**描述: *在HASH表的一个bucket,把一个cell内容复制出来。*输出:SHMHT_OK 成功 , SHMHT_FAILED 失败*/static int  nSerABucketCell( recHTCell* pHTLink, int nBucket,                              recHashCell* pCell, void* pvCellAddr,                              int nCellSize ){    if ( pHTLink == NULL ||           pvCellAddr == NULL ||          nCellSize <= 0 ||          pCell == NULL )    return SHMHT_FAILED;        if( nBucket >= pHTLink->nBucket || nBucket < 0 )    return SHMHT_FAILED;            /*    * copy 内容到 pCellAddr      */    if( nCellSize != pCell->nPckSize )    {        ErrMsg("nCellSize != nPckSize int nSerA");        return SHMHT_FAILED;    }    else    {        memcpy( pvCellAddr, pCell->pvPck, pCell->nPckSize );     }            /*    *记录进程ID和操作时间    */    pCell->tMsgTime = time(NULL);   /*记录该消息的操作时间*/                return SHMHT_OK;}/**描述:在HASH表的一个bucket,把一个cell内容更新。*  注意超时间处理逻辑,可能会该操作而被破坏,*输出:SHMHT_OK 成功 , SHMHT_FAILED 失败*/static int  nUpdateABucketCell( recHTCell* pHTLink, int nBucket,                                 recHashCell* pCell, void* pvCellAddr,                                 int nCellSize ){    if ( pHTLink == NULL ||           pvCellAddr == NULL ||          nCellSize <= 0 ||          pCell == NULL )    return SHMHT_FAILED;        if( nBucket >= pHTLink->nBucket || nBucket < 0 )    return SHMHT_FAILED;            /*    * copy 内容到 pCellAddr      */    if( nCellSize != pCell->nPckSize )    {        ErrMsg( "Error When nUpdateABucketCell, nCellSize != nPckSize" );        return SHMHT_FAILED;    }    else    {        memcpy( pCell->pvPck, pvCellAddr, pCell->nPckSize );     }            /*    *记录进程ID和操作时间    */    //pHTLink->nMsgPid = getpid();  /*哈希表最后一条操作消息进程ID*/    //pHTLink->tMsgTime = time(NULL);   /*哈希表中最后一条消息时间*/        pCell->tMsgTime = time(NULL);   /*记录该消息的操作时间*/                return SHMHT_OK;}/*描述:删除HASH表内存一条记录输入:pHLink HT表句柄,pvKeyAddr KEY值指针, nKeySize KEY长度,nCellSize 包的长度。 输出:pvCellAddr 删除的包指针*返回:SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOFOUND 没有该包,*/int  nDelACellApi( 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 nBucket =%d\n", nBucket );        return SHMHT_FAILED ;    }        /*    *查找到和KEY匹配的包    *返回 >0 成功,NULL ,失败    */    pCell = pCellSearchByKey( pHTLink, nBucket, pvKeyAddr, nKeySize );     if( pCell == NULL )    return SHMHT_NOFOUND;    /*    *在HASH表的一个bucket删除一个记录。    */    return  nDelABucketCell( pHTLink, nBucket,                              pCell, pvCellAddr,                              nCellSize, NULL, 0 );        }/**描述: *在HASH表的一个bucket删除一个记录。*输出:SHMHT_OK 成功 , SHMHT_FAILED 失败*/static int  nDelABucketCell( recHTCell* pHTLink, int nBucket,                              recHashCell* pCell, void* pvCellAddr,                              int nCellSize, void* pvKeyAddr,                             int nKeySize ){    int nRet;       recHashCell* pMarkCell; /*哨兵结点*/    recHashCell* pNextCell;    recHashCell* pPrevCell;        if ( pHTLink == NULL ||          pCell == NULL )    return SHMHT_FAILED;        if( nBucket >= pHTLink->nBucket || nBucket < 0 )    return SHMHT_FAILED;        /*    *copy 内容到 pCellAddr      */    if ( pvCellAddr != NULL && nCellSize > 0 )    {        if ( nCellSize != pCell->nPckSize )         {            ErrMsg("Error When nDel, nCellSize = %d, nSize = %d\n",                         nCellSize, pCell->nPckSize );            return SHMHT_FAILED;        }        else        {            memcpy( pvCellAddr, pCell->pvPck, pCell->nPckSize );         }    }        if( pvKeyAddr != NULL && nKeySize > 0 )    {        if ( nKeySize != pCell->nKeySize )         {            ErrMsg("Error When nDel, nKeySize = %d, pCell->nKeySize = %d\n",                         nKeySize, pCell->nKeySize );            return SHMHT_FAILED;        }        else        {            memcpy( pvKeyAddr, pCell->pvKey, pCell->nKeySize );         }    }    pMarkCell = pHTLink->pBucket[nBucket];      pNextCell = pCell->pNext;    pPrevCell = pCell->pPrev;    if( pCell == pMarkCell ) /*如果将哨兵结点删除*/    {        if ( pNextCell == pCell )/*如果只有一个哨兵结点了,                                            * 并且是要删除的结点                                            */        {            pHTLink->pBucket[nBucket] = NULL;        }        else        {            pNextCell->pPrev = pCell->pPrev;            pPrevCell->pNext = pCell->pNext;            pHTLink->pBucket[nBucket] = pNextCell;        }            }    else    {        pNextCell->pPrev = pCell->pPrev;        pPrevCell->pNext = pCell->pNext;        }        memset( pCell->pvPck, 0, pHTLink->nSize );    memset( pCell->pvKey, 0, pHTLink->nKeySize );    /*    *记录进程ID和操作时间    */    //pHTLink->nMsgPid = getpid();  /*哈希表最后一条操作消息进程ID*/    //pHTLink->tMsgTime = time(NULL);   /*哈希表中最后一条消息时间*/        /*    *释放内存( 在内存管理队列中写入一个空闲的包 )    */    nRet = nHTFree( pHTLink, pCell );    if( nRet < 0  )    {        ErrMsg( "Error When nHTFree, nRet = %d" , nRet );        return SHMHT_FAILED;    }    return SHMHT_OK;}/**描述: 添加一条记录进入HASH表内存,                   如果已经有一条的话,就update,如果没有就添加*输入: pHLink HT表句柄, pvKeyAddr KEY值指针, nKeySize KEY长度,                   pvCellAddr 要添加的包指针,nCellSize 包的长度。 *输出: SHMHT_OK, 成功, SHMHT_FAILED 失败  SHMHT_NOSPACE  空间不够*/int  nAddACellAndUpdateApi( void* pvHTLink, void* pvKeyAddr,                         int nKeySize, void* pvCellAddr, int nCellSize                         ){    int nRet;        if ( pvHTLink == NULL || pvKeyAddr == NULL ||           nKeySize <= 0 || pvCellAddr == NULL || nCellSize <= 0 )    return SHMHT_FAILED;        nRet =  nUpdateACellApi( pvHTLink,                           pvKeyAddr,  nKeySize,                            pvCellAddr,  nCellSize );        if( nRet == SHMHT_OK )    {        return SHMHT_OK ;    }        if( nRet != SHMHT_OK && nRet != SHMHT_NOFOUND )    {        ErrMsg( "Error When nUpdateACellApi, nRet = %d ", nRet );        return SHMHT_FAILED;    }        if( nRet == SHMHT_NOFOUND ) /* Hash Table 没有以该KEY的记录,就添加进去 */    {        nRet = nAddACellApi( pvHTLink,                           pvKeyAddr,  nKeySize,                            pvCellAddr,  nCellSize );        if( nRet != SHMHT_OK && nRet != SHMHT_NOSPACE )        {            ErrMsg( "Error When nAddACellApi , nRet = %d ", nRet );            return SHMHT_FAILED;        }        return nRet;    /* SHMHT_OK or SHMHT_NOSPACE */    }               return SHMHT_OK;}/**描述: 添加一条记录进入HASH表内存*输入: pHLink HT表句柄, pvKeyAddr KEY值指针, nKeySize KEY长度,                    pvCellAddr 要添加的包指针,nCellSize 包的长度。 *输出: SHMHT_OK 成功 , SHMHT_FAILED 失败 SHMHT_NOSPACE   没有空间*/int  nAddACellApi( void* pvHTLink, void* pvKeyAddr, int nKeySize,                             void* pvCellAddr, int nCellSize ){    int nBucket; /*bucket的定位信息*/    //int nRet;    recHTCell* pHTLink;        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 nBucket =%d\n", nBucket );        return SHMHT_FAILED ;    }        /*    *增加记录进入HASH表的一个bucket    */    return  nAddABucketCell( pHTLink, nBucket, pvKeyAddr, nKeySize,                                     pvCellAddr, nCellSize );    }/**描述: 添加一条记录进入HASH表的一个bucket*输出:SHMHT_OK 成功 , SHMHT_FAILED 失败 SHMHT_NOSPACE   没有空间*/static int  nAddABucketCell( recHTCell* pHTLink, int nBucket,                               void* pvKeyAddr, int nKeySize,                                void* pvCellAddr, int nCellSize ){    recHashCell* pFirstCell;    recHashCell* pCellAddr; /* Malloc a Cell */    recHashCell* pPrevCell;    if ( pHTLink == NULL ||           pvCellAddr == NULL ||          nCellSize <= 0 ||          pvKeyAddr == NULL ||          nKeySize <= 0 ||         nKeySize != pHTLink->nKeySize ||         nCellSize != pHTLink->nSize          )    return SHMHT_FAILED;        if( nBucket >= pHTLink->nBucket || nBucket < 0 )    return SHMHT_FAILED;        /*    *首先申请内存( 在内存管理队列中取一个空闲的包 )    */

⌨️ 快捷键说明

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