对一个memcache的封装
来源:互联网 发布:淘宝店铺招牌怎么制作 编辑:程序博客网 时间:2024/04/28 03:40
最近对一个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 "ESMemcache.h"
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 + 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
# define ES_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_SIZE 8
/*
struct TPkgHeader //包头
{
char cmdConst[2]; //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)
{
//判断本机是大端还是小端
short i=20;
if( htons(i) == i ) //本地是大端
{
return hvalue;
}
else //本地是小端,需要转换
{
return (long long)de_htonll(hvalue);
}
}
inline long long ntohll(long long nvalue)
{
//判断本机是大端还是小端
short i=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 "";
}
int cnt = 0;
int n = 0;
int cnt2 = 0;
stringstream sstr;
const char *data = (const char *)pdata;
sstr<<"Address Hexadecimal values Printable\n";
sstr<<"------- ----------------------------------------------- -------------\n";
unsigned char buffer[20];
unsigned int rpos = 0;
while ( 1 )
{
if(len <= rpos)
{
break;
}
if(len >= rpos + 16)
{
memcpy(buffer, data + rpos, 16);
rpos += 16;
cnt = 16;
}
else
{
memcpy(buffer, data + rpos, len - rpos);
cnt = len - rpos;
rpos = len;
}
if(cnt <= 0)
{
outstr = sstr.str();
return outstr;
}
sstr << setw(7) << ( int ) rpos << " ";
cnt2 = 0;
for ( n = 0; n < 16; n++ )
{
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt )
{
sstr << hex << setw(2) << setfill ( '0' ) << (unsigned int)buffer[n];
}
else
{
sstr << " ";
}
sstr << " ";
}
sstr << setfill ( ' ' );
sstr << " ";
cnt2 = 0;
for ( n = 0; n < 16; n++ )
{
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt )
{
if ( buffer[n] < 32 || 126 < buffer[n] )
{
sstr << '.';
}
else
{
sstr << buffer[n];
}
}
}
sstr << "\n";
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
};
unsigned m_nPacketSize ; // 实际报文总长度
unsigned m_nBufPos;
char m_strBuf[PACKET_BUFFER_SIZE]; // 报文包缓存
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("ES", 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 + m_nBufPos) > m_nPacketSize )
return false ;
memcpy(pOut, m_strBuf + m_nBufPos, nLen);
m_nBufPos += nLen;
return true;
}
//取出变量并从包中移除
bool _ReadDel(char *pOut, unsigned nLen)
{
if(!_Read(pOut, nLen)){
return false;
}
memcpy(m_strBuf + m_nBufPos - nLen, m_strBuf + 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 + m_nBufPos) > m_nPacketSize){
return NULL;
}
char *p = &m_strBuf[m_nBufPos];
m_nBufPos += nLen;
return p;
}
// 写入一个变量
bool _Write(const char *pIn, unsigned nLen)
{
if( (nLen + m_nPacketSize) > PACKET_BUFFER_SIZE){
return false ;
}
memcpy(m_strBuf+m_nPacketSize, pIn, nLen);
m_nPacketSize += nLen;
return true;
}
//插入一个变量
bool _Insert(const char *pIn, unsigned nLen)
{
if((nLen + m_nPacketSize) > PACKET_BUFFER_SIZE){
return false;
}
memcpy(m_strBuf+PACKET_HEADER_SIZE+nLen, m_strBuf+PACKET_HEADER_SIZE, m_nPacketSize-PACKET_HEADER_SIZE);
memcpy(m_strBuf+PACKET_HEADER_SIZE, pIn, nLen);
m_nPacketSize += nLen;
_end();
return true;
}
// 写入一个变量
bool _writezero(void)
{
if((m_nPacketSize + 1) > PACKET_BUFFER_SIZE){
return false ;
}
memset(m_strBuf+m_nPacketSize, '\0', sizeof(char)) ;
m_nPacketSize ++;
return true;
}
// readHeader
void _readHeader(char *pOut, unsigned nLen, unsigned nPos)
{
if( nPos+nLen <= PACKET_HEADER_SIZE)
{
memcpy(pOut, m_strBuf+nPos, nLen) ;
}
}
// writeHeader
void _writeHeader(char *pIn, unsigned nLen, unsigned nPos)
{
if( nPos+nLen <= PACKET_HEADER_SIZE)
{
memcpy(m_strBuf+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+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+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 ? "" : p);
return p != NULL;
}
int ReadBinary(char *pBuf, unsigned nMaxLen)
{
unsigned nLen = ReadInt();
if(nLen == (unsigned)-1 || nLen > nMaxLen || nLen+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 + 1) ;
return base::_Write(pString, nLen) && base::_writezero();
}
bool WriteString(const string &strDate)
{
int nLen = strDate.size();
WriteInt(nLen + 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;
- 对一个memcache的封装
- 一个简单的Memcache和PDO封装类
- 对jquery的ajax的一个封装
- 对JMagick的一个简单封装
- 对下载进行一个简单的封装
- 一个菜鸟对封装,继承等的的简单认知
- 一个对Winsock 完成端口模型封装的类
- 封装一个对磁盘,文件夹,文件进行遍历的类
- 一个对Winsock 完成端口模型封装的类
- 一个对Winsock 完成端口模型封装的类
- 属性是对一个或者多个字段的封装.
- 一个对Winsock完成端口模型封装的类
- 一个对Winsock完成端口模型封装的类
- 一个对Winsock 完成端口模型封装的类
- 一个对Winsock 完成端口模型封装的类
- 【转】一个对Winsock 完成端口模型封装的类
- 一个对Winsock 完成端口模型封装的类
- 一个对Winsock 完成端口模型封装的类【2】
- Socket对话
- MYSQL学习笔记 第四讲:列属性
- hdu1690
- HDU 2199
- Nginx工作原理和优化
- 对一个memcache的封装
- 解决sudo timestamp too far in the future
- DOM、JDOM、DOM4J的区别
- matplotlib画图(4)
- POJ 1274 The Perfect Stall
- C++ strcpy 函数的实现
- 使用独立PID namespace防止误杀进程
- Eclipse用法和技巧十九:eclipse修改workspace
- hdu2993 MAX Average Problem(斜率+单调队列)