apiht.c

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

C
1,753
字号
    pCellAddr = pHTMalloc( pHTLink );    if( pCellAddr == NULL )    {        //ErrMsg( "Error When pHTMalloc\n " );        return SHMHT_NOSPACE;    }    memcpy( pCellAddr->pvKey, pvKeyAddr, nKeySize );        pCellAddr->nKeySize = nKeySize;    memcpy( pCellAddr->pvPck, pvCellAddr, nCellSize );    pCellAddr->nPckSize = nCellSize;    pCellAddr->tMsgTime = time(NULL);       /*记录该消息的操作时间*/    if ( pHTLink->pBucket[nBucket] == NULL ) /* 首记录  作为第一个元素插入 */    {        pCellAddr->pNext = pCellAddr;        pCellAddr->pPrev = pCellAddr;        pHTLink->pBucket[nBucket] = pCellAddr;            }    else /*作为第一个元素插入*/    {                pFirstCell = pHTLink->pBucket[nBucket]; /*首指针*/                pPrevCell = pFirstCell->pPrev;                pCellAddr->pNext = pFirstCell;        pCellAddr->pPrev = pPrevCell;        pPrevCell->pNext = pCellAddr;        pFirstCell->pPrev = pCellAddr;                 pHTLink->pBucket[nBucket] = pCellAddr;    }    /*    *记录进程ID和操作时间    */    //pHTLink->nMsgPid = getpid();  /*哈希表最后一条操作消息进程ID*/    //pHTLink->tMsgTime = time(NULL);   /*哈希表中最后一条操作消息时间*/    return SHMHT_OK;}/**描述: 从一个桶中取出一个超时的记录*输入: pHLink HT表句柄,nBucket 桶的下标, nTimeOut 超过时间间隔    输出pvKeyAddr KEY值指针, nKeySize KEY长度,    pvCellAddr 查找的包指针,nCellSize 包的长度。    如果pvKeyAddr, nKeySize , pvCellAddr, nCellSize 为空的话,      清除所有超时的包 *输出:>=0 成功 清除的包的个数, SHMHT_FAILED 失败 */int  nGetABucketTimeOutCell( void* pvHTLink, int nBucket,                      int nTimeOut,  void* pvKeyAddr,                      int nKeySize, void* pvCellAddr,                      int nCellSize ){    time_t  tNowTime;    recHTCell* pHTLink;    recHashCell* pMarkCell; /*哨兵结点*/    recHashCell* pCell;    /*变化的结点*/    int nSumPackCell = 0;   /*清空的包的个数*/    int nRet;        if( nTimeOut <= 0 || pvHTLink == NULL )    return SHMHT_FAILED;        pHTLink = (recHTCell* )pvHTLink;        if( nBucket <0 || nBucket >= pHTLink->nBucket )    return SHMHT_FAILED;            while( 1 )    {        /*该桶链表的哨兵,会因为nDelABukcetCell调用而变化*/              pMarkCell = pHTLink->pBucket[nBucket];          if( pMarkCell == NULL )        {            break;        }        pCell = pMarkCell->pPrev; /*从后往前查,保证先进先出*/                /*具体的操作*/        tNowTime = time(NULL);        if( tNowTime - pCell->tMsgTime > nTimeOut ) /*如果超时*/        {                        nRet = nDelABucketCell( pHTLink, nBucket,                                                  pCell,                                                  pvCellAddr,                                                  nCellSize,                                                  pvKeyAddr,                                                 nKeySize );            if ( nRet != SHMHT_OK )            {                return SHMHT_FAILED ;            }            else                {                nSumPackCell ++;                if ( pvCellAddr != NULL )   /*如果是要取出包*/                {                                        return nSumPackCell;                }            }                        }        else    /*最早的都没有超过时间*/        {            break;        }            }/* end of while */    return nSumPackCell;}/**note : 写日志函数待实现*/int  nGetTimeOutACellApi( void* pvHTLink, int   nTimeOut,                        void* pvKeyAddr, int nKeySize,                        void* pvCellAddr, int nCellSize ){    int nBucket;    recHTCell* pHTLink;    int nSumPackCell = 0;   /*清空的包的个数*/    int nRet;        if( nTimeOut <= 0 || pvHTLink == NULL)     return SHMHT_FAILED;        pHTLink = (recHTCell* )pvHTLink;        for( nBucket=0; nBucket<pHTLink->nBucket; nBucket++ )    {        nRet =  nGetABucketTimeOutCell( pHTLink, nBucket,                                          nTimeOut, pvKeyAddr,                                           nKeySize,  pvCellAddr,                                           nCellSize );        if( nRet < 0 )        {            ErrMsg( "Error When nGetABucketTimeOutCell\n" );            return SHMHT_OK;        }        if( pvCellAddr != NULL && nRet == 1 ) /*得到了一个要取出的包*/        {            return 1;        }        nSumPackCell += nRet;    }        return nSumPackCell;    }/**描述: 调试工具 显示出以该记录为首的链表的所有结点和内容。**/static void     vListChain( FILE* fp,  recHashCell* pCell ){    FILE* fD;    int nSum; /*总的结点数目*/    recHashCell* pMarkCell ;    /*哨兵结点*/    recHashCell* pVarCell;  /*变化的结点*/            fD = ( fp == NULL )? stdout:fp ;        if ( pCell == NULL )    {           fprintf( fD, "Total Sum of Chain = %d\n\n", 0 );        fflush( fD );        return ;    }        nSum = 0;    pMarkCell = pCell ;    pVarCell = pCell;    while( pMarkCell != NULL ) /*找了一遍*/    {    /*                        fprintf( fD, "\tNo.%d pCur[x]=%x, pNext[x]=%x,pPrev[x]=%x\n",                         nSum, (int)pVarCell, (int)pVarCell->pNext, (int)pVarCell->pPrev );        fprintf( fD, "\tNo.%d pvPck[%d]=%s,pvKey[%d]=%s\n",                        nSum, pVarCell->nPckSize, (char*)pVarCell->pvPck,                         pVarCell->nKeySize, (char*)pVarCell->pvKey );    */        nSum++;                pVarCell = pVarCell->pNext;        if( pVarCell == pMarkCell )        break;            }    fprintf( fD, "Total Sum of Chain = %d\n\n", nSum );        fflush( fD );        return ;}#ifdef USEDSHAREMEMORYint  nRemoveShmHT( int nShmId ){    if ( nShmId <= 0 )    return SHMHT_FAILED;    return shmctl( nShmId, IPC_RMID, NULL );}#endif/*---------beg of memory hash function------------*//*--------------------------* *内存表的三个函数定义      *    ---------------------------*//*描述: 初始化固定长度的HASH表内存输入:  nKeySize KEY值的长度。 nPckSize 包体长度    nBucket 桶的个数, nPckCount 包的个数        *返回:HT表句柄 >0 成功 , NULL 失败*/void*    pvInitMemHT( int nKeySize, int nPckSize, int nBucket, int nPckCount ){    int     nRet;       /*函数调用结果值*/    size_t  sizeMemory; /*需要申请内存的大小*/    char*   pvMemAddr;  /*内存首地址*/            if ( nKeySize<= 0 ||          nPckSize <= 0 ||          nBucket <= 0 ||          nPckCount <= 0        )    return NULL;        sizeMemory =          /*连接控制信息内存区*/            sizeof( recHTCell ) +                              /*包内容内存区域*/           ( sizeof( recHashCell )  + nKeySize+nPckSize )* nPckCount +          /*bucket指针数组的存贮空间*/           nBucket*sizeof( recHashCell* ) +                     /* 空闲队列的地址存贮空间*/           nPckCount*sizeof( void*) ;                         pvMemAddr = ( char *)malloc( sizeMemory );        if ( pvMemAddr  == NULL )  /* operation failed. */    {        ErrRet( "Error When malloc(%d)\n", (int)sizeMemory );        return NULL;    }    /*    *注意:内存空间的的分配为:    *              1整个的控制信息(recHTCell) 的空间    *              2Bucket的首指针数组空间    *              3空闲队列的地址数组空间      *              4整个包体的控制信息和内容空间        */    nRet = nInitHTLink( pvMemAddr, sizeMemory,                                  pvMemAddr+sizeof( recHTCell )+                                    nBucket*sizeof(recHashCell*)+nPckCount*sizeof(void*),                                  pvMemAddr+sizeMemory,                                  nPckSize,                                  nKeySize,                                  nBucket,                                  nPckCount );     if ( nRet != 0 )    {        ErrMsg( "Error When nInitQLink, pvShmAddr[x] = %x\n", (int)pvMemAddr );        return NULL;    }        /*vDumpHT( NULL, pvMemAddr );*/    return pvMemAddr;}/**描述: 释放该HASH表的内存*输入:  pvHTLink HT表句柄*输出: 无 *返回: SHMHT_OK 成功,SHMHT_FAILED 错误*/int      nRemoveMemHT(  void* pvHTLink ){    if( pvHTLink == NULL )     return SHMHT_FAILED;        free( pvHTLink );        return SHMHT_OK;}   /*描述: 复位HASH表内存输入:  pvHLink HT表句柄,                 输出: 返回: SHMHT_OK 成功,SHMHT_FAILED 错误*/int     nResetMemHT( void* pvHTLink ){    if( pvHTLink == NULL )    return SHMHT_FAILED;        return nResetShmHTApi( pvHTLink );}#ifdef USEDSHAREMEMORY/**描述: 内存分配函数 *输入参数:nShmKey , 关键字 lShmSize 大小, *输出参数: pnShmId     输出内存ID,为NULL不输出*返回值:       > 0 成功,*       Null 失败 */ #define MacShmFlag 0666static void*         pShmMalloc( int nShmKey, long lShmSize, int* pnShmId  ){    int nShmId;     /*内存ID*/    void*   pvShmAddr = NULL;   /*内存首地址*/    struct  shmid_ds StuShm_Ds; /*内存信息的数据结构*/    int nRet;        nShmId = shmget( nShmKey, lShmSize, IPC_CREAT | MacShmFlag );        if ( nShmId < 0 )    {           ErrRet( "Error When Shmget, nKey[x] = %x, Size[x] = %x\n", nShmKey, lShmSize );        nShmId = shmget( nShmKey, 0, IPC_CREAT | MacShmFlag );        if ( nShmId < 0 )        {            ErrRet( "Error When Shmget, nKey[x] = %x, Size[x] = %x\n", nShmKey, 0 );            return NULL;        }            }    /*为防止版本不对,在这里对大小进行严格的匹配*/    nRet = shmctl( nShmId, IPC_STAT, &StuShm_Ds );    if( nRet < 0 )    {        ErrRet( "Error When shmctl, nShmId[x]=%x", nShmId );        return NULL;    }    if( StuShm_Ds.shm_segsz != lShmSize ) /*大小不对*/    {        ErrMsg( "Error InitShm\nBecause Current Version Not Matching "                "The Exist Version\nRequire Shmem Size[x]=%x, Existing"                "Shmem Size[x]=%x\n"                "Pls check the version or remove the share memory, KEY[x]=%d",                 lShmSize, StuShm_Ds.shm_segsz, nShmKey );        return NULL;    }        pvShmAddr = ( void *)shmat( nShmId, NULL, 0 );    if ( !pvShmAddr || (int)pvShmAddr == -1 )  /* operation failed. */        {            ErrRet( "Error When shmat, nShmId = %d\n", nShmId );            return NULL;        }                if( pnShmId != NULL ) /*输出ID */        {            *pnShmId = nShmId;        }        return pvShmAddr;        }   #endif // USEDSHAREMEMORY/*---------end of memory hash function------------*///#define SELFTEST#ifdef  SELFTEST//#define   MacSHMKEY 0xbbbb#define MacPckSize 512#define MacKeySize 8#define MacPckCount 1000#define MacBucket 100int  main(){    int i;    int nRet;    char    sKey[ MacKeySize+1 ];    char    sPck[ MacPckSize+1 ];        void* pvHT;        memset( sKey, 0, sizeof( sKey ) );    memset( sPck, 0, sizeof( sPck ) );        pvHT = pvInitMemHT( MacKeySize, MacPckSize, MacBucket, MacPckCount );    if( pvHT == NULL )    {        printf( "Error when pvInitMemHT \n" );        return -1;    }    else    {        printf( "OK, Init, pvHT = %p\n", pvHT );    }        for( i=0; i<10; ++i)    {        printf( "now i = %d\n", i );        snprintf( sKey, sizeof( sKey ), "%d", i );        snprintf( sPck, sizeof( sPck ), "%d", i );        nRet = nAddACellApi( pvHT, sKey,  MacKeySize,                                 sPck,  MacPckSize );        printf( "nRet = %d after nAddACell\n", nRet );                                    }        for( i=0; i<10; ++i)    {        printf( "now i = %d\n", i );        snprintf( sKey, sizeof( sKey ), "%d", i );             nRet = nDelACellApi( pvHT, sKey,  MacKeySize,                                 sPck,  MacPckSize );        printf( "nRet = %d after nDelACell\n", nRet );         printf( "sPck = %s\n", sPck );                                   }    return 0;}#endif

⌨️ 快捷键说明

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