Hiredis是一个开源C库函数,提供了基本的操作redis 函数, 如数据库连接、发送命令、释放资源等等
hiredis 本身就是做了跨平台的代码,c语言打造可以执行在多种平台上,看看他的net块做了些什么
#include "fmacros.h"
#include
#ifdef _WIN32
#ifndef FD_SETSIZE
#define FD_SETSIZE 16000
#endif
#else
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#ifndef _WIN32
#include
#endif
#include
#include "net.h"
#include "sds.h"
#ifdef _WIN32
#include "../src/win32fixes.h"
#endif
看他的头文件,分析一下,linux下是使用poll 和 epoll方式的,windows下使用select 和IOCP 异步方式,对iocp的封装在win32_iocp.h 和win32_iocp.c 里面对于客户端来说,poll方式是可以了,比select方式效率还是要高,不过poll在windows和linux操作系统上还是可以使用封装来通用的。所以里面还有一个asycn 封装模块,异步回调。c语言写的东西确实简单易懂。
2、线程锁和互斥来看一下他对加锁方面的写法,实际上,在windows上使用了api互斥变量,在linux上使用pthread,通用做法,这对做数据库系统客户端来说是很有帮助的,简化编程,在windows上直接调用锁api方式效率更高。
#define pthread_mutex_t CRITICAL_SECTION
#define pthread_attr_t ssize_t
#define pthread_mutex_init(a,b) (InitializeCriticalSectionAndSpinCount((a), 0x80000400),0)
#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
#define pthread_mutex_lock EnterCriticalSection
#define pthread_mutex_unlock LeaveCriticalSection
#define pthread_equal(t1, t2) ((t1) == (t2))
#define pthread_attr_init(x) (*(x) = 0)
#define pthread_attr_getstacksize(x, y) (*(y) = *(x))
#define pthread_attr_setstacksize(x, y) (*(x) = y)
#define pthread_t u_int
3、hash
typedef struct dictEntry {
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
typedef struct dictType {
unsigned int (*hashFunction)(const void *key);
void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
3.1 hash 函数
/* Generic hash function (a popular one from Bernstein).
* I tested a few and this was the best. */
static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
unsigned int hash = 5381;
while (len--)
hash = ((hash table[index];
ht->table[index] = entry;
/* Set the hash entry fields. */
dictSetHashKey(ht, entry, key);
dictSetHashVal(ht, entry, val);
ht->used++;
return DICT_OK;
}
这个对于使用c语言的程序员最熟悉不过了,实际上就是hash-》链表,寻址,检测冲突,增加,挂链表。整个hash表操作增删改查,400多行代码,精简,效率好。
4、 链表typedef struct listNode {
struct listNode *prev;
struct listNode *next;
void *value;
} listNode;
typedef struct listIter {
listNode *next;
int direction;
} listIter;
typedef struct list {
listNode *head;
listNode *tail;
void *(*dup)(void *ptr);
void (*free)(void *ptr);
int (*match)(void *ptr, void *key);
unsigned long len;
} list;
/* Functions implemented as macros */
#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)
#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))
#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
/* Prototypes */
list *listCreate(void);
void listRelease(list *list);
list *listAddNodeHead(list *list, void *value);
list *listAddNodeTail(list *list, void *value);
list *listInsertNode(list *list, listNode *old_node, void *value, int after);
void listDelNode(list *list, listNode *node);
listIter *listGetIterator(list *list, int direction);
listNode *listNext(listIter *iter);
void listReleaseIterator(listIter *iter);
list *listDup(list *orig);
listNode *listSearchKey(list *list, void *key);
listNode *listIndex(list *list, long index);
void listRewind(list *list, listIter *li);
void listRewindTail(list *list, listIter *li);
void listRotate(list *list);
链表加尾
list *listAddNodeTail(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return list;
}
链表操作简直就是数据结构课程基础课,如果读者是年轻的程序员,无论是使用java,c,c++,还是其他语言的使用者,这个模块可以作为通用学习模块。
5、aeae是hiredis的一个事件消息loop模块,被封装在ae.h 和ae.cpp 中 下面是一个文件创建消息的eventloop
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData)
{
aeFileEvent *fe;
if (fd >= eventLoop->setsize) {
errno = ERANGE;
return AE_ERR;
}
fe = &eventLoop->events[fd];
if (aeApiAddEvent(eventLoop, fd, mask) == -1)
return AE_ERR;
fe->mask |= mask;
if (mask & AE_READABLE) fe->rfileProc = proc;
if (mask & AE_WRITABLE) fe->wfileProc = proc;
fe->clientData = clientData;
if (fd > eventLoop->maxfd)
eventLoop->maxfd = fd;
return AE_OK;
}
还有iocp的事件,epoll事件,时间事件等等。
总结总的来说,对于做一个数据库系统来说,无论是客户端还是服务器端,都有很多需要我们做的,做一个精品需要我们在细节上下更多的功夫。
封装简单用c++ 封装一下,更容易使用
#ifndef _REDIS_CLIENT_H_
#define _REDIS_CLIENT_H_
#include "../hiredis/hiredis.h"
#include
#include
using namespace std;
class Redis
{
public:
Redis();
~Redis();
public:
int Connect(const char * ip, int port);
void disConnect();
public:
void setString(const string & key, const string & value);
void setString(const string & key, const int & value);
void setString(const string & key, const float & value);
bool SetBinary(const string & key, void* pData, int dataLen);
bool GetBinary(const string & key, void*pData, int datalen);
private:
void setString(const string & data);
public:
void getString(const string & key, string & value);
void getString(const string & key, int & value);
void getString(const string & key, float & value);
private:
void getString(const string & key);
private:
void freeReply();
bool isError();
private:
redisContext * _context = NULL;
redisReply * _reply = NULL;
string _ip;
int _port;
};
#include "redisclient.h"
#include
#include
#include
#include
using std::cout;
using std::endl;
using std::stringstream;
#define SETSTRING(key, value) \
stringstream ss;\
ss
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?