apiht.c
来自「用c/c++实现的一个CMPP API」· C语言 代码 · 共 1,753 行 · 第 1/4 页
C
1,753 行
/*---------------------------------------------------------------* * File: apiht.c * Desc: 实现内存哈希表的实现 * 只实现定长的包操作 * * 2002/11/09 *-------------------------changeLog ----------------------------* * DATE Author Description *--------------------------------------------------------------- *2002/11/09 wenyz Created *--------------------------------------------------------------- *2002/11/09 wenyz 整理代码,用于货架技术 *2002/11/22 wenyz update *2002/11/26 wenyz ANSIC 版本 *---------------------------------------------------------------*/#include "apiht.h"//#define USEDSHAREMEMORY#include "os.h"#include "log.h"/*#define ErrMsg printf#define ErrRet printf#define DPrintf printf*/#define ErrMsg Trace#define ErrRet Trace#define DPrintf Trace static int nInitHTLink( void* pAddr, int nSize, void* pSAddr, void* pEAddr, int nPckSize, int nKeySize, int nBucket, int nPckCount ); static recHashCell* pHTMalloc( recHTCell* pHTLink );static int nHTFree( recHTCell* pHTLink, recHashCell* pCell ); static int nMakeKey( void* pKey, int nLen, int nBucket ); static int nAddABucketCell( recHTCell* pHTLink, int nBucket, void* pvKeyAddr, int nKeySize, void* pvCellAddr, int nCellSize ); static int nDelABucketCell( recHTCell* pHTLink, int nBucket, recHashCell* pCell, void* pvCellAddr, int nCellSize, void* pvKeyAddr, int nKeySize ); static int nSerABucketCell( recHTCell* pHTLink, int nBucket, recHashCell* pCell, void* pvCellAddr, int nCellSize ); static int nUpdateABucketCell( recHTCell* pHTLink, int nBucket, recHashCell* pCell, void* pvCellAddr, int nCellSize ); static void vListChain( FILE* fp, recHashCell* pCell ); static recHashCell* pCellSearchByKey(const recHTCell* pHTLink, int nBucket, void* pvKeyAddr,int nKeySize ); static recHashCell* pCellSearchByPck(const recHTCell* pHTLink, int nBucket, void* pvPckAddr,int nPckSize ); static recHashCell* pCellSearchByPckInAllBucket( const recHTCell* pHTLink, void* pvPckAddr, int nPckSize, int* pnBucket );#ifdef USEDSHAREMEMORYstatic void* pShmMalloc( int nShmKey, long lShmSize, int* pnShmId );/* private function */#define MacShmFlag 0666/*描述: 初始化固定长度的HASH表内存输入: nShmKey 内存KEY值, nKeySize KEY值的长度。 nPckSize 包体长度 nBucket 桶的个数 nPckCount 包的个数 输出: pnShmId*/void* pvInitShmHT( int nShmKey, int* pnShmId, int nKeySize, int nPckSize, int nBucket, int nPckCount ){ int nRet; /*函数调用结果值*/ long lShmSize; /*需要申请内存的大小*/ int nShmId; /*内存ID*/ char* pcharAddr; //struct shmid_ds StuShm_Ds; /*内存信息的数据结构*/ if ( pnShmId == NULL || nKeySize<= 0 || nPckSize <= 0 || nBucket <= 0 || nPckCount <= 0 ) return NULL; lShmSize = /*连接控制信息内存区*/ sizeof( recHTCell ) + /*包内容内存区域*/ ( sizeof( recHashCell ) + nKeySize+nPckSize )* nPckCount + /*bucket指针数组的存贮空间*/ nBucket*sizeof( recHashCell* ) + /* 空闲队列的地址存贮空间*/ nPckCount*sizeof( void*) ; //2002/08/14 wenyz Add pShmMalloc() Function pcharAddr = (char*)pShmMalloc( nShmKey, lShmSize, &nShmId ); if( pcharAddr == NULL ) /* fail */ { ErrMsg( "Error When pShmMalloc, KEY = %d, lShmSize = %d", nShmKey, lShmSize ); return NULL ; } /* *注意:内存空间的的分配为: * 1整个的控制信息(recHTCell) 的空间 * 2Bucket的首指针数组空间 * 3空闲队列的地址数组空间 * 4整个包体的控制信息和内容空间 */ nRet = nInitHTLink( pcharAddr, lShmSize, pcharAddr+sizeof( recHTCell )+ nBucket*sizeof(recHashCell*)+nPckCount*sizeof(void*), pcharAddr+lShmSize, nPckSize, nKeySize, nBucket, nPckCount ); if ( nRet != 0 ) { ErrMsg( "Error When nInitHTLink, pcharAddr[x] = %x\n", (int)pcharAddr ); return NULL; } *pnShmId = nShmId; return pcharAddr;}#endif // USEDSHAREMEMORY/*描述: 复位HASH表内存输入: pvHLink HT表句柄, 输出: 返回: SHMHT_OK 成功,SHMHT_FAILED 错误*/int nResetShmHTApi( void* pvHTLink ){ recHTCell* pHTLink; int nRet; long lShmSize; void* pSAddr; void* pEAddr; int nPckSize; int nKeySize; int nBucket; int nPckCount; if( pvHTLink == NULL ) return SHMHT_FAILED; pHTLink = (recHTCell*)pvHTLink; /*将initflag复位*/ pHTLink->nInitFlag = 0; lShmSize = pHTLink->nShmSize ; /*申请的总共内容包内存大小*/ pSAddr = pHTLink->pSAddr; /*内容包的开始地址*/ pEAddr = pHTLink->pEAddr; /*内容包的结束地址*/ nPckSize = pHTLink->nSize; /*哈希表中包长度*/ nKeySize = pHTLink->nKeySize; /*哈希表中key的长度*/ nBucket = pHTLink->nBucket; /*哈希表的桶数*/ nPckCount = pHTLink->nMsgMaxNum;/*哈希表中包最多个数*/ /*重新初始化内存*/ nRet = nInitHTLink( pvHTLink, lShmSize, pSAddr, pEAddr, nPckSize, nKeySize, nBucket, nPckCount ); if ( nRet != 0 ) { ErrMsg( "Error When nInitQLink, pvShmAddr[x] = %x\n", (int)pvHTLink ); return SHMHT_FAILED; } return SHMHT_OK; }#ifdef MacDebugLevel5int nListCell( recHashCell* prCell ){ if ( prCell == NULL ) return SHMHT_FAILED; printf("sizeofCell=%d\n",(int)sizeof(recHashCell) ); printf("prCur[x]=%x\n", (int)prCell ); printf("pNext[x]=%x\n", (int)prCell->pNext );/*下一个结点*/ printf("pPrev[x]=%x\n", (int)prCell->pPrev );/*前一个结点*/ printf("nKeySize=%d\n", prCell->nKeySize );/*key的长度*/ printf("pvKey[x]=%x\n", (int)prCell->pvKey );/*key的内容地址*/ printf("nPckSize=%d\n", prCell->nPckSize );/*包体长度*/ printf("pvPck[x]=%x\n", (int)prCell->pvPck );/*包体内容地址*/ return SHMHT_OK;}#endif /*end of MacDebugLevel5 */static int nInitHTLink( void* pAddr, int nSize, void* pSAddr, void* pEAddr, int nPckSize, int nKeySize, int nBucket, int nPckCount ){ recHTCell* pHTAddr; char* pvKeySAddr;/*key的地址空间*/ recHashCell* prCell; char* pCharAddr; int i; if ( pAddr == NULL ) return SHMHT_FAILED; pCharAddr = (char*)pAddr; pHTAddr = (recHTCell* )pAddr; if( pHTAddr->nInitFlag == 1) return SHMHT_OK; /*初始化数据*/ pHTAddr->nInitFlag = 1; /*是否初始化标志*/ pHTAddr->nShmSize = nSize; /*申请的总共内容包内存大小*/ pHTAddr->nMsgMaxNum = nPckCount; /*哈希表中包最多个数*/ pHTAddr->nBucket = nBucket; /*哈希表的桶数*/ pHTAddr->nSize = nPckSize; /*哈希表中包长度*/ pHTAddr->nKeySize = nKeySize; /*哈希表中key的长度*/ pHTAddr->nIterFlag = -1; /* for iterator */ pHTAddr->nCurrentBucket = 0; /* for iterator */ pHTAddr->pSAddr = pSAddr; /*内容包的开始地址*/ pHTAddr->pEAddr = pEAddr; /*内容包的结束地址*/ pHTAddr->tMsgTime = 0; /*哈希表中最后一条操作消息时间*/ pHTAddr->nMsgPid = -1; /*哈希表最后一条操作消息进程ID*/ /*bucket的头的存储空间*/ pHTAddr->pBucket = (recHashCell**)(pCharAddr+sizeof( recHTCell )); /*哈希表的桶的首指针数组*/ for( i=0; i<nBucket; i++ ) { pHTAddr->pBucket[i] = NULL; } /*空闲队列的地址数组空间*/ pHTAddr->RecFreeQ.pvAddr = (recHashCell**) ( pCharAddr+sizeof( recHTCell) + nBucket*sizeof( recHashCell*) ); /* 初始化每个包体内容 */ memset( pSAddr, 0, (int)pEAddr-(int)pSAddr ); /*key的地址空间*/ pvKeySAddr = ( (char*)pSAddr + nPckCount*sizeof(recHashCell) ); prCell = (recHashCell*)pSAddr; for( i=0; i<nPckCount; i++ ) { prCell->pvKey = pvKeySAddr; prCell->pvPck = ( (char*)pvKeySAddr + nKeySize ); /*空闲的内存管理队列*/ pHTAddr->RecFreeQ.pvAddr[i] = (recHashCell*)prCell;/*可用的地址空间*/ prCell++; /*recHashCell 增加*/ pvKeySAddr += (nKeySize + nPckSize );/*key和pck的地址空间增加*/ } /*空闲的内存管理队列*/ pHTAddr->RecFreeQ.nHead = nPckCount-1; /*内存管理队列的头*/ pHTAddr->RecFreeQ.nTail = 0; /*内存管理队列的尾*/ return SHMHT_OK;}/*描述: 得到HASH表内存的负载系数和包的个数输入: pvHLink HT表句柄, 输出: pnCellNum 包的个数返回: 0-100负载的百分比系数 SHMHT_FAILED 错误, */int nGetHTLoadApi( void* pvHTLink, int* pnCellNum ){ recHTCell* pHTLink; int nMemCellSum; int nUsedCellNum; if( pvHTLink == NULL ) return SHMHT_FAILED; pHTLink = (recHTCell*)pvHTLink; nMemCellSum = pHTLink->RecFreeQ.nHead - pHTLink->RecFreeQ.nTail; nMemCellSum = (nMemCellSum>=0)? nMemCellSum: pHTLink->nMsgMaxNum+nMemCellSum ; nUsedCellNum = pHTLink->nMsgMaxNum-nMemCellSum-1; if( pnCellNum != NULL ) { *pnCellNum = nUsedCellNum; } return ( (nUsedCellNum*100)/(pHTLink->nMsgMaxNum) );}/*描述: 得到HASH表内存的pBucket指针数组的首地址输入: pvHLink HT表句柄, 输出: recHashCell*** pppBucket, int* pnCount 指针数组个数返回: SHMHT_OK 成功 SHMHT_FAILED 错误, */int nGetHTpBucketApi( void* pvHTLink, recHashCell*** pppBucket, int* pnCount ){ recHTCell* pHTLink; if( pvHTLink == NULL || pppBucket == NULL || pnCount == NULL ) return SHMHT_FAILED; pHTLink = (recHTCell*)pvHTLink; *pppBucket = (recHashCell**)pHTLink->pBucket; *pnCount = pHTLink->nBucket ; return SHMHT_OK;}/*描述: 通过KEY得到HASH表内存的pBucket指针的首地址输入: pvHLink HT表句柄, pvKeyAddr, KEY的地址, nKeySize KEY的长度 输出: recHashCell** ppBucket返回: SHMHT_OK 成功 SHMHT_FAILED 错误,*/int nGetHTpBucketByKeyApi( void* pvHTLink, void* pvKeyAddr, int nKeySize, recHashCell** ppBucket ){ recHTCell* pHTLink; int nBucket; /*bucket的定位信息*/ if( pvHTLink == NULL || ppBucket == NULL || pvKeyAddr == NULL || nKeySize <= 0 ) return SHMHT_FAILED; pHTLink = (recHTCell*)pvHTLink; /* *定位bucket */ nBucket = nMakeKey( pvKeyAddr, nKeySize, pHTLink->nBucket ); if ( nBucket < 0 ) { ErrMsg( " Error nBucket =%d\n", nBucket ); return SHMHT_FAILED ; } *ppBucket = (recHashCell*)pHTLink->pBucket[nBucket]; return SHMHT_OK;}/**function 调试工具*/void vDumpHTApi( FILE* fp, void* pAddr ){ FILE* fD; recHTCell* pHTAddr; int nMemCellSum; int i; if( pAddr == NULL ) return ; pHTAddr = (recHTCell*) pAddr; fD = ( fp == NULL )? stdout:fp ; fprintf( fD, "\n\n----beg of Queue Status----\n" ); /*是否初始化标志*/ fprintf( fD, "nInitFlag=%d\n", pHTAddr->nInitFlag ); /*申请的总共内容包内存大小*/ fprintf( fD, "nShmSize=%d\n", pHTAddr->nShmSize ); /*哈希表中包最多个数*/ fprintf( fD, "nMsgMaxNum=%d\n", pHTAddr->nMsgMaxNum ); /*哈希表中包长度*/ fprintf( fD, "nPckSize=%d\n", pHTAddr->nSize ); /*哈希表中KEY包长度*/ fprintf( fD, "nKeySize=%d\n", pHTAddr->nKeySize ); /*哈希表的桶数*/ fprintf( fD, "nBucket=%d\n", pHTAddr->nBucket ); /*内容包的开始地址*/ fprintf( fD, "pSAddr[x]=%x\n", (int)pHTAddr->pSAddr ); /*内容包的结束地址*/ fprintf( fD, "pEAddr[x]=%x\n", (int)pHTAddr->pEAddr ); /*哈希表最后一条操作消息进程ID*/ fprintf( fD, "nMsgPid=%d\n", pHTAddr->nMsgPid ); /*哈希表中最后一条操作消息时间*/ fprintf( fD, "tMsgTime=%s\n", ctime( (time_t*)&pHTAddr->tMsgTime) ); /*哈希表的桶的首指针数组*/ for( i=0; i<pHTAddr->nBucket; i++ )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?