libevent中文件queue.h文件包含5种数据结构:单链表,双向链表,队列,尾队列,环形队列。在处理I/O和signal中的事件时,用的就是尾队列,下面就介绍这几种数据结构

1、单链表

链表头用宏SLIT_HEAD来定义

#define SLIST_HEAD(name, type)                       \
struct name {                               \struct type *slh_first;    /* first element */         \
}

链表中的元素用宏SLIST_ENTRY定义

#define SLIST_ENTRY(type)                        \
struct {                                \struct type *sle_next; /* next element */          \
}

单链表的逻辑结构图表示为

包含的操作有元素后插入,头部插入,头部删除

元素后插入宏定义

#define  SLIST_INSERT_AFTER(slistelm, elm, field) do {           \(elm)->field.sle_next = (slistelm)->field.sle_next;     \(slistelm)->field.sle_next = (elm);                \
} while (0)

头部插入

#define  SLIST_INSERT_HEAD(head, elm, field) do {            \(elm)->field.sle_next = (head)->slh_first;          \(head)->slh_first = (elm);                 \
} while (0)

头部删除

#define  SLIST_REMOVE_HEAD(head, field) do {             \(head)->slh_first = (head)->slh_first->field.sle_next;       \
} while (0)

2、双链表

双链表头宏定义为

#define LIST_HEAD(name, type)                        \
struct name {                               \struct type *lh_first; /* first element */         \
}

双链表中元素宏定义为

#define LIST_ENTRY(type)                     \
struct {                                \struct type *le_next;  /* next element */          \struct type **le_prev; /* address of previous next element */  \  //前一个成员le_next的地址
}

逻辑结构图为

元素后插入

#define LIST_INSERT_AFTER(listelm, elm, field) do {          \if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \(listelm)->field.le_next->field.le_prev =       \&(elm)->field.le_next;              \(listelm)->field.le_next = (elm);              \(elm)->field.le_prev = &(listelm)->field.le_next;       \
} while (0)

逻辑结构图为

元素前插入

#define  LIST_INSERT_BEFORE(listelm, elm, field) do {            \(elm)->field.le_prev = (listelm)->field.le_prev;        \(elm)->field.le_next = (listelm);              \*(listelm)->field.le_prev = (elm);             \(listelm)->field.le_prev = &(elm)->field.le_next;       \
} while (0)

列表头插入

#define LIST_INSERT_HEAD(head, elm, field) do {              \if (((elm)->field.le_next = (head)->lh_first) != NULL)     \(head)->lh_first->field.le_prev = &(elm)->field.le_next;\(head)->lh_first = (elm);                   \(elm)->field.le_prev = &(head)->lh_first;           \
} while (0)

元素删除

#define LIST_REMOVE(elm, field) do {                 \if ((elm)->field.le_next != NULL)              \(elm)->field.le_next->field.le_prev =           \(elm)->field.le_prev;               \*(elm)->field.le_prev = (elm)->field.le_next;           \
} while (0)

元素替换

#define LIST_REPLACE(elm, elm2, field) do {              \if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)    \(elm2)->field.le_next->field.le_prev =          \&(elm2)->field.le_next;             \(elm2)->field.le_prev = (elm)->field.le_prev;           \*(elm2)->field.le_prev = (elm2);               \
} while (0)

3、简单队列

简单队列主要包含头插入,尾插入,元素后插入,头删除操作

/** Simple queue definitions.*///简单队列头定义
#define SIMPLEQ_HEAD(name, type)                    \
struct name {                               \struct type *sqh_first;    /* first element */         \struct type **sqh_last;    /* addr of last next element */     \
}//队列头初始化,sqh_first=NULL, sqh_last=&sql_first
#define SIMPLEQ_HEAD_INITIALIZER(head)                  \{ NULL, &(head).sqh_first }//简单队列元素定义
#define SIMPLEQ_ENTRY(type)                     \
struct {                                \struct type *sqe_next; /* next element */          \
}/** Simple queue access methods.*/
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)  //队列头
#define SIMPLEQ_END(head)       NULL                //队列尾
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))  //队列空的判断
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)  //队列元素的下一个元素//简单队列遍历
#define SIMPLEQ_FOREACH(var, head, field)               \for((var) = SIMPLEQ_FIRST(head);              \(var) != SIMPLEQ_END(head);                   \(var) = SIMPLEQ_NEXT(var, field))/** Simple queue functions.*///简单队列初始化
#define SIMPLEQ_INIT(head) do {                     \(head)->sqh_first = NULL;                  \(head)->sqh_last = &(head)->sqh_first;              \
} while (0)//简单队列头插入元素
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {          \if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \(head)->sqh_last = &(elm)->field.sqe_next;      \(head)->sqh_first = (elm);                 \
} while (0)//简单队列尾插入元素
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {          \(elm)->field.sqe_next = NULL;                  \*(head)->sqh_last = (elm);                 \(head)->sqh_last = &(elm)->field.sqe_next;          \
} while (0)//简单队列元素后插入元素
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {        \if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\(head)->sqh_last = &(elm)->field.sqe_next;        \(listelm)->field.sqe_next = (elm);             \
} while (0)//队列头部删除元素
#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {          \if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)  \(head)->sqh_last = &(head)->sqh_first;          \
} while (0)

4、尾队列

尾队列中主要包含队列头插入,尾插入,元素后插入,元素前插入,元素删除,元素替换。libevent中用到的队列其实也是尾队列

/** Tail queue definitions.*///尾队列头定义,其中tqh_last表示最后一个元素的地址
#define TAILQ_HEAD(name, type)                      \
struct name {                               \struct type *tqh_first;    /* first element */         \struct type **tqh_last;    /* addr of last next element */     \
}//队列初始化
#define TAILQ_HEAD_INITIALIZER(head)                    \{ NULL, &(head).tqh_first }//队列元素定义
#define TAILQ_ENTRY(type)                       \
struct {                                \struct type *tqe_next; /* next element */          \struct type **tqe_prev;    /* address of previous next element */  \
}/** tail queue access methods*/
#define TAILQ_FIRST(head)       ((head)->tqh_first)   //队列中的第一个元素
#define TAILQ_END(head)         NULL                //队列结束
#define TAILQ_NEXT(elm, field)      ((elm)->field.tqe_next) //队列中当前元素的下一个元素
#define TAILQ_LAST(head, headname)                  \   //两级队列,即第一队列中的每一个元素又是一个队列(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field)                \(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head)                       \   //队列是否为空(TAILQ_FIRST(head) == TAILQ_END(head))  //队列遍历
#define TAILQ_FOREACH(var, head, field)                 \  for((var) = TAILQ_FIRST(head);                  \(var) != TAILQ_END(head);                 \(var) = TAILQ_NEXT(var, field))//二级队列遍历
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)       \for((var) = TAILQ_LAST(head, headname);               \(var) != TAILQ_END(head);                 \(var) = TAILQ_PREV(var, headname, field))/** Tail queue functions.*///队列初始化
#define TAILQ_INIT(head) do {                       \(head)->tqh_first = NULL;                  \(head)->tqh_last = &(head)->tqh_first;              \
} while (0)//队列头插入元素
#define TAILQ_INSERT_HEAD(head, elm, field) do {            \if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)   \(head)->tqh_first->field.tqe_prev =         \&(elm)->field.tqe_next;             \else                               \(head)->tqh_last = &(elm)->field.tqe_next;      \(head)->tqh_first = (elm);                 \(elm)->field.tqe_prev = &(head)->tqh_first;         \
} while (0)//队列尾插入元素
#define TAILQ_INSERT_TAIL(head, elm, field) do {            \(elm)->field.tqe_next = NULL;                  \(elm)->field.tqe_prev = (head)->tqh_last;           \*(head)->tqh_last = (elm);                 \(head)->tqh_last = &(elm)->field.tqe_next;          \
} while (0)//队列元素后插入元素
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {      \if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\(elm)->field.tqe_next->field.tqe_prev =            \&(elm)->field.tqe_next;             \else                               \(head)->tqh_last = &(elm)->field.tqe_next;      \(listelm)->field.tqe_next = (elm);             \(elm)->field.tqe_prev = &(listelm)->field.tqe_next;     \
} while (0)//队列元素前插入
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {           \(elm)->field.tqe_prev = (listelm)->field.tqe_prev;      \(elm)->field.tqe_next = (listelm);             \*(listelm)->field.tqe_prev = (elm);                \(listelm)->field.tqe_prev = &(elm)->field.tqe_next;     \
} while (0)//队列元素删除
#define TAILQ_REMOVE(head, elm, field) do {             \if (((elm)->field.tqe_next) != NULL)               \(elm)->field.tqe_next->field.tqe_prev =         \(elm)->field.tqe_prev;              \else                               \(head)->tqh_last = (elm)->field.tqe_prev;       \*(elm)->field.tqe_prev = (elm)->field.tqe_next;         \
} while (0)//队列元素替换
#define TAILQ_REPLACE(head, elm, elm2, field) do {          \if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)  \(elm2)->field.tqe_next->field.tqe_prev =        \&(elm2)->field.tqe_next;                \else                               \(head)->tqh_last = &(elm2)->field.tqe_next;     \(elm2)->field.tqe_prev = (elm)->field.tqe_prev;         \*(elm2)->field.tqe_prev = (elm2);              \
} while (0)

5、环形队列

操作包含元素前插入, 元素后插入,头插入,尾接入,元素删除,元素替换

/** Circular queue definitions.*///队列头定义
#define CIRCLEQ_HEAD(name, type)                    \
struct name {                               \struct type *cqh_first;        /* first element */     \struct type *cqh_last;     /* last element */      \
}//队列头初始化
#define CIRCLEQ_HEAD_INITIALIZER(head)                  \{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }//队列元素定义
#define CIRCLEQ_ENTRY(type)                     \
struct {                                \struct type *cqe_next;     /* next element */      \struct type *cqe_prev;     /* previous element */      \
}/** Circular queue access methods*/
#define CIRCLEQ_FIRST(head)     ((head)->cqh_first)   //环形队列中的第一个元素
#define CIRCLEQ_LAST(head)      ((head)->cqh_last)   //环形队列中的最后一个元素
#define CIRCLEQ_END(head)       ((void *)(head))
#define CIRCLEQ_NEXT(elm, field)    ((elm)->field.cqe_next)   //下一个元素
#define CIRCLEQ_PREV(elm, field)    ((elm)->field.cqe_prev)   //前一个元素
#define CIRCLEQ_EMPTY(head)                 \    //环形队列是否为空(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))//环形队列遍历
#define CIRCLEQ_FOREACH(var, head, field)               \for((var) = CIRCLEQ_FIRST(head);              \(var) != CIRCLEQ_END(head);                   \(var) = CIRCLEQ_NEXT(var, field))//环形队列反向遍历
#define CIRCLEQ_FOREACH_REVERSE(var, head, field)           \for((var) = CIRCLEQ_LAST(head);                   \(var) != CIRCLEQ_END(head);                   \(var) = CIRCLEQ_PREV(var, field))/** Circular queue functions.*///环形队列初始化
#define CIRCLEQ_INIT(head) do {                     \(head)->cqh_first = CIRCLEQ_END(head);             \(head)->cqh_last = CIRCLEQ_END(head);              \
} while (0)//元素后插入
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {        \(elm)->field.cqe_next = (listelm)->field.cqe_next;      \(elm)->field.cqe_prev = (listelm);             \if ((listelm)->field.cqe_next == CIRCLEQ_END(head))       \(head)->cqh_last = (elm);              \else                               \(listelm)->field.cqe_next->field.cqe_prev = (elm);  \(listelm)->field.cqe_next = (elm);             \
} while (0)//元素前插入
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {       \(elm)->field.cqe_next = (listelm);             \(elm)->field.cqe_prev = (listelm)->field.cqe_prev;      \if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))       \(head)->cqh_first = (elm);             \else                               \(listelm)->field.cqe_prev->field.cqe_next = (elm);  \(listelm)->field.cqe_prev = (elm);             \
} while (0)//队列头插入
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {          \(elm)->field.cqe_next = (head)->cqh_first;          \(elm)->field.cqe_prev = CIRCLEQ_END(head);         \if ((head)->cqh_last == CIRCLEQ_END(head))            \(head)->cqh_last = (elm);              \else                               \(head)->cqh_first->field.cqe_prev = (elm);      \(head)->cqh_first = (elm);                 \
} while (0)//队列尾插入
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {          \(elm)->field.cqe_next = CIRCLEQ_END(head);         \(elm)->field.cqe_prev = (head)->cqh_last;           \if ((head)->cqh_first == CIRCLEQ_END(head))           \(head)->cqh_first = (elm);             \else                               \(head)->cqh_last->field.cqe_next = (elm);       \(head)->cqh_last = (elm);                  \
} while (0)//元素删除
#define CIRCLEQ_REMOVE(head, elm, field) do {               \if ((elm)->field.cqe_next == CIRCLEQ_END(head))           \(head)->cqh_last = (elm)->field.cqe_prev;       \else                               \(elm)->field.cqe_next->field.cqe_prev =         \(elm)->field.cqe_prev;              \if ((elm)->field.cqe_prev == CIRCLEQ_END(head))           \(head)->cqh_first = (elm)->field.cqe_next;      \else                               \(elm)->field.cqe_prev->field.cqe_next =         \(elm)->field.cqe_next;              \
} while (0)//元素替换
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {            \if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==       \CIRCLEQ_END(head))                     \(head).cqh_last = (elm2);             \else                               \(elm2)->field.cqe_next->field.cqe_prev = (elm2);    \if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==       \CIRCLEQ_END(head))                     \(head).cqh_first = (elm2);                \else                               \(elm2)->field.cqe_prev->field.cqe_next = (elm2);    \
} while (0)

libevent中的基本数据结构相关推荐

  1. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  2. libevent中的bufferevent

    bufferevent是libevent中处理网络事件很重要也是比较复杂的一个模块,其中包含一个读事件,一个写事件,两个缓冲区(读和写).读写水位.三个回调(读.写.出错)和函数指针组成的操作集.目前 ...

  3. libevent中的缓冲区(一)

     libevent中的缓冲区定义为evbuffer,主要在文件evbuffer-internal.h文件中,定义如下 struct evbuffer {/** The first chain in ...

  4. libevent中事件的添加与删除

     前面介绍了libevent中的hash表,在添加事件时,具体是如何操作的呢?事件操作主要是在evmap.c文件中,包含了io事件,signal事件的操作.在事件操作时,分两种情况,一种是利用ha ...

  5. libevent中的信号处理

    libevent中将信号集成到event_base_loop事件循环中,通过socketpair转换成I/O事件,本文主要介绍相关的转换. 1.将信号转成I/O 采用socket pair方式,一个s ...

  6. libevent中的时间及相关的管理

    libevent中的时间及相关的管理 在介绍时间之前,先说明几个与时间相关的函数及其用法 1.基础 1.1 clock_gettime(精度比较高,ns级) #include <time.h&g ...

  7. libevent中的hash表

    libevent中的hash表的代码在ht-internal文件中,在添加io事件,signal事件时,底层是在操作  event_io_map和event_signal_map 1. hash的 ...

  8. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  9. Android开发中高效的数据结构用SparseArray代替HashMap

    Android开发中高效的数据结构用SparseArray代替HashMap 转载于:https://www.cnblogs.com/zhujiabin/p/5775435.html

最新文章

  1. SAP MM 移动类型101与103+105组合混用?
  2. C# Dynamic特性
  3. 微信红包随机数字_微信红包随机算法转载
  4. Linux常用50条命令
  5. 人社部《劳动合同》通用范本模板
  6. 最新系统分析师考试大纲
  7. win7计算机资源管理器卡住,win7系统资源管理器出现卡死现象的解决方法
  8. 北京市参加汽车摇号条件
  9. 05、Flutter FFI 结构体
  10. 《WEB开发-阿里云建站》第1章 建站前的准备
  11. 部分 VIII. A10 Networks
  12. VBA:MsgBox函数
  13. 嵌入式培训如何学?什么人适合转行嵌入式开发?
  14. 转载:Linux下用mutt给QQ邮箱发匿名邮件
  15. 等额本息与等额本金,从财务管理的角度充分考虑货币时间价值,哪个对于购房人来说更划算?
  16. Python 无框架实现决策树(DecisionTree)
  17. 正则表达式大写转小写
  18. ABAP:增强篇-MIGO过账增强之CHECK方法获取行项目
  19. c 语言的产生及发展过程,在意识的产生和发展过程中,起决定性作用的是( ) A.人脑B.语言C.物质D.劳动 - 赏学吧...
  20. s7400plc运行时关闭服务器,S7-400PLC频繁死机

热门文章

  1. shell的一些常识
  2. javascript中常用的
  3. 【转】Nginx+uWSGI 部署 Django 应用
  4. 会员系统整合的想法[择]
  5. mysql中先随机提取再排序d_mysql性能优化
  6. python语法基础知识-python_基础知识_安装和基础语法
  7. python项目-推荐 10 个有趣的 Python 练手项目
  8. python如何调用图片-python调用图片
  9. python百度百科api-python使用API
  10. python爬虫可以干什么-Python 爬虫一 简介