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