acl/lib_acl_cpp/include/acl_cpp/memcache/memcache.hpp

253 lines
7.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <time.h>
#include "acl_cpp/connpool/connect_client.hpp"
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/mime/rfc2047.hpp"
namespace acl {
class socket_stream;
typedef class memcache mem_cache;
/**
* memcached 客户端通信协议库,支持长连接与自动重连
*/
class ACL_CPP_API memcache : public connect_client
{
public:
/**
* 构造函数
* @param addr {const char*} memcached 服务器监听地址,格式为:
* ip:port如: 127.0.0.1:11211
* @param conn_timeout {int} 连接服务器的超时时间(秒)
* @param rw_timeout {int} 网络 IO 超时时间(秒)
*/
memcache(const char* addr = "127.0.0.1:11211", int conn_timeout = 30,
int rw_timeout = 10);
~memcache();
/**
* 设置 key 的前缀,即实际的 key 将由 该前缀+原始key 组成,缺省时不设
* 前缀,当多个应用共用同一个 memcached 服务时,建议应用设置自身的
* key 前缀,这样可以避免与其它应用的 key 产生重复问题
* @param keypre {const char*} 非空时设置 key 前缀,否则取消 key 前缀
* @return {memcache&}
*/
memcache& set_prefix(const char* keypre);
/**
* 在保持的长连接中断时是否要求自动重连,缺省为自动重连
* @param onoff {bool} 为 true 时表示长连接意外断开后自动重连
* @return {memcache&}
*/
memcache& auto_retry(bool onoff);
/**
* 设置是否针对 KEY 键值进行编码,缺少时不对 key 编码,当应用的 key 中
* 可能会有特殊字符或二进制值时,建议调用此函数对 key 进行编码
* @param onoff {bool} 为 true 表示内部需要对 key 进行编码
* @return {memcache&}
*/
memcache& encode_key(bool onoff);
/**
* 向 memcached 中修改或添加新的数据缓存对象
* @param key {const char*} 键值
* @param klen {size_t} key 键值长度
* @param dat {const void*} 数据
* @param dlen {size_t} data 数据长度
* @param timeout {time_t} 缓存超时时间(秒)
* @param flags {unsigned short} 附属的标志位
* @return {bool} 是否成功
*/
bool set(const char* key, size_t klen,
const void* dat, size_t dlen,
time_t timeout = 0, unsigned short flags = 0);
/**
* 向 memcached 中修改或添加新的数据缓存对象
* @param key {const char*} 字符串键值
* @param dat {const void*} 数据
* @param dlen {size_t} data 数据长度
* @param timeout {time_t} 缓存超时时间(秒)
* @param flags {unsigned short} 附属的标志位
* @return {bool} 是否成功
*/
bool set(const char* key, const void* dat, size_t dlen,
time_t timeout = 0, unsigned short flags = 0);
/**
* 更新 memcached 中已经存在的键的过期日期,因为目前 libmemcached 没有
* 提供此接口,所以该函数实现的方式是先调用 get 取出对应键的值,然后再
* 调用 set 重新设置该键的值及过期时间
* @param key {const char*} 键值
* @param klen {size_t} key 键值长度
* @param timeout {time_t} 过期时间(秒)
* @return {bool} 是否成功
*/
bool set(const char* key, size_t klen, time_t timeout = 0);
/**
* 更新 memcached 中已经存在的键的过期日期,因为目前 libmemcached 没有
* 提供此接口,所以该函数实现的方式是先调用 get 取出对应键的值,然后再
* 调用 set 重新设置该键的值及过期时间
* @param key {const char*} 字符串键值
* @param timeout {time_t} 过期时间(秒)
* @return {bool} 是否成功
*/
bool set(const char* key, time_t timeout = 0);
/**
* 以流式方式上传大数据时,该函数发送数据头
* @param key {const char*} 键值字符串
* @param dlen {size_t} 数据体的数据总长度
* @param timeout {time_t} 数据的过期时间(秒)
* @param flags {unsigned short} 附属的标志位
* @return {bool} 是否成功
*/
bool set_begin(const char* key, size_t dlen,
time_t timeout = 0, unsigned short flags = 0);
/**
* 循环调用本函数上传数据值,内部会自动计算已经上传的数据总和是否达到
* 了 set_begin 中设置的数据总长度,当达到后会自动补一个 "\r\n",调用
* 者不应再调用此函数上传数据,除非是一个新的上传过程开始了
* @param data {const void*} 数据地址指针
* @param len {data} data 数据长度
* @return {bool} 是否成功
*/
bool set_data(const void* data, size_t len);
/**
* 从 memcached 中获得对应键值的缓存数据
* @param key {const char*} 字符串键值
* @param klen {size_t} 键值长度
* @param buf {string&} 存储结果的缓冲区,内部首先会清空该缓冲区
* @param flags {unsigned short*} 存储附属的标志位
* @return {bool} 返回 true 表示正确获得结果值,否则表示键值对应的
* 数据不存在或出错
*/
bool get(const char* key, size_t klen, string& buf,
unsigned short* flags = NULL);
/**
* 从 memcached 中获得对应键值的缓存数据
* @param key {const char*} 字符串键值
* @param buf {string&} 存储结果的缓冲区,内部首先会清空该缓冲区
* @param flags {unsigned short*} 存储附属的标志位
* @return {bool} 返回 true 表示正确获得结果值,否则表示键值对应的
* 数据不存在或出错
*/
bool get(const char* key, string& buf, unsigned short* flags = NULL);
/**
* 流式方式从服务端获取数据,本函数发送请求协议
* @param key {const void*} 键值
* @param klen {size_t} key 键值长度
* @param flags {unsigned short*} 存储附属的标志位
* @return {int} 返回数据体的长度,分以下三种情形:
* 0表示不存在
* -1表示出错
* >0表示数据体的长度
*/
int get_begin(const void* key, size_t klen, unsigned short* flags = NULL);
/**
* 流式方式从服务端获取数据,本函数发送请求协议
* @param key {const char*} 键值字符串
* @param flags {unsigned short*} 存储附属的标志位
* @return {int} 返回数据体的长度,分以下三种情形:
* 0表示不存在
* -1表示出错
* >0表示数据体的长度
*/
int get_begin(const char* key, unsigned short* flags = NULL);
/**
* 流式方式从服务端获取数据,循环调用本函数接收数据
* @param buf {void*} 缓冲区地址
* @param size {size_t} 缓冲区大小
* @return {int} 已读到的数据大小,分为以下三种情形:
* 0表示数据读完
* > 0: 表示本次读到的数据长度
* -1表示出错
*/
int get_data(void* buf, size_t size);
/**
* 从 memcached 中删除数据
* @param key {const char*} 键值
* @param klen {size_t} 键值长度
* @return {bool} 删除是否成功
*/
bool del(const char* key, size_t klen);
/**
* 从 memcached 中删除数据
* @param key {const char*} 字符串键值
* @return {bool} 删除是否成功
*/
bool del(const char* key);
/**
* 获得上次操作 memcached 错误描述信息
* @return {const char*} 错误描述信息,永不为空
*/
const char* last_serror() const;
/**
* 获得上次操作 memcached 的错误号
* @return {int} 错误号
*/
int last_error() const;
/**
* 打开与 memcached 的连接, 因为 set/get/del 操作都会自动打开与
* memcached 的连接,所以不必显示地调用此函数来打开与 memcached
* 的连接
* @return {bool} 打开是否成功
*/
virtual bool open();
/**
* 关闭与 memcached 的连接,一般该函数不需要调用,因为类对象在
* 析构时会自动调用此函数
*/
void close();
/**
* 列出 memcached 连接的一些属性,调试用
*/
void property_list();
private:
bool set(const string& key, const void* dat, size_t dlen,
time_t timeout, unsigned short flags);
bool get(const string& key, string& buf, unsigned short* flags);
const string& build_key(const char* key, size_t klen);
string* keypre_; // 非空时,该字符串被添加在 KEY 值前组成新的 KEY
rfc2047 coder_; // 当需要对 KEY 编码时的编码器
bool encode_key_; // 是否需要对 KEY 进行编码
bool opened_; // 连接是否打开
bool retry_; // 是否支持连接中断重试
char* addr_; // 服务地址(ip:port)
int enum_; // 出错号,留作将来扩充用
string ebuf_; // 存储出错信息
string kbuf_; // 存储经转码后的 KEY 值缓冲区
size_t content_length_; // 当采用流式上传/下载大数据时此值记录数据体的总长度
size_t length_; // 已经上传/下载的数据总和
socket_stream* conn_; // 与后端服务的连接对象
string req_line_; // 存储请求数据
string res_line_; // 存储响应数据
bool error_happen(const char* line);
};
} // namespace acl