zyh3033 发表于 2015-11-18 09:45:28

对一个memcache的封装

  最近对一个memcache进行封装,感觉还不错 由于注释比较多,就不一一解释了。
  头文件
  #pragma once


#include <libmemcached/memcached.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>


class ESMemcache
{
public:
ESMemcache(void);
~ESMemcache(void);
public:
bool Init(char* pIPPort, int msec=1000);
bool SetRecord(char* key, const char* value, const size_t bytes, const time_t expire = 0);
bool Replace(char* key, const char* value, const size_t bytes, const time_t expire = 0);
void GetRecord(const char* key, std::string &value);
bool DeleteRecord(const char* key);
bool Increment(const char *key, int offset, uint64_t &value);
bool Decrement(const char *key, int offset, uint64_t &value);
bool IsKeyExist(const char *key);
private:
int setTimeOut(int msec);
memcached_return rc;
memcached_st *memc;


};

cpp
  #include &quot;ESMemcache.h&quot;
using namespace std;


ESMemcache::ESMemcache(void)
{
}


ESMemcache::~ESMemcache(void)
{
}


int ESMemcache::setTimeOut(int msec)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, -1);
return 0;
}


bool ESMemcache::Init(char* pIPPort, int msec)
{
memc = memcached_create(NULL);
int nPort = 0;
char * pszPort = strchr(pIPPort, ':');
if (pszPort) {
nPort = atoi(pszPort &#43; 1);
*pszPort = 0;
}
setTimeOut(msec);
rc = memcached_server_add(memc, pIPPort, nPort);
if(rc != MEMCACHED_SUCCESS)
return false;

return rc == MEMCACHED_SUCCESS;
}




bool ESMemcache::SetRecord(char* key, const char* value, const size_t bytes, const time_t expire)
{
rc = memcached_set(memc, key, strlen(key), value, bytes, expire, 0);
return rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED;
}


bool ESMemcache::Replace(char* key, const char* value, const size_t bytes, const time_t expire)
{
rc = memcached_replace(memc, key, strlen(key), value, bytes, expire, 0);
return rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED;
}




void ESMemcache::GetRecord(const char* key, std::string &value)
{
size_t value_length = 0;
uint32_t flags = 0;
char *val = memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);
if(val !=NULL)
{
value = val;
free(val);
}
else
{
value.clear();
}
}


bool ESMemcache::DeleteRecord(const char* key)
{


rc = memcached_delete(memc, key, strlen(key), 0);
return rc == MEMCACHED_SUCCESS;
}


bool ESMemcache::Increment(const char *key, int offset, uint64_t &value)
{
rc = memcached_increment(memc, key, strlen(key), offset, &value);
return rc == MEMCACHED_SUCCESS;
}


bool ESMemcache::Decrement(const char *key, int offset, uint64_t &value)
{
rc = memcached_decrement(memc, key, strlen(key), offset, &value);
return rc == MEMCACHED_SUCCESS;
}


bool ESMemcache::IsKeyExist(const char *key)
{
size_t value_length = 0;
uint32_t flags = 0;
memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);
if (rc == MEMCACHED_NOTFOUND) {
return false;
}
return true;
}

packet的base类,偷懒,将所有实现都放在头文件中了,有洁癖的可以自己拆
  

  #pragma once
  

#ifndef ES_TCP_MAX_BUFFER    //TCP socket 最大接收 Buffer Size
#   defineES_TCP_MAX_BUFFER    1024*16
#endif


#ifndef _WINDEF_
typedef unsigned char       BYTE;
#endif
// STL头文件定义
#include <string>
#include <queue>
#include <vector>
#include <deque>
#include <list>
#include <iostream>
#include <sstream>
#include <map>
#include <arpa/inet.h>
#include <iomanip>
using namespace std;


#if WIN32
typedef long long       int64_t;
#endif


#ifndef WIN32
#   define _atoi64 atoll
#endif


#define   SERVER_PACEKTVER    1
#define   PROTOL_HEADER_SIZE8


/*
struct TPkgHeader //包头
{
    charcmdConst; //ES
    short cmd;
    short cVersion;
    short length; //body长度
};
*/




typedef unsigned long long __u64;
#define de_htonll(x) \
({ \
    __u64 __x = (x); \
    ((__u64)( \
    (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
    (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
    (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
    (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) <<8) | \
    (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >>8) | \
    (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
    (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
    (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
})




inline long long htonll(long long hvalue)
{
    //判断本机是大端还是小端
    shorti=20;
    if( htons(i) == i ) //本地是大端
    {
      return hvalue;
    }
    else //本地是小端,需要转换
    {
      return (long long)de_htonll(hvalue);
    }
}


inline long long ntohll(long long nvalue)
{
    //判断本机是大端还是小端
    shorti=20;
    if( htons(i) == i ) //本地是大端
    {
      return nvalue;
    }
    else //本地是小端,需要转换
    {
      return (long long)de_htonll(nvalue);
    }
}




inline string ESHexDumpImp(const void *pdata, unsigned int len)
{
      string outstr;
       if(pdata == 0 || len == 0)
      {
            return &quot;&quot;;
      }
   
      int cnt = 0;
      int n = 0;
      int cnt2 = 0;
      stringstreamsstr;
      const char *data = (const char *)pdata;
      sstr<<&quot;Address               Hexadecimal values                  Printable\n&quot;;
      sstr<<&quot;-------------------------------------------------------------------\n&quot;;
      unsigned char buffer;
      unsigned int rpos = 0;


      while ( 1 )
      {
                if(len <= rpos)
                {
                        break;
                }
                if(len >= rpos &#43; 16)
                {
                        memcpy(buffer, data &#43; rpos, 16);
                        rpos &#43;= 16;
                        cnt = 16;
                }
                else
                {
                        memcpy(buffer, data &#43; rpos, len - rpos);
                        cnt = len - rpos;
                        rpos = len;
                }
                if(cnt <= 0)
                {
                        outstr = sstr.str();
                        return outstr;
                }


                sstr << setw(7) << ( int ) rpos << &quot;&quot;;


                cnt2 = 0;
                for ( n = 0; n < 16; n&#43;&#43; )
                {
                        cnt2 = cnt2 &#43; 1;
                        if ( cnt2 <= cnt )
                        {
                              sstr << hex << setw(2) << setfill ( '0' ) <<(unsigned int)buffer;
                        }
                        else
                        {
                              sstr << &quot;&quot;;
                        }
                        sstr << &quot; &quot;;
                }


                sstr << setfill ( ' ' );


                sstr << &quot; &quot;;
                cnt2 = 0;
                for ( n = 0; n < 16; n&#43;&#43; )
                {
                        cnt2 = cnt2 &#43; 1;
                        if ( cnt2 <= cnt )
                        {
                              if ( buffer < 32 || 126 < buffer )
                              {
                                        sstr << '.';
                              }
                              else
                              {
                                        sstr << buffer;
                              }
                        }
                }
                sstr << &quot;\n&quot;;
                sstr << dec;
      }


      outstr = sstr.str();
      return outstr;
}






template <unsigned _buffer_size, unsigned _header_size>
class PacketBase
{
public:
    char *packet_buf(void)   {return m_strBuf;}
    unsigned packet_size(void)    {return m_nPacketSize;}
protected:
PacketBase(void){}
    ~PacketBase(void){}
    enum
    {
      PACKET_HEADER_SIZE = _header_size,
      PACKET_BUFFER_SIZE = _buffer_size
    };
unsignedm_nPacketSize ; // 实际报文总长度
    unsignedm_nBufPos;
    char m_strBuf;// 报文包缓存


protected:
    ////////////////////////////////////////////////////////////////////////////////
    bool _copy(const void *pInBuf, unsigned nLen)
    {
      if(NULL==pInBuf || nLen > PACKET_BUFFER_SIZE){
            return false;
}


      _reset();
      memcpy(m_strBuf, pInBuf, nLen);
      m_nPacketSize = nLen;
      //assert(m_nPacketSize>PACKET_HEADER_SIZE);
      return true;
    }
    ////////////////////////////////////////////////////////////////////////////////
    void _begin(short nCmdType, short cVersion)
    {
      _reset();
      _writeHeader(&quot;ES&quot;, sizeof(char)*2, 0);// 命令码


      short cmdType = htons(nCmdType);
      _writeHeader((char*)&cmdType, sizeof(short), 2);// 命令码
      
      short version = htons(cVersion);
      _writeHeader((char*)&version, sizeof(short), 4);       // 版本号
    }


    void _SetBegin(short nCmdType)
    {
      short cmdType = htons(nCmdType);
      _writeHeader((char*)&cmdType, sizeof(short), 2);// 命令码
    }
public:
    short GetCmdType(void)
    {
      short nCmdType;
      _readHeader((char*)&nCmdType, sizeof(short), 2);// 命令码
      return ntohs(nCmdType);
    }
    short GetVersion(void)
    {
      short c;
      _readHeader((char *)&c, sizeof(short), 4);// 版本号
      return ntohs(c);
    }
    short GetBodyLength(void)
    {
      short nLen;
      _readHeader((char*)&nLen, sizeof(short), 6);// 包正文长度
      return ntohs(nLen);
    }


protected:
    void _end(unsigned /*sequence*/ = 0)
    {
      short nBody = m_nPacketSize - PACKET_HEADER_SIZE;
      short bodyLen = htons(nBody);
      _writeHeader((char*)&bodyLen, sizeof(short), 6);// 包正文长度
    }


    /////////////////////////////////////////////////////////////////////////////////
    void _reset(void)
    {
      memset(m_strBuf, 0, PACKET_BUFFER_SIZE);
      m_nBufPos = PACKET_HEADER_SIZE;
      m_nPacketSize = PACKET_HEADER_SIZE;
    }
    // 取出一个变量
    bool _Read(char *pOut, unsigned nLen)
    {
      if((nLen &#43; m_nBufPos) > m_nPacketSize )
            return false ;


      memcpy(pOut, m_strBuf &#43; m_nBufPos, nLen);
      m_nBufPos &#43;= nLen;
      return true;
    }
    //取出变量并从包中移除
    bool _ReadDel(char *pOut, unsigned nLen)
    {
      if(!_Read(pOut, nLen)){
            return false;
}
      memcpy(m_strBuf &#43; m_nBufPos - nLen, m_strBuf &#43; m_nBufPos, PACKET_BUFFER_SIZE - m_nBufPos);
      m_nBufPos -= nLen;
      m_nPacketSize -= nLen;
      _end();
      return true;
    }
    //读撤消
    void _readundo(unsigned nLen)
    {
      m_nBufPos -= nLen;
    }
    //读出当前POS位置的BUFFER指针
    char *_readpoint(unsigned nLen) //注意返回的是指针 请慎重使用string
    {
      if((nLen &#43; m_nBufPos) > m_nPacketSize){
            return NULL;
}
      char *p = &m_strBuf;
      m_nBufPos &#43;= nLen;
      return p;


    }
    // 写入一个变量
    bool _Write(const char *pIn, unsigned nLen)
    {
      if( (nLen &#43; m_nPacketSize) > PACKET_BUFFER_SIZE){
            return false ;
}
      memcpy(m_strBuf&#43;m_nPacketSize, pIn, nLen);
      m_nPacketSize &#43;= nLen;
      return true;
    }
    //插入一个变量
    bool _Insert(const char *pIn, unsigned nLen)
    {
      if((nLen &#43; m_nPacketSize) > PACKET_BUFFER_SIZE){
            return false;
}
      memcpy(m_strBuf&#43;PACKET_HEADER_SIZE&#43;nLen, m_strBuf&#43;PACKET_HEADER_SIZE, m_nPacketSize-PACKET_HEADER_SIZE);
      memcpy(m_strBuf&#43;PACKET_HEADER_SIZE, pIn, nLen);
      m_nPacketSize &#43;= nLen;
      _end();
      return true;
    }
    // 写入一个变量
    bool _writezero(void)
    {
      if((m_nPacketSize &#43; 1) > PACKET_BUFFER_SIZE){
            return false ;
}
      memset(m_strBuf&#43;m_nPacketSize, '\0', sizeof(char)) ;
      m_nPacketSize &#43;&#43;;
      return true;
    }
    // readHeader
    void _readHeader(char *pOut, unsigned nLen, unsigned nPos)
    {
      if( nPos&#43;nLen <= PACKET_HEADER_SIZE)
      {
            memcpy(pOut, m_strBuf&#43;nPos, nLen) ;
      }
    }
    // writeHeader
    void _writeHeader(char *pIn, unsigned nLen, unsigned nPos)
    {
      if( nPos&#43;nLen <= PACKET_HEADER_SIZE)
      {
            memcpy(m_strBuf&#43;nPos, pIn, nLen) ;
      }
    }
};


template <unsigned BUFFER_SIZE, unsigned HEADER_SIZE=PROTOL_HEADER_SIZE>
class InputPacket: public PacketBase<BUFFER_SIZE, HEADER_SIZE>
{
public:
    typedef PacketBase<BUFFER_SIZE, HEADER_SIZE> base;


    int ReadInt(void)
    {
      //这里必需初始化
      int nValue = -1;
      base::_Read((char*)&nValue, sizeof(int));
      return ntohl(nValue);
    }


    short ReadShort(void)
    {
      short nValue = -1;
      base::_Read((char*)&nValue, sizeof(short));
      return ntohs(nValue);
    }


    BYTE ReadByte(void)
    {
      BYTE nValue = -1;
      base::_Read((char*)&nValue, sizeof(BYTE));
      return nValue;
    }


    int64_t ReadInt64(void)
    {
      int64_t nValue = -1;
      base::_Read((char*)&nValue, sizeof(int64_t));
      return ntohll(nValue);
    }


    bool ReadString(char *pOutString, unsigned nMaxLen)
    {
      int nLen = ReadInt();
      if(nLen == -1){//这里必需判断
            return false;
}
      if(nLen > nMaxLen || nLen&#43;base::m_nBufPos>base::m_nPacketSize )
      {
            base::_readundo(sizeof(unsigned));
            return false;
      }
      return base::_Read(pOutString, nLen);
    }


    char *ReadChar(void)
    {
      unsigned nLen = ReadInt();
      if(nLen == (unsigned)-1 || nLen&#43;base::m_nBufPos>base::m_nPacketSize) {
base::_readundo(sizeof(unsigned));
return NULL;
}
      return base::_readpoint(nLen);
    }


    bool ReadString(string &str)
    {
      char *p = ReadChar();
      str =(p == NULL ? &quot;&quot; : p);
return p != NULL;
    }


    int ReadBinary(char *pBuf, unsigned nMaxLen)
    {
      unsigned nLen = ReadInt();
      if(nLen == (unsigned)-1 || nLen > nMaxLen || nLen&#43;base::m_nBufPos>base::m_nPacketSize )
      {
            base::_readundo(sizeof(unsigned));
            return -1;
      }
      if(base::_Read(pBuf, nLen)){
            return nLen ;
}
      return 0;
    }
    void Reset(void)
    {
      base::_reset();
    }
    bool Copy(const void *pInBuf, unsigned nLen)
    {
      return base::_copy(pInBuf, nLen);
    }
};


template <unsigned BUFFER_SIZE, unsigned HEADER_SIZE=PROTOL_HEADER_SIZE>
class OutputPacket: public PacketBase<BUFFER_SIZE, HEADER_SIZE>
{
public:
    OutputPacket(void){}
public:
    typedef PacketBase<BUFFER_SIZE, HEADER_SIZE> base;


    bool WriteInt(int nValue)
    {
      int value = htonl(nValue);
      return base::_Write((char*)&value, sizeof(int));
    }


    bool WriteInt64(int64_t nValue)   
    {
      int64_t value = htonll(nValue);
      return base::_Write((char*)&value, sizeof(int64_t));
    }


    bool WriteByte(BYTE nValue)   
    {
      return base::_Write((char*)&nValue, sizeof(BYTE));
    }


    bool WriteShort(short nValue)
    {
      short value = htons(nValue);
      return base::_Write((char*)&value, sizeof(short));
    }


    //在正文首插入数据
    bool InsertInt(int nValue)
    {
      int value = htonl(nValue);
      return base::_Insert((char*)&value, sizeof(int));
    }


    bool InsertByte(BYTE nValue)   
    {
      return base::_Insert((char*)&nValue, sizeof(BYTE));
    }


    bool WriteString(const char *pString)
    {
      int nLen = (int)strlen(pString) ;
      WriteInt(nLen &#43; 1) ;
      return base::_Write(pString, nLen) && base::_writezero();
    }


    bool WriteString(const string &strDate)
    {
      int nLen = strDate.size();
      WriteInt(nLen &#43; 1) ;
      return base::_Write(strDate.c_str(), nLen) && base::_writezero();
    }


    bool WriteBinary(const char *pBuf, unsigned nLen)
    {
      WriteInt(nLen) ;
      return base::_Write(pBuf, nLen) ;
    }
    bool Copy(const void *pInBuf, unsigned nLen)
    {
      return base::_copy(pInBuf, nLen);
    }
    void Begin(short nCommand, char cVersion = SERVER_PACEKTVER)
    {
      base::_begin(nCommand, cVersion);
    }
    void End(void)
    {
      base::_end();
    }
   
    void SetBegin(short nCommand)
    {
      base::_SetBegin(nCommand);
    }
};


typedef InputPacket<ES_TCP_MAX_BUFFER>   ESInputPacket;
typedef OutputPacket<ES_TCP_MAX_BUFFER>ESOutputPacket;

  

  

         版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: 对一个memcache的封装