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 + -
显示快捷键?