⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memdatabase.c

📁 Unix 环境下用C语言实现的内存数据库。
💻 C
字号:
#include "MemDataBase.h"#define HEAD_TABLE_NAME_LEN    64#define HEAD_RESERVED_LEN      128#define MDB_IPC_MODE     0660#define MAX_KEY_NUM     10typedef struct{    int iKeyOffSet;     /* TheKey fieldoffset */    int iKeyLen;       /* The Keyfield len */}TABLE_KEY_DEF;typedef struct{    char sTableName[HEAD_TABLE_NAME_LEN]; /* The name of table*/    long lRecordNum;      /* The total number of record in table */    int  iRecordLen;      /* The length of recode */    long lMaxRecordNum;   /* The max number of record in table */    char sReserved[HEAD_RESERVED_LEN]; /* The reserved area*/    int  iKeyNum;         /* The Key field number */    TABLE_KEY_DEF stuTableKeyBuf[MAX_KEY_NUM];   /* The Table Key define */}TABLE_HEAD_DEF;static TABLE_HEAD_DEF stuTableHeadBuf;int CreateMemDB(MEMDATABASE **pMemDB,char *pTableName,int iIpcKey,long lMaxRecord,int RecordLen){    int iRet;    memset((char*)&stuTableHeadBuf,0,sizeof(TABLE_HEAD_DEF));    if(strlen(pTableName)>HEAD_TABLE_NAME_LEN) return T_MDB_ENAMELEN;    memcpy(stuTableHeadBuf.sTableName,pTableName,strlen(pTableName));    stuTableHeadBuf.iRecordLen = RecordLen;    stuTableHeadBuf.lMaxRecordNum = lMaxRecord;    stuTableHeadBuf.lRecordNum = 0;    stuTableHeadBuf.iKeyNum = 0;    *pMemDB = (MEMDATABASE*)malloc(sizeof(MEMDATABASE));    if(*pMemDB==NULL) return T_MDB_ENOMEM;    (*pMemDB)->iFetchKeyNum = 0;    (*pMemDB)->lFetchNum = 1;    (*pMemDB)->iIpcKey = iIpcKey;    (*pMemDB)->iShmId = shmget(iIpcKey,                               stuTableHeadBuf.iRecordLen*stuTableHeadBuf.lMaxRecordNum +                               sizeof(stuTableHeadBuf),                               IPC_CREAT|MDB_IPC_MODE);    if( (*pMemDB)->iShmId<0 )    {        return T_MDB_ESHMGET;    }    (*pMemDB)->pShmArea = (char*)shmat((*pMemDB)->iShmId,NULL,0);    if( (long)(*pMemDB)->pShmArea==-1 )    {        return T_MDB_ESHMAT;    }    memcpy((*pMemDB)->pShmArea,(char*)&stuTableHeadBuf,sizeof(stuTableHeadBuf));    (*pMemDB)->iSemId = semget(iIpcKey,1,IPC_CREAT|MDB_IPC_MODE);    if( (*pMemDB)->iSemId<0 )    {        return T_MDB_ESEMGET;    }    iRet = semctl((*pMemDB)->iSemId,0,SETVAL,1);    if( iRet<0 )    {        return T_MDB_ESEMCTL;    }    return T_SUCCESS;}void GetHead(char *pShmArea){    memcpy((char*)&stuTableHeadBuf,(char*)pShmArea,sizeof(TABLE_HEAD_DEF));}void PutHead(char *pShmArea){    memcpy((char*)pShmArea,(char*)&stuTableHeadBuf,sizeof(TABLE_HEAD_DEF));}int SetTableKey(MEMDATABASE *pMemDB,int iKeyOffSet,int iKeyLen){    int i;    GetHead(pMemDB->pShmArea);    for(i=0;i<stuTableHeadBuf.iKeyNum;i++)    {        if((stuTableHeadBuf.stuTableKeyBuf[i].iKeyOffSet == iKeyOffSet)&&           (stuTableHeadBuf.stuTableKeyBuf[i].iKeyLen == iKeyLen))        {            return T_SUCCESS;        }    }    if(stuTableHeadBuf.iKeyNum >= MAX_KEY_NUM) return T_MDB_EMAXKEY;    stuTableHeadBuf.stuTableKeyBuf[stuTableHeadBuf.iKeyNum].iKeyOffSet = iKeyOffSet;    stuTableHeadBuf.stuTableKeyBuf[stuTableHeadBuf.iKeyNum].iKeyLen = iKeyLen;    stuTableHeadBuf.iKeyNum++;    PutHead(pMemDB->pShmArea);    return T_SUCCESS;}int CompareKey(MEMDATABASE *pMemDB,char *pShmBuf,char *pInBuf){    int i,iRet;    GetHead(pMemDB->pShmArea);    for(i=0;i<stuTableHeadBuf.iKeyNum;i++)    {        iRet = memcmp((char*)&pInBuf[stuTableHeadBuf.stuTableKeyBuf[i].iKeyOffSet],                      (char*)&pShmBuf[stuTableHeadBuf.stuTableKeyBuf[i].iKeyOffSet],                      stuTableHeadBuf.stuTableKeyBuf[i].iKeyLen);        if(iRet!=0) return iRet;    }    return 0;}int ShmLock(int iSemId){    int iRet;    struct sembuf stuSemBuf;    stuSemBuf.sem_num = 0;    stuSemBuf.sem_op = -1;    stuSemBuf.sem_flg = 0;    iRet = semop(iSemId,&stuSemBuf,1);    return iRet;}int ShmUnLock(int iSemId){    int iRet;    struct sembuf stuSemBuf;    stuSemBuf.sem_num = 0;    stuSemBuf.sem_op = 1;    stuSemBuf.sem_flg = 0;    iRet = semop(iSemId,&stuSemBuf,1);    return iRet;}char * LocateShm(char *pShmArea,int iNum){    if( iNum>stuTableHeadBuf.lMaxRecordNum )    {        return NULL;    }    return pShmArea +           (iNum-1)*stuTableHeadBuf.iRecordLen +           sizeof(stuTableHeadBuf);}int SearchRecord(MEMDATABASE *pMemDB,char *pInBuf,int *iPosition){    int iRet,i,iMax,iMin;    char *pRecordBuf;    iMin = i = 0;    iMax = stuTableHeadBuf.lRecordNum-1;    while(iMin<=iMax)    {        i = (iMax+iMin)/2;        pRecordBuf = LocateShm(pMemDB->pShmArea,i+1);        iRet = CompareKey(pMemDB,pRecordBuf,pInBuf);        switch(iRet)        {            case  0: *iPosition = i+1;                    return T_SUCCESS;                    break;            case  1: iMin = i+1;                    break;            case -1: iMax = i-1;                    break;        }    }    if(iMin>iMax&&i==iMax) i=iMin;    *iPosition = i+1;    return T_MDB_NOTFOUND;}int DropMemDB(MEMDATABASE *pMemDB){    int iRet;    iRet = shmctl(pMemDB->iShmId,IPC_RMID,0);    if( iRet<0 )    {        return T_MDB_ESHMRM;    }    iRet = semctl(pMemDB->iSemId,IPC_RMID,0);    if( iRet<0 )    {        return T_MDB_ESEMRM;    }    free(pMemDB);    return T_SUCCESS;}int AttachMemDB(MEMDATABASE **pMemDB,int iIpcKey){    *pMemDB = (MEMDATABASE*)malloc(sizeof(MEMDATABASE));    if(*pMemDB==NULL) return T_MDB_ENOMEM;    (*pMemDB)->iFetchKeyNum = 0;    (*pMemDB)->lFetchNum = 1;    (*pMemDB)->iIpcKey = iIpcKey;    (*pMemDB)->iShmId = shmget(iIpcKey,0,MDB_IPC_MODE);    if( (*pMemDB)->iShmId<0 )    {        return T_MDB_ESHMGET;    }    (*pMemDB)->pShmArea = (char*)shmat((*pMemDB)->iShmId,NULL,0);    if( (long)(*pMemDB)->pShmArea==-1 )    {        return T_MDB_ESHMAT;    }    (*pMemDB)->iSemId = semget(iIpcKey,1,MDB_IPC_MODE);    if( (*pMemDB)->iSemId<0 )    {        return T_MDB_ESEMGET;    }    return T_SUCCESS;}int DeclareTableKey(MEMDATABASE *pMemDB,int iKeyOffSet,int iKeyLen,void *pValue){    int i;    pMemDB->lFetchNum = 1;    for(i=0;i<pMemDB->iFetchKeyNum;i++)    {        if((pMemDB->stuFetchKeyBuf[i].iKeyOffSet==iKeyOffSet)&&           (pMemDB->stuFetchKeyBuf[i].iKeyLen==iKeyLen))        {            memcpy(pMemDB->stuFetchKeyBuf[i].sValue,(char*)pValue,iKeyLen);            return T_SUCCESS;        }    }    if(pMemDB->iFetchKeyNum>=MAX_FETCHKEY_NUM) return T_MDB_EMAXFETCHKEY;    pMemDB->stuFetchKeyBuf[pMemDB->iFetchKeyNum].iKeyOffSet = iKeyOffSet;    pMemDB->stuFetchKeyBuf[pMemDB->iFetchKeyNum].iKeyLen = iKeyLen;    memcpy(pMemDB->stuFetchKeyBuf[pMemDB->iFetchKeyNum].sValue,(char*)pValue,iKeyLen);    pMemDB->iFetchKeyNum++;    return T_SUCCESS;}int CloseCursorMemDB(MEMDATABASE *pMemDB){    pMemDB->lFetchNum = 1;    pMemDB->iFetchKeyNum = 0;    return T_SUCCESS;}int FetchCursorMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    int iRet;    char *pRecordBuf;    GetHead(pMemDB->pShmArea);    while(stuTableHeadBuf.lRecordNum >=pMemDB->lFetchNum )    {        pRecordBuf = LocateShm(pMemDB->pShmArea,pMemDB->lFetchNum++);        iRet = FetchCondition(pMemDB,pRecordBuf);        if(iRet!=T_SUCCESS) continue;        memcpy((char*)pInBuffer,pRecordBuf,stuTableHeadBuf.iRecordLen);        return T_SUCCESS;    }    return T_MDB_NOTFOUND;}int FetchCondition(MEMDATABASE *pMemDB,char *pRecordBuf){    int i;    for(i=0;i<pMemDB->iFetchKeyNum;i++)    {        if(memcmp((char*)&pRecordBuf[pMemDB->stuFetchKeyBuf[i].iKeyOffSet],                  (char*)pMemDB->stuFetchKeyBuf[i].sValue,                  pMemDB->stuFetchKeyBuf[i].iKeyLen)!=0)        return T_MDB_NOTMATCH;    }    return T_SUCCESS;}int SelectOneMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    char *pRecordBuf;    GetHead(pMemDB->pShmArea);    if(stuTableHeadBuf.lRecordNum > 0)    {        pRecordBuf = LocateShm(pMemDB->pShmArea,1);        memcpy((char*)pInBuffer,pRecordBuf,stuTableHeadBuf.iRecordLen);        return T_SUCCESS;    }    else    {        return T_MDB_NOTFOUND;    }}int SelectMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    int iRet,iPosition;    char *pRecordBuf;    if(ShmLock(pMemDB->iSemId)) return T_MDB_ESHMLOCK;    GetHead(pMemDB->pShmArea);    iRet = SearchRecord(pMemDB,pInBuffer,&iPosition);    if(iRet!=T_SUCCESS)    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_NOTFOUND;    }    pRecordBuf = LocateShm(pMemDB->pShmArea,iPosition);    memcpy((char*)pInBuffer,pRecordBuf,stuTableHeadBuf.iRecordLen);    if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;    return T_SUCCESS;}int UpdateMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    int iRet,iPosition;    char *pRecordBuf;    if(ShmLock(pMemDB->iSemId)) return T_MDB_ESHMLOCK;    GetHead(pMemDB->pShmArea);    iRet = SearchRecord(pMemDB,pInBuffer,&iPosition);    if(iRet!=T_SUCCESS)    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_NOTFOUND;    }    pRecordBuf = LocateShm(pMemDB->pShmArea,iPosition);    memcpy((char*)pRecordBuf,(char*)pInBuffer,stuTableHeadBuf.iRecordLen);    if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;    return T_SUCCESS;}int DeleteMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    int iNum,iRet,iPosition;    char *pRecordBuf;    if(ShmLock(pMemDB->iSemId)) return T_MDB_ESHMLOCK;    GetHead(pMemDB->pShmArea);    iRet = SearchRecord(pMemDB,pInBuffer,&iPosition);    if(iRet!=T_SUCCESS)    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_NOTFOUND;    }    pRecordBuf = LocateShm(pMemDB->pShmArea,iPosition);    memcpy((char*)pInBuffer,(char*)pRecordBuf,stuTableHeadBuf.iRecordLen);    iNum = stuTableHeadBuf.lRecordNum-iPosition;    if(iNum>0)    {        memmove(LocateShm(pMemDB->pShmArea,iPosition),LocateShm(pMemDB->pShmArea,iPosition+1),                stuTableHeadBuf.iRecordLen*iNum);    }    stuTableHeadBuf.lRecordNum--;    PutHead(pMemDB->pShmArea);    if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;    return T_SUCCESS;}int DeleteOneMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    char *pRecordBuf;    if(ShmLock(pMemDB->iSemId)) return T_MDB_ESHMLOCK;    GetHead(pMemDB->pShmArea);    if( stuTableHeadBuf.lRecordNum > 0 )    {        pRecordBuf = LocateShm(pMemDB->pShmArea,1);        memcpy(pInBuffer,pRecordBuf,stuTableHeadBuf.iRecordLen);        memcpy(pRecordBuf,LocateShm(pMemDB->pShmArea,1+1),               (stuTableHeadBuf.lRecordNum-1)*stuTableHeadBuf.iRecordLen);        stuTableHeadBuf.lRecordNum--;        PutHead(pMemDB->pShmArea);    }    else    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_NOTFOUND;    }    if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;    return T_SUCCESS;}int InsertMemDB(MEMDATABASE *pMemDB,char *pInBuffer){    int iRet,iNum,iPosition;    char *pRecordBuf;    if(ShmLock(pMemDB->iSemId)) return T_MDB_ESHMLOCK;    GetHead(pMemDB->pShmArea);    iRet = SearchRecord(pMemDB,pInBuffer,&iPosition);    if(iRet==T_SUCCESS)    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_DUPKEY;    }    if(stuTableHeadBuf.lRecordNum>=stuTableHeadBuf.lMaxRecordNum)    {        if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;        return T_MDB_LACKSPACE;    }    stuTableHeadBuf.lRecordNum++;    iNum = stuTableHeadBuf.lRecordNum-iPosition;    if(iNum>0)    {        memmove(LocateShm(pMemDB->pShmArea,iPosition+1),LocateShm(pMemDB->pShmArea,iPosition),                stuTableHeadBuf.iRecordLen*iNum);    }    memcpy(LocateShm(pMemDB->pShmArea,iPosition),pInBuffer,           stuTableHeadBuf.iRecordLen);    PutHead(pMemDB->pShmArea);    if(ShmUnLock(pMemDB->iSemId)) return T_MDB_ESHMUNLOCK;    return T_SUCCESS;}void TruncateMemDB(MEMDATABASE *pMemDB){    GetHead(pMemDB->pShmArea);    stuTableHeadBuf.lRecordNum = 0;    PutHead(pMemDB->pShmArea);}

⌨️ 快捷键说明

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